{
  "name": "@timui/react-registry",
  "items": [
    {
      "name": "use-machine",
      "type": "registry:hook",
      "files": [
        {
          "path": "registry/default/hooks/use-machine.ts",
          "type": "registry:hook",
          "target": "components/ui/use-machine/use-machine.ts",
          "content": "import { useCallback, useRef, useState } from 'react'\n\ntype PrimitiveValue = string | number | boolean | null | undefined\ntype MachineValue = PrimitiveValue | MachineValue[] | { [key: string]: MachineValue }\ntype MachineContext = { [key: string]: MachineValue }\ntype MachineEventObject = {\n  type: string\n  [key: string]: MachineValue\n}\ntype MachineEvent = string | MachineEventObject\n\ntype MachineTransition =\n  | string\n  | {\n      target?: string\n      actions?: string | string[]\n    }\n\ntype MachineDefinition = {\n  context?: MachineContext | ((...args: MachineValue[]) => MachineContext) | MachineContext\n  initial?: string\n  initialState?: { value?: string } | ((...args: MachineValue[]) => string) | { value?: string }\n  states?: {\n    [state: string]: {\n      on?: { [eventType: string]: MachineTransition }\n    }\n  }\n  on?: { [eventType: string]: MachineTransition }\n  options?: {\n    actions?: {\n      [actionName: string]: (context: MachineContext, event: MachineEventObject) => void\n    }\n  }\n  config?: {\n    actions?: {\n      [actionName: string]: (context: MachineContext, event: MachineEventObject) => void\n    }\n  }\n  actions?: {\n    [actionName: string]: (context: MachineContext, event: MachineEventObject) => void\n  }\n}\n\ntype HookState = {\n  value?: string | { value?: string }\n  context: MachineContext\n}\n\nconst resolveInitialContext = (\n  context: MachineDefinition['context'],\n  override?: MachineContext\n): MachineContext => {\n  const base = typeof context === 'function' ? {} : (context ?? {})\n  return {\n    ...(typeof base === 'object' && base !== null ? (base as MachineContext) : {}),\n    ...(override ?? {}),\n  }\n}\n\nconst resolveInitialStateValue = (machine: MachineDefinition): string | undefined => {\n  if (typeof machine.initialState === 'function') return machine.initial\n  if (typeof machine.initialState === 'object' && machine.initialState !== null) {\n    return machine.initial || (machine.initialState as { value?: string }).value\n  }\n  return machine.initial\n}\n\nconst isTransitionObject = (\n  transition: MachineTransition\n): transition is Exclude<MachineTransition, string> => typeof transition !== 'string'\n\nexport function useMachine(machine: object, options: { context?: MachineContext } = {}) {\n  const machineRef = machine as {\n    context?: MachineDefinition['context']\n    initial?: string\n    initialState?: MachineDefinition['initialState']\n    states?: MachineDefinition['states']\n    on?: MachineDefinition['on']\n    options?: MachineDefinition['options']\n    config?: MachineDefinition['config']\n    actions?: MachineDefinition['actions']\n  }\n  const initialContext = resolveInitialContext(machineRef.context, options.context)\n\n  const [state, setState] = useState({\n    value: resolveInitialStateValue(machineRef),\n    context: initialContext,\n  } satisfies HookState)\n\n  const stateRef = useRef(state)\n\n  const send = useCallback(\n    (event: MachineEvent) => {\n      const evt = typeof event === 'string' ? { type: event } : event\n      const current = stateRef.current\n\n      const currentStateKey = (() => {\n        if (typeof current.value === 'string') return current.value\n        if (typeof current.value === 'object' && current.value !== null) {\n          const valueObj = current.value as { value?: string }\n          return valueObj.value || 'idle'\n        }\n        return 'idle'\n      })()\n\n      const transition =\n        machineRef.states?.[currentStateKey]?.on?.[evt.type] || machineRef.on?.[evt.type]\n\n      if (transition) {\n        let nextStateKey = currentStateKey\n        if (typeof transition === 'string') {\n          nextStateKey = transition\n        } else if (isTransitionObject(transition) && transition.target) {\n          nextStateKey = transition.target\n        }\n\n        const actions = isTransitionObject(transition) ? transition.actions || [] : []\n        const actionList = Array.isArray(actions) ? actions : [actions]\n        const nextContext = { ...current.context }\n\n        actionList.forEach((actionName: string) => {\n          const actionFn =\n            machineRef.options?.actions?.[actionName] ||\n            machineRef.config?.actions?.[actionName] ||\n            machineRef.actions?.[actionName]\n\n          if (typeof actionFn === 'function') {\n            actionFn(nextContext, evt)\n          }\n        })\n\n        const nextState = {\n          value: nextStateKey,\n          context: nextContext,\n        }\n\n        stateRef.current = nextState\n        setState(nextState satisfies HookState)\n      }\n    },\n    [machineRef]\n  )\n\n  return [state, send] as const\n}\n"
        }
      ],
      "meta": {
        "frameworks": [],
        "dependenciesByFramework": {},
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "accordion",
      "type": "registry:ui",
      "dependencies": [
        "@timui/core",
        "@zag-js/react"
      ],
      "registryDependencies": [
        "use-machine"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/ui/accordion.tsx",
          "type": "registry:ui",
          "target": "components/ui/accordion.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport type { AssertNoExtraKeys, AccordionProps as CoreAccordionProps } from '@timui/core'\nimport {\n  accordionContentInnerVariants,\n  accordionContentVariants,\n  accordionItemVariants,\n  accordionTriggerIconVariants,\n  accordionTriggerInlineVariants,\n  accordionTriggerVariants,\n  cn,\n} from '@timui/core'\nimport { mergeProps } from '@zag-js/react'\nimport { ChevronDownIcon } from 'lucide-react'\n\nimport { useAccordion } from './accordion/use-accordion'\nimport {\n  AccordionItemProvider,\n  AccordionProvider,\n  useAccordionContext,\n  useAccordionItemContext,\n} from './accordion/use-accordion-context'\nimport { Slot } from './slot'\n\ninterface AccordionProps\n  extends\n    CoreAccordionProps,\n    Omit<React.HTMLAttributes<HTMLDivElement>, keyof CoreAccordionProps | 'dir'> {\n  type?: 'single' | 'multiple'\n}\ntype _AccordionPropsGuard = AssertNoExtraKeys<\n  AccordionProps,\n  CoreAccordionProps & Omit<React.HTMLAttributes<HTMLDivElement>, keyof CoreAccordionProps | 'dir'>\n>\n\nconst Accordion = React.forwardRef<HTMLDivElement, AccordionProps>(\n  (\n    {\n      className,\n      type = 'single',\n      collapsible,\n      defaultValue,\n      value,\n      onValueChange,\n      disabled,\n      id,\n      ...props\n    },\n    ref\n  ) => {\n    const { api, multiple } = useAccordion({\n      type,\n      collapsible,\n      defaultValue,\n      value,\n      onValueChange,\n      disabled,\n      id,\n    })\n    const contextValue = React.useMemo(() => ({ api, multiple }), [api, multiple])\n    const rootProps = api.getRootProps()\n    const mergedProps = mergeProps(rootProps, props) as React.HTMLAttributes<HTMLDivElement>\n    const { className: mergedClassName, ...restProps } = mergedProps\n\n    return (\n      <AccordionProvider value={contextValue}>\n        <div\n          ref={ref}\n          data-slot=\"accordion\"\n          className={cn(className, mergedClassName)}\n          {...restProps}\n        />\n      </AccordionProvider>\n    )\n  }\n)\nAccordion.displayName = 'Accordion'\n\nconst AccordionTrigger = React.forwardRef<\n  HTMLButtonElement,\n  React.ButtonHTMLAttributes<HTMLButtonElement> & {\n    asChild?: boolean\n    showChevron?: boolean\n    icon?: React.ReactNode\n  }\n>(({ className, children, asChild = false, showChevron = true, icon, ...props }, ref) => {\n  const { api } = useAccordionContext()\n  const item = useAccordionItemContext()\n  if (!item) throw new Error('Trigger must be within Item')\n  const triggerProps = api.getItemTriggerProps({ value: item.value, disabled: item.disabled })\n\n  const Comp = asChild ? Slot : 'button'\n\n  if (asChild) {\n    return (\n      <Comp\n        ref={ref}\n        data-slot=\"accordion-trigger\"\n        data-state={item.isOpen ? 'open' : 'closed'}\n        className={cn(accordionTriggerInlineVariants(), className)}\n        {...mergeProps(triggerProps, props)}\n      >\n        {children}\n      </Comp>\n    )\n  }\n\n  return (\n    <div className=\"flex\">\n      <Comp\n        ref={ref}\n        type=\"button\"\n        data-slot=\"accordion-trigger\"\n        data-state={item.isOpen ? 'open' : 'closed'}\n        className={cn(accordionTriggerVariants(), className)}\n        {...mergeProps(triggerProps, props)}\n      >\n        {children}\n        {icon\n          ? icon\n          : showChevron && (\n              <ChevronDownIcon\n                size={16}\n                className={cn(accordionTriggerIconVariants())}\n                aria-hidden=\"true\"\n              />\n            )}\n      </Comp>\n    </div>\n  )\n})\nAccordionTrigger.displayName = 'AccordionTrigger'\n\nconst AccordionItem = React.forwardRef<\n  HTMLDivElement,\n  React.HTMLAttributes<HTMLDivElement> & { value: string; disabled?: boolean }\n>(({ className, value, disabled, ...props }, ref) => {\n  const { api } = useAccordionContext()\n  const itemState = api.getItemState({ value, disabled })\n  const itemProps = api.getItemProps({ value, disabled })\n  const mergedProps = mergeProps(itemProps, props)\n  const { className: mergedClassName, ...restProps } = mergedProps\n\n  return (\n    <AccordionItemProvider value={{ value, disabled, isOpen: itemState.expanded }}>\n      <div\n        ref={ref}\n        data-slot=\"accordion-item\"\n        data-state={itemState.expanded ? 'open' : 'closed'}\n        className={cn(accordionItemVariants(), className, mergedClassName)}\n        {...restProps}\n      />\n    </AccordionItemProvider>\n  )\n})\nAccordionItem.displayName = 'AccordionItem'\n\nconst AccordionContent = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, children, ...props }, ref) => {\n    const { api } = useAccordionContext()\n    const item = useAccordionItemContext()\n    if (!item) throw new Error('Content must be within Item')\n    const contentProps = api.getItemContentProps({ value: item.value, disabled: item.disabled })\n    const mergedProps = mergeProps(contentProps, props)\n    const { className: mergedClassName, ...restProps } = mergedProps\n\n    return (\n      <div\n        ref={ref}\n        data-slot=\"accordion-content\"\n        data-state={item.isOpen ? 'open' : 'closed'}\n        hidden={!item.isOpen}\n        className={cn(accordionContentVariants(), className, mergedClassName)}\n        {...restProps}\n      >\n        <div className={cn(accordionContentInnerVariants())}>{children}</div>\n      </div>\n    )\n  }\n)\nAccordionContent.displayName = 'AccordionContent'\n\nexport { Accordion, AccordionContent, AccordionItem, AccordionTrigger }\n"
        },
        {
          "path": "registry/default/ui/accordion/use-accordion-context.ts",
          "target": "components/ui/accordion/use-accordion-context.ts",
          "type": "registry:ui",
          "content": "import * as React from 'react'\nimport type { accordionConnect } from '@timui/core'\n\nexport interface AccordionContextValue {\n  api: ReturnType<typeof accordionConnect>\n  multiple: boolean\n}\n\nexport const AccordionContext = React.createContext<AccordionContextValue | null>(null)\n\nexport function useAccordionContext() {\n  const context = React.useContext(AccordionContext)\n  if (!context) {\n    throw new Error('Accordion components must be used within an Accordion Provider')\n  }\n  return context\n}\n\nexport const AccordionProvider = AccordionContext.Provider\n\nexport interface AccordionItemContextValue {\n  value: string\n  disabled?: boolean\n  isOpen: boolean\n}\n\nexport const AccordionItemContext = React.createContext<AccordionItemContextValue | null>(null)\n\nexport function useAccordionItemContext() {\n  const context = React.useContext(AccordionItemContext)\n  if (!context) {\n    throw new Error('Accordion child components must be used within an AccordionItem')\n  }\n  return context\n}\n\nexport const AccordionItemProvider = AccordionItemContext.Provider\n"
        },
        {
          "path": "registry/default/ui/accordion/use-accordion.ts",
          "target": "components/ui/accordion/use-accordion.ts",
          "type": "registry:ui",
          "content": "import * as React from 'react'\nimport { accordionConnect, accordionMachine, createTimEvent } from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/react'\n\ntype AccordionChangeEvent = {\n  type: string\n  target: { id: string }\n  detail: { value: string | string[] }\n  timestamp: number\n}\n\nexport interface UseAccordionProps {\n  id?: string\n  value?: string | string[]\n  defaultValue?: string | string[]\n  type?: 'single' | 'multiple'\n  collapsible?: boolean\n  disabled?: boolean\n  onValueChange?: (details: AccordionChangeEvent) => void\n}\n\nconst toArray = (value?: string | string[] | null, multiple?: boolean) => {\n  if (value == null) return undefined\n  if (Array.isArray(value)) return value\n  return value === '' ? [] : [value]\n}\n\nconst toValue = (value: string[], multiple: boolean) => {\n  if (multiple) return value\n  return value[0] ?? ''\n}\n\nexport function useAccordion(props: UseAccordionProps = {}) {\n  const generatedId = React.useId()\n  const accordionId = props.id ?? generatedId\n  const multiple = props.type === 'multiple'\n  const value = toArray(props.value, multiple)\n  const defaultValueArray = toArray(props.defaultValue, multiple)\n\n  const service = useMachine(accordionMachine, {\n    id: accordionId,\n    multiple,\n    collapsible: props.collapsible,\n    disabled: props.disabled,\n    value,\n    defaultValue: value === undefined ? defaultValueArray : undefined,\n    onValueChange: (details) => {\n      props.onValueChange?.(\n        createTimEvent('change', accordionId, {\n          value: toValue(details.value, multiple),\n        })\n      )\n    },\n  })\n\n  const api = React.useMemo(() => accordionConnect(service, normalizeProps), [service])\n\n  return { api, multiple }\n}\n"
        },
        {
          "path": "registry/default/vue/accordion/accordion-content.vue",
          "target": "components/ui/accordion/accordion-content.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, type HTMLAttributes } from \"vue\";\nimport {\n  accordionContentInnerVariants,\n  accordionContentVariants,\n  cn,\n} from \"@timui/core\";\nimport { useAccordionContext, useAccordionItemContext } from \"./use-accordion-context\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\nconst api = useAccordionContext();\nconst item = useAccordionItemContext();\n\nconst isOpen = computed(() => item.value.isOpen);\nconst contentProps = computed(() => {\n  return (\n    api.value.getItemContentProps({\n      value: item.value.value,\n      disabled: item.value.disabled,\n    }) || {}\n  );\n});\n</script>\n\n<template>\n  <div\n    v-bind=\"contentProps\"\n    data-slot=\"accordion-content\"\n    :data-state=\"isOpen ? 'open' : 'closed'\"\n    :hidden=\"!isOpen\"\n    :class=\"\n      cn(accordionContentVariants(), props.class)\n    \"\n  >\n    <div :class=\"cn(accordionContentInnerVariants())\">\n      <slot />\n    </div>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/accordion/accordion-item.vue",
          "target": "components/ui/accordion/accordion-item.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, type HTMLAttributes } from \"vue\";\nimport { accordionItemVariants, cn } from \"@timui/core\";\nimport { useAccordionContext, AccordionItemProvider } from \"./use-accordion-context\";\n\nconst props = defineProps<{ value: string; class?: HTMLAttributes[\"class\"]; disabled?: boolean }>();\nconst api = useAccordionContext();\n\nconst itemState = computed(() =>\n  api.value.getItemState({ value: props.value, disabled: props.disabled })\n);\n\nconst isOpen = computed(() => itemState.value.expanded);\nconst itemProps = computed(() =>\n  api.value.getItemProps({ value: props.value, disabled: props.disabled })\n);\n\nAccordionItemProvider(\n  computed(() => ({\n    value: props.value,\n    disabled: itemState.value.disabled,\n    isOpen: isOpen.value,\n  }))\n);\n</script>\n\n<template>\n  <div\n    v-bind=\"itemProps\"\n    data-slot=\"accordion-item\"\n    :data-state=\"isOpen ? 'open' : 'closed'\"\n    :class=\"cn(accordionItemVariants(), props.class)\"\n  >\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/accordion/accordion-trigger.vue",
          "target": "components/ui/accordion/accordion-trigger.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed } from \"vue\";\nimport { ChevronDownIcon } from \"lucide-vue-next\";\nimport {\n  accordionTriggerIconVariants,\n  accordionTriggerVariants,\n  cn,\n} from \"@timui/core\";\nimport { useAccordionContext, useAccordionItemContext } from \"./use-accordion-context\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\nconst api = useAccordionContext();\nconst item = useAccordionItemContext();\n\nconst isOpen = computed(() => item.value.isOpen);\nconst isDisabled = computed(() => item.value.disabled || false);\nconst triggerProps = computed(() => {\n  return api.value.getItemTriggerProps({\n    value: item.value.value,\n    disabled: isDisabled.value,\n  });\n});\n</script>\n\n<template>\n  <div class=\"flex\">\n    <button\n      v-bind=\"triggerProps\"\n      data-slot=\"accordion-trigger\"\n      :data-state=\"isOpen ? 'open' : 'closed'\"\n      type=\"button\"\n      :disabled=\"isDisabled\"\n      :class=\"\n        cn(accordionTriggerVariants(), props.class)\n      \"\n    >\n      <slot />\n      <slot name=\"icon\">\n        <ChevronDownIcon :size=\"16\" :class=\"cn(accordionTriggerIconVariants())\" />\n      </slot>\n    </button>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/accordion/accordion.vue",
          "target": "components/ui/accordion/accordion.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { useAccordion } from \"./use-accordion\";\nimport { AccordionProvider } from \"./use-accordion-context\";\n\nconst props = defineProps<{\n  modelValue?: string | string[];\n  defaultValue?: string | string[];\n  type?: \"single\" | \"multiple\";\n  multiple?: boolean;\n  collapsible?: boolean;\n  disabled?: boolean;\n  onValueChange?: (value: string | string[]) => void;\n  class?: string;\n  id?: string;\n}>();\n\nconst emit = defineEmits([\"update:modelValue\", \"change\"]);\n\nconst api = useAccordion(props, emit);\nAccordionProvider(api);\n</script>\n\n<template>\n  <div v-bind=\"api.getRootProps()\" data-slot=\"accordion\" :class=\"props.class\">\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/accordion/use-accordion-context.ts",
          "target": "components/ui/accordion/use-accordion-context.ts",
          "type": "registry:component",
          "content": "import type { AccordionApi } from '@timui/core'\nimport type { ComputedRef } from 'vue'\n\nimport { createContext } from '../../hooks/create-context'\n\nexport type UseAccordionContext = ComputedRef<AccordionApi>\n\nexport const [AccordionProvider, useAccordionContext] = createContext<UseAccordionContext>({\n  id: 'AccordionContext',\n  providerName: '<Accordion />',\n})\n\nexport type UseAccordionItemContext = ComputedRef<{\n  value: string\n  disabled?: boolean\n  isOpen: boolean\n}>\n\nexport const [AccordionItemProvider, useAccordionItemContext] =\n  createContext<UseAccordionItemContext>({\n    id: 'AccordionItemContext',\n    providerName: '<AccordionItem />',\n  })\n"
        },
        {
          "path": "registry/default/vue/accordion/use-accordion.ts",
          "target": "components/ui/accordion/use-accordion.ts",
          "type": "registry:component",
          "content": "import { accordionConnect, accordionMachine } from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/vue'\nimport { computed, useId } from 'vue'\n\nexport interface UseAccordionProps {\n  modelValue?: string | string[]\n  defaultValue?: string | string[]\n  type?: 'single' | 'multiple'\n  multiple?: boolean\n  collapsible?: boolean\n  disabled?: boolean\n  id?: string\n  onValueChange?: (value: string | string[]) => void\n}\n\ntype AccordionEmits = {\n  (event: 'update:modelValue', value: string | string[]): void\n  (event: 'change', value: string | string[]): void\n}\n\nexport const useAccordion = (props: UseAccordionProps, emit?: AccordionEmits) => {\n  const generatedId = useId()\n  const id = props.id ?? generatedId\n\n  const toArray = (value?: string | string[] | null) => {\n    if (value == null) return undefined\n    return Array.isArray(value) ? value : value === '' ? [] : [value]\n  }\n\n  const toValue = (value: string[], multiple: boolean) => {\n    if (multiple) return value\n    return value[0] ?? ''\n  }\n\n  const machineProps = computed(() => {\n    const multiple = props.type ? props.type === 'multiple' : !!props.multiple\n    const value = toArray(props.modelValue)\n    const defaultValue = toArray(props.defaultValue)\n    return {\n      id,\n      multiple,\n      collapsible: props.collapsible,\n      disabled: props.disabled,\n      value,\n      defaultValue: value === undefined ? defaultValue : undefined,\n      onValueChange(details: { value: string[] }) {\n        const nextValue = toValue(details.value, multiple)\n        props.onValueChange?.(nextValue)\n        if (emit) {\n          emit('update:modelValue', nextValue)\n          emit('change', nextValue)\n        }\n      },\n    }\n  })\n\n  const service = useMachine(accordionMachine, machineProps)\n  return computed(() => accordionConnect(service, normalizeProps))\n}\n"
        },
        {
          "path": "registry/default/html/accordion.html",
          "target": "components/ui/accordion.html",
          "type": "registry:component",
          "content": "<div data-timui-root data-timui-init=\"auto\">\n  <div data-slot=\"accordion\" data-type=\"single\" data-collapsible=\"true\" class=\"\">\n      <div data-slot=\"accordion-item\" data-value=\"item-1\" data-state=\"closed\" class=\"w-full border-b last:border-b-0 border-b\">\n          <div class=\"flex\">\n              <button type=\"button\" data-slot=\"accordion-trigger\" data-value=\"item-1\" data-state=\"closed\"\n                  aria-expanded=\"false\" aria-controls=\"accordion-content-1\" id=\"accordion-trigger-1\"\n                  class=\"focus-visible:border-ring focus-visible:ring-ring/50 flex w-full flex-1 items-center justify-between gap-4 rounded-md py-4 text-left text-sm font-semibold transition-all outline-none hover:underline focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&amp;[data-state&#x3D;open]&gt;svg]:rotate-180\">\n                  Accordion Item 1\n                  <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\"\n                      stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\n                      class=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\">\n                      <path d=\"m6 9 6 6 6-6\" />\n                  </svg>\n              </button>\n          </div>\n          <div id=\"accordion-content-1\" role=\"region\" aria-labelledby=\"accordion-trigger-1\" data-slot=\"accordion-content\"\n              data-value=\"item-1\" data-state=\"closed\" hidden class=\"overflow-hidden text-sm transition-all data-[state&#x3D;open]:animate-accordion-down data-[state&#x3D;closed]:animate-accordion-up\">\n              <div class=\"pt-0 pb-4\">Accordion Content 1</div>\n          </div>\n      </div>\n  </div>\n</div>\n<script type=\"module\">\n  import { autoInitHtmlRuntime } from '@timui/html'\n  autoInitHtmlRuntime({ components: ['accordion'] })\n</script>"
        },
        {
          "path": "registry/default/weapp/accordion.wxml",
          "target": "components/ui/accordion.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}} accordion\">\n  <slot></slot>\n</view>\n\n<!-- 使用示例：\n<accordion value=\"{{['item1']}}\" bind:change=\"handleChange\">\n  <view class=\"accordion-item\" data-value=\"item1\" bindtap=\"onItemTap\">\n    <view class=\"accordion-trigger\">\n      <text>标题 1</text>\n      <text class=\"accordion-icon\">{{api.value.includes('item1') ? '▼' : '▶'}}</text>\n    </view>\n    <view class=\"accordion-content\" wx:if=\"{{api.value.includes('item1')}}\">\n      内容 1\n    </view>\n  </view>\n</accordion>\n-->\n"
        },
        {
          "path": "registry/default/weapp/accordion.ts",
          "target": "components/ui/accordion.ts",
          "type": "registry:component",
          "content": "import { emitTimEvent } from '../utils'\nimport { setupAccordionMachine } from './use-accordion'\n\ntype MachineEvent =\n  | string\n  | {\n      type: string\n      [key: string]: string | number | boolean | string[] | number[] | null | undefined\n    }\n\ntype WeappAccordionApi = {\n  setValue?: (value: string[]) => void\n}\n\ntype WeappService = {\n  setContext: (context: {\n    value?: string[]\n    multiple?: boolean\n    collapsible?: boolean\n    disabled?: boolean\n  }) => void\n}\n\ntype ItemTapEvent = WechatMiniprogram.BaseEvent & {\n  currentTarget: {\n    dataset: {\n      value?: string\n    }\n  }\n}\n\ntype WeappAccordionInternal =\n  WechatMiniprogram.Component.InstanceMethods<WechatMiniprogram.IAnyObject> & {\n    _service?: WeappService\n    _cleanup?: () => void\n    _send?: (event: MachineEvent) => void\n    _connect?: (\n      state: { value?: string[] },\n      send: (event: MachineEvent) => void\n    ) => WeappAccordionApi\n    data: {\n      api: WeappAccordionApi\n    }\n    properties: {\n      value: string[]\n      multiple: boolean\n      collapsible: boolean\n      disabled: boolean\n      id: string\n      extClass: string\n    }\n  }\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    value: { type: Array, value: [] },\n    multiple: { type: Boolean, value: false },\n    collapsible: { type: Boolean, value: true },\n    disabled: { type: Boolean, value: false },\n    id: { type: String, value: 'accordion' },\n    extClass: { type: String, value: '' },\n  },\n\n  data: {\n    api: {} as WeappAccordionApi,\n    className: '',\n  },\n\n  lifetimes: {\n    attached() {\n      const self = this as WeappAccordionInternal\n      const { service, cleanup, send, connect } = setupAccordionMachine(this, {\n        id: this.properties.id,\n        value: this.properties.value,\n        multiple: this.properties.multiple,\n        collapsible: this.properties.collapsible,\n        disabled: this.properties.disabled,\n        onValueChange: (details) => {\n          emitTimEvent(this, 'change', 'change', this.properties.id || 'accordion', {\n            value: details.value,\n          })\n        },\n      })\n\n      self._service = service as WeappService\n      self._cleanup = cleanup\n      self._send = send as (event: MachineEvent) => void\n      self._connect = connect\n    },\n    detached() {\n      const self = this as WeappAccordionInternal\n      self._cleanup?.()\n    },\n  },\n\n  observers: {\n    state: function (state) {\n      const self = this as WeappAccordionInternal\n      if (!state || !self._send || !self._connect) return\n      const api = self._connect(state, self._send) as WeappAccordionApi\n      this.setData({ api, className: this.properties.extClass })\n    },\n  },\n\n  methods: {\n    onItemTap(e: ItemTapEvent) {\n      const self = this as WeappAccordionInternal\n      const value = e.currentTarget.dataset.value\n      if (value && self.data.api.setValue) {\n        self.data.api.setValue([value])\n      }\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/accordion.json",
          "target": "components/ui/accordion.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        },
        {
          "path": "registry/default/weapp/accordion-item/index.wxml",
          "target": "components/ui/accordion-item/index.wxml",
          "type": "registry:component",
          "content": "<view\n  class=\"accordion-item border-b {{className}}\"\n  data-slot=\"accordion-item\"\n  data-state=\"{{expanded ? 'open' : 'closed'}}\"\n>\n  <view class=\"accordion-header flex\">\n    <view \n      class=\"accordion-trigger flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline  {{disabled ? 'opacity-50 pointer-events-none' : ''}}\"\n      data-slot=\"accordion-trigger\"\n      bindtap=\"onTap\"\n      data-state=\"{{expanded ? 'open' : 'closed'}}\"\n      aria-expanded=\"{{expanded ? 'true' : 'false'}}\"\n    >\n      <slot name=\"trigger\"></slot>\n      <view class=\"icon-container {{expanded ? iconExpandedClass : ''}} transition-transform duration-200\">\n         <slot name=\"icon\">\n           <!-- Ideally use an icon component or svg here -->\n           <view class=\"h-4 w-4\">⌄</view> \n         </slot>\n      </view>\n    </view>\n  </view>\n  <view \n    class=\"accordion-content overflow-hidden text-sm transition-all\"\n    data-slot=\"accordion-content\"\n    data-state=\"{{expanded ? 'open' : 'closed'}}\"\n    style=\"{{expanded ? '' : 'height: 0; padding-bottom: 0;'}}\"\n  >\n    <view class=\"pb-4 pt-0\">\n      <slot name=\"content\"></slot>\n      <slot></slot>\n    </view>\n  </view>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/accordion-item/index.wxss",
          "target": "components/ui/accordion-item/index.wxss",
          "type": "registry:component",
          "content": "@import \"../../styles/index.wxss\";\n\n.rotate-180 {\n  transform: rotate(180deg);\n}\n"
        },
        {
          "path": "registry/default/weapp/accordion-item/index.json",
          "target": "components/ui/accordion-item/index.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        },
        {
          "path": "registry/default/weapp/accordion-item/index.ts",
          "target": "components/ui/accordion-item/index.ts",
          "type": "registry:component",
          "content": "type AccordionParent = {\n  handleItemTap: (value: string) => void\n}\n\ntype AccordionItemInstance = WechatMiniprogram.Component.InstanceMethods<{}, {}, {}> & {\n  parent?: AccordionParent | null\n  data: {\n    disabled: boolean\n    value: string\n  }\n}\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  relations: {\n    '../accordion/index': {\n      type: 'parent',\n      linked(target: AccordionParent) {\n        ;(this as AccordionItemInstance).parent = target\n      },\n      unlinked() {\n        ;(this as AccordionItemInstance).parent = null\n      },\n    },\n  },\n\n  properties: {\n    value: {\n      type: String,\n      value: '',\n    },\n    disabled: {\n      type: Boolean,\n      value: false,\n    },\n    className: {\n      type: String,\n      value: '',\n    },\n    iconExpandedClass: {\n      type: String,\n      value: 'rotate-180',\n    },\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n\n  data: {\n    expanded: false,\n  },\n\n  methods: {\n    onTap() {\n      const self = this as AccordionItemInstance\n      if (self.data.disabled) return\n      self.parent?.handleItemTap(self.data.value)\n    },\n  },\n})\n"
        }
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@zag-js/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@zag-js/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "alert-dialog",
      "type": "registry:ui",
      "dependencies": [
        "@timui/core",
        "@zag-js/react"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "use-machine"
      ],
      "files": [
        {
          "path": "registry/default/ui/alert-dialog.tsx",
          "type": "registry:ui",
          "target": "components/ui/alert-dialog.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport {\n  alertDialogCancelVariants,\n  AssertNoExtraKeys,\n  buttonVariants,\n  cn,\n  AlertDialogProps as CoreAlertDialogProps,\n  createTimEvent,\n  dialogContentVariants,\n  dialogDescriptionVariants,\n  dialogFooterVariants,\n  dialogHeaderVariants,\n  dialogOverlayVariants,\n  dialogTitleVariants,\n} from '@timui/core'\nimport { createPortal } from 'react-dom'\n\nimport { useAlertDialog, type UseAlertDialogProps } from './alert-dialog/use-alert-dialog'\nimport { AlertDialogProvider, useAlertDialogContext } from './alert-dialog/use-alert-dialog-context'\nimport { Slot } from './slot'\n\nexport interface AlertDialogProps extends UseAlertDialogProps {\n  children?: React.ReactNode\n}\n\nconst AlertDialog: React.FC<AlertDialogProps> = (props) => {\n  const { children, ...restProps } = props\n  const api = useAlertDialog(restProps)\n\n  return <AlertDialogProvider value={api}>{children}</AlertDialogProvider>\n}\nAlertDialog.displayName = 'AlertDialog'\n\nconst AlertDialogTrigger = React.forwardRef<\n  HTMLButtonElement,\n  React.ButtonHTMLAttributes<HTMLButtonElement> & { asChild?: boolean }\n>(({ asChild = false, ...props }, ref) => {\n  const api = useAlertDialogContext()\n  const Comp = asChild ? Slot : 'button'\n  return <Comp data-slot=\"alert-dialog-trigger\" {...api.getTriggerProps()} {...props} ref={ref} />\n})\nAlertDialogTrigger.displayName = 'AlertDialogTrigger'\n\nconst AlertDialogPortal = ({ children }: { children: React.ReactNode }) => {\n  const api = useAlertDialogContext()\n\n  if (!api.open) return null\n  if (typeof window === 'undefined') return null\n\n  return createPortal(<div data-slot=\"alert-dialog-portal\">{children}</div>, document.body)\n}\nAlertDialogPortal.displayName = 'AlertDialogPortal'\n\nconst AlertDialogOverlay = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  (props, ref) => {\n    const api = useAlertDialogContext()\n    return (\n      <div\n        data-slot=\"alert-dialog-overlay\"\n        {...api.getBackdropProps()}\n        {...props}\n        className={cn(dialogOverlayVariants(), props.className)}\n        ref={ref}\n      />\n    )\n  }\n)\nAlertDialogOverlay.displayName = 'AlertDialogOverlay'\n\nconst AlertDialogContent = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  (props, ref) => {\n    const api = useAlertDialogContext()\n    return (\n      <AlertDialogPortal>\n        <AlertDialogOverlay />\n        <div {...api.getPositionerProps()}>\n          <div\n            data-slot=\"alert-dialog-content\"\n            {...api.getContentProps()}\n            {...props}\n            className={cn(dialogContentVariants(), props.className)}\n            ref={ref}\n          >\n            {props.children}\n          </div>\n        </div>\n      </AlertDialogPortal>\n    )\n  }\n)\nAlertDialogContent.displayName = 'AlertDialogContent'\n\nconst AlertDialogHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (\n  <div className={cn(dialogHeaderVariants(), className)} {...props} />\n)\nAlertDialogHeader.displayName = 'AlertDialogHeader'\n\nconst AlertDialogFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (\n  <div className={cn(dialogFooterVariants(), className)} {...props} />\n)\nAlertDialogFooter.displayName = 'AlertDialogFooter'\n\nconst AlertDialogTitle = React.forwardRef<\n  HTMLHeadingElement,\n  React.HTMLAttributes<HTMLHeadingElement>\n>(({ className, ...props }, ref) => {\n  const api = useAlertDialogContext()\n  return (\n    <h2\n      ref={ref}\n      data-slot=\"alert-dialog-title\"\n      {...api.getTitleProps()}\n      {...props}\n      className={cn(dialogTitleVariants(), className)}\n    />\n  )\n})\nAlertDialogTitle.displayName = 'AlertDialogTitle'\n\nconst AlertDialogDescription = React.forwardRef<\n  HTMLParagraphElement,\n  React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => {\n  const api = useAlertDialogContext()\n  return (\n    <p\n      ref={ref}\n      data-slot=\"alert-dialog-description\"\n      {...api.getDescriptionProps()}\n      {...props}\n      className={cn(dialogDescriptionVariants(), className)}\n    />\n  )\n})\nAlertDialogDescription.displayName = 'AlertDialogDescription'\n\nconst AlertDialogAction = React.forwardRef<\n  HTMLButtonElement,\n  React.ButtonHTMLAttributes<HTMLButtonElement>\n>(({ className, ...props }, ref) => {\n  const api = useAlertDialogContext()\n  const { onClick, ...restProps } = props\n\n  return (\n    <button\n      data-slot=\"alert-dialog-close\"\n      {...api.getCloseTriggerProps()}\n      {...restProps}\n      onClick={(e) => {\n        api.setOpen(false)\n        onClick?.(e)\n      }}\n      className={cn(buttonVariants(), className)}\n      ref={ref}\n    />\n  )\n})\nAlertDialogAction.displayName = 'AlertDialogAction'\n\nconst AlertDialogCancel = React.forwardRef<\n  HTMLButtonElement,\n  React.ButtonHTMLAttributes<HTMLButtonElement>\n>(({ className, ...props }, ref) => {\n  const api = useAlertDialogContext()\n  const { onClick, ...restProps } = props\n\n  return (\n    <button\n      data-slot=\"alert-dialog-close\"\n      {...api.getCloseTriggerProps()}\n      {...restProps}\n      onClick={(e) => {\n        api.setOpen(false)\n        onClick?.(e)\n      }}\n      className={cn(buttonVariants({ variant: 'outline' }), alertDialogCancelVariants(), className)}\n      ref={ref}\n    />\n  )\n})\nAlertDialogCancel.displayName = 'AlertDialogCancel'\n\nexport {\n  AlertDialog,\n  AlertDialogPortal,\n  AlertDialogOverlay,\n  AlertDialogTrigger,\n  AlertDialogContent,\n  AlertDialogHeader,\n  AlertDialogFooter,\n  AlertDialogTitle,\n  AlertDialogDescription,\n  AlertDialogAction,\n  AlertDialogCancel,\n}\n"
        },
        {
          "path": "registry/default/ui/alert-dialog/use-alert-dialog-context.ts",
          "target": "components/ui/alert-dialog/use-alert-dialog-context.ts",
          "type": "registry:ui",
          "content": "import * as React from 'react'\nimport type { dialogConnect } from '@timui/core'\n\nexport type AlertDialogContextValue = ReturnType<typeof dialogConnect>\n\nconst AlertDialogContext = React.createContext<AlertDialogContextValue | null>(null)\n\nexport const AlertDialogProvider: React.Provider<AlertDialogContextValue | null> =\n  AlertDialogContext.Provider\n\nexport function useAlertDialogContext(): AlertDialogContextValue {\n  const context = React.useContext(AlertDialogContext)\n  if (!context) {\n    throw new Error('AlertDialog components must be used within `<AlertDialogProvider />`')\n  }\n  return context\n}\n"
        },
        {
          "path": "registry/default/ui/alert-dialog/use-alert-dialog.ts",
          "target": "components/ui/alert-dialog/use-alert-dialog.ts",
          "type": "registry:ui",
          "content": "import * as React from 'react'\nimport { createTimEvent, dialogConnect, dialogMachine } from '@timui/core'\nimport type { AlertDialogProps as CoreAlertDialogProps } from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/react'\n\nexport interface UseAlertDialogProps extends Omit<CoreAlertDialogProps, 'id'> {\n  id?: string\n  defaultOpen?: boolean\n}\n\nexport function useAlertDialog(props: UseAlertDialogProps = {}) {\n  const generatedId = React.useId()\n  const dialogId = props.id ?? `alert-dialog-${generatedId}`\n\n  const service = useMachine(dialogMachine, {\n    id: dialogId,\n    open: props.open,\n    defaultOpen: props.defaultOpen ?? false,\n    modal: true,\n    role: 'alertdialog',\n    onOpenChange: (details) => {\n      props.onOpenChange?.(\n        createTimEvent('alertDialog.openChange', dialogId, { open: details.open })\n      )\n    },\n  })\n\n  const api = React.useMemo(() => dialogConnect(service, normalizeProps), [service])\n\n  React.useEffect(() => {\n    if (props.open !== undefined && props.open !== api.open) {\n      api.setOpen(props.open)\n    }\n  }, [props.open, api])\n\n  return api\n}\n"
        },
        {
          "path": "registry/default/vue/alert-dialog/alert-dialog-action.vue",
          "target": "components/ui/alert-dialog/alert-dialog-action.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, useAttrs, type HTMLAttributes } from \"vue\";\nimport { cn, buttonVariants } from \"@timui/core\";\nimport { useAlertDialogContext } from \"./use-alert-dialog-context\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\nconst attrs = useAttrs();\nconst api = useAlertDialogContext();\n\ntype AttrValue = string | number | boolean | null | undefined | ((event: MouseEvent) => void);\n\nconst actionAttrs = computed(() => {\n  const { onClick, ...rest } = attrs as Record<string, AttrValue>;\n  return rest;\n});\n\nconst handleClick = (event: MouseEvent) => {\n  api.value.setOpen(false);\n  const onClick = (attrs as Record<string, AttrValue>).onClick;\n  if (typeof onClick !== \"function\") return;\n  onClick?.(event);\n};\n</script>\n\n<template>\n  <button\n    v-bind=\"actionAttrs\"\n    type=\"button\"\n    :class=\"cn(buttonVariants(), props.class)\"\n    @click=\"handleClick\"\n  >\n    <slot />\n  </button>\n</template>\n"
        },
        {
          "path": "registry/default/vue/alert-dialog/alert-dialog-cancel.vue",
          "target": "components/ui/alert-dialog/alert-dialog-cancel.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, useAttrs, type HTMLAttributes } from \"vue\";\nimport { alertDialogCancelVariants, cn, buttonVariants } from \"@timui/core\";\nimport { useAlertDialogContext } from \"./use-alert-dialog-context\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\nconst attrs = useAttrs();\nconst api = useAlertDialogContext();\n\nconst cancelAttrs = computed(() => {\n  const { onClick, ...rest } = attrs as Record<string, object>;\n  return rest;\n});\n\nconst handleClick = (event: MouseEvent) => {\n  api.value.setOpen(false);\n  const onClick = (attrs as Record<string, object>).onClick as\n    | ((event: MouseEvent) => void)\n    | undefined;\n  onClick?.(event);\n};\n</script>\n\n<template>\n  <button\n    v-bind=\"cancelAttrs\"\n    type=\"button\"\n    :class=\"cn(buttonVariants({ variant: 'outline' }), alertDialogCancelVariants(), props.class)\"\n    @click=\"handleClick\"\n  >\n    <slot />\n  </button>\n</template>\n"
        },
        {
          "path": "registry/default/vue/alert-dialog/alert-dialog-content.vue",
          "target": "components/ui/alert-dialog/alert-dialog-content.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, type HTMLAttributes } from \"vue\";\nimport {\n  cn,\n  dialogContentVariants,\n  dialogOverlayVariants,\n  dialogPositionerVariants,\n} from \"@timui/core\";\nimport { useAlertDialogContext } from \"./use-alert-dialog-context\";\nimport Presence from \"../presence/presence.vue\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\nconst api = useAlertDialogContext();\nconst overlayProps = computed(() => {\n  const { onClick, ...rest } = api.value.getBackdropProps() ?? {};\n  return rest;\n});\n</script>\n\n<template>\n  <Teleport to=\"body\">\n    <Presence\n      :present=\"api.open\"\n      lazyMount\n      unmountOnExit\n      v-bind=\"overlayProps\"\n      data-state=\"open\"\n      :class=\"cn(dialogOverlayVariants())\"\n    />\n    <Presence\n      :present=\"api.open\"\n      lazyMount\n      unmountOnExit\n      v-bind=\"api.getPositionerProps()\"\n      :class=\"cn(dialogPositionerVariants())\"\n    >\n      <div\n        v-bind=\"api.getContentProps()\"\n        data-state=\"open\"\n        :class=\"\n          cn(\n            dialogContentVariants(),\n            props.class\n          )\n        \"\n      >\n        <slot />\n      </div>\n    </Presence>\n  </Teleport>\n</template>\n"
        },
        {
          "path": "registry/default/vue/alert-dialog/alert-dialog-description.vue",
          "target": "components/ui/alert-dialog/alert-dialog-description.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, dialogDescriptionVariants } from \"@timui/core\";\nimport type { HTMLAttributes } from \"vue\";\nimport { useAlertDialogContext } from \"./use-alert-dialog-context\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\nconst api = useAlertDialogContext();\n</script>\n\n<template>\n  <p v-bind=\"api.getDescriptionProps()\" :class=\"cn(dialogDescriptionVariants(), props.class)\">\n    <slot />\n  </p>\n</template>\n"
        },
        {
          "path": "registry/default/vue/alert-dialog/alert-dialog-footer.vue",
          "target": "components/ui/alert-dialog/alert-dialog-footer.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, dialogFooterVariants } from '@timui/core'\nimport type { HTMLAttributes } from 'vue'\n\nconst props = defineProps<{\n  class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n  <div :class=\"cn(dialogFooterVariants(), props.class)\">\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/alert-dialog/alert-dialog-header.vue",
          "target": "components/ui/alert-dialog/alert-dialog-header.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, dialogHeaderVariants } from '@timui/core'\nimport type { HTMLAttributes } from 'vue'\n\nconst props = defineProps<{\n  class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n  <div :class=\"cn(dialogHeaderVariants(), props.class)\">\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/alert-dialog/alert-dialog-title.vue",
          "target": "components/ui/alert-dialog/alert-dialog-title.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, dialogTitleVariants } from \"@timui/core\";\nimport type { HTMLAttributes } from \"vue\";\nimport { useAlertDialogContext } from \"./use-alert-dialog-context\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\nconst api = useAlertDialogContext();\n</script>\n\n<template>\n  <h2 v-bind=\"api.getTitleProps()\" :class=\"cn(dialogTitleVariants(), props.class)\">\n    <slot />\n  </h2>\n</template>\n"
        },
        {
          "path": "registry/default/vue/alert-dialog/alert-dialog-trigger.vue",
          "target": "components/ui/alert-dialog/alert-dialog-trigger.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, type Component } from \"vue\";\nimport { cn } from \"@timui/core\";\nimport { Primitive } from '../../primitive';\nimport { useAlertDialogContext } from \"./use-alert-dialog-context\";\n\nconst props = withDefaults(\n  defineProps<{\n    as?: string | Component;\n    asChild?: boolean;\n    class?: HTMLAttributes[\"class\"];\n  }>(),\n  {\n    as: \"button\",\n  }\n);\n\nconst api = useAlertDialogContext();\n</script>\n\n<template>\n  <Primitive\n    :as=\"props.as\"\n    :as-child=\"props.asChild\"\n    v-bind=\"api.getTriggerProps()\"\n    :class=\"cn(props.class)\"\n  >\n    <slot />\n  </Primitive>\n</template>\n"
        },
        {
          "path": "registry/default/vue/alert-dialog/alert-dialog.vue",
          "target": "components/ui/alert-dialog/alert-dialog.vue",
          "type": "registry:component",
          "content": "<script lang=\"ts\">\nexport { default } from '../alert/alert-dialog.vue'\n</script>\n"
        },
        {
          "path": "registry/default/vue/alert-dialog/use-alert-dialog-context.ts",
          "target": "components/ui/alert-dialog/use-alert-dialog-context.ts",
          "type": "registry:component",
          "content": "import type { dialogConnect } from '@timui/core'\nimport { inject, provide, type ComputedRef } from 'vue'\n\nexport type AlertDialogContext = ComputedRef<ReturnType<typeof dialogConnect>>\n\nexport const AlertDialogContextKey = Symbol('AlertDialogContext')\n\nexport const provideAlertDialogContext = (context: AlertDialogContext) => {\n  provide(AlertDialogContextKey, context)\n}\n\nexport const useAlertDialogContext = (): AlertDialogContext => {\n  const context = inject(AlertDialogContextKey)\n  if (!context) {\n    throw new Error('AlertDialog components must be used within a `<AlertDialog />` provider.')\n  }\n  return context as AlertDialogContext\n}\n"
        },
        {
          "path": "registry/default/vue/alert-dialog/use-alert-dialog.ts",
          "target": "components/ui/alert-dialog/use-alert-dialog.ts",
          "type": "registry:component",
          "content": "import type { AlertDialogVueProps as CoreAlertDialogProps } from '@timui/core'\nimport { dialogConnect, dialogMachine } from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/vue'\nimport { computed, useId, watch } from 'vue'\n\nexport interface UseAlertDialogProps extends Omit<CoreAlertDialogProps, 'id'> {\n  id?: string\n  defaultOpen?: boolean\n}\n\nexport interface UseAlertDialogEmits {\n  (e: 'update:open', value: boolean): void\n  (e: 'openChange', value: boolean): void\n}\n\nexport function useAlertDialog(props: UseAlertDialogProps, emit: UseAlertDialogEmits) {\n  const generatedId = useId()\n\n  const machineProps = computed(() => ({\n    id: props.id ?? generatedId,\n    open: props.open,\n    defaultOpen: props.defaultOpen ?? false,\n    role: 'alertdialog' as const, // Force alertdialog role\n    modal: true, // Alerts are always modal\n    onOpenChange(details: { open: boolean }) {\n      props.onOpenChange?.(details.open)\n      emit('update:open', details.open)\n      emit('openChange', details.open)\n    },\n  }))\n\n  const service = useMachine(dialogMachine, machineProps)\n  const api = computed(() => dialogConnect(service, normalizeProps))\n\n  watch(\n    () => props.open,\n    (val?: boolean) => {\n      if (val !== undefined && val !== api.value.open) {\n        api.value.setOpen(val)\n      }\n    }\n  )\n\n  return api\n}\n"
        },
        {
          "path": "registry/default/html/alert-dialog.html",
          "target": "components/ui/alert-dialog.html",
          "type": "registry:component",
          "content": "<div data-slot=\"alert-dialog\" class=\"data-[state&#x3D;open]:animate-in data-[state&#x3D;closed]:animate-out data-[state&#x3D;closed]:fade-out-0 data-[state&#x3D;open]:fade-in-0 fixed inset-0 z-50 bg-black/80\">\n  <div class=\"data-[state&#x3D;open]:animate-in data-[state&#x3D;closed]:animate-out data-[state&#x3D;closed]:fade-out-0 data-[state&#x3D;open]:fade-in-0 data-[state&#x3D;closed]:zoom-out-95 data-[state&#x3D;open]:zoom-in-95 data-[state&#x3D;closed]:slide-out-to-top-[48%] data-[state&#x3D;closed]:slide-out-to-left-[50%] data-[state&#x3D;open]:slide-in-from-top-[48%] data-[state&#x3D;open]:slide-in-from-left-[50%] fixed top-[50%] left-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 sm:rounded-lg\">\n    <h2 class=\"text-lg font-semibold\">Are you absolutely sure?</h2>\n    <p class=\"text-sm text-muted-foreground\">\n      This action cannot be undone.\n    </p>\n    <div class=\"mt-4 flex justify-end gap-2\">\n      <button class=\"rounded-md border px-3 py-2 text-sm\">Cancel</button>\n      <button class=\"rounded-md bg-destructive px-3 py-2 text-sm text-destructive-foreground\">Continue</button>\n    </div>\n  </div>\n</div>"
        },
        {
          "path": "registry/default/weapp/alert-dialog.wxml",
          "target": "components/ui/alert-dialog.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\">\n  <!-- Trigger (optional) -->\n  <view \n    wx:if=\"{{showTrigger}}\"\n    bindtap=\"onTriggerTap\"\n  >\n    <slot name=\"trigger\"></slot>\n  </view>\n\n  <!-- Backdrop -->\n  <view \n    wx:if=\"{{api.open}}\"\n    class=\"alert-dialog-backdrop\"\n    bindtap=\"onBackdropTap\"\n    data-state=\"{{api.open ? 'open' : 'closed'}}\"\n  ></view>\n\n  <!-- Dialog Content -->\n  <view \n    wx:if=\"{{api.open}}\"\n    id=\"{{api.contentProps.id}}\"\n    class=\"alert-dialog-content\"\n    role=\"{{role}}\"\n    data-state=\"{{api.open ? 'open' : 'closed'}}\"\n  >\n    <!-- Header -->\n    <view class=\"alert-dialog-header\">\n      <text \n        id=\"{{api.titleProps.id}}\"\n        class=\"alert-dialog-title\"\n      >\n        <slot name=\"title\">{{title}}</slot>\n      </text>\n      <view \n        wx:if=\"{{showClose}}\"\n        class=\"alert-dialog-close\" \n        bindtap=\"onCloseTap\"\n      >×</view>\n    </view>\n\n    <!-- Body -->\n    <view \n      id=\"{{api.descriptionProps.id}}\"\n      class=\"alert-dialog-body\"\n    >\n      <slot name=\"description\">{{description}}</slot>\n    </view>\n\n    <!-- Footer -->\n    <view class=\"alert-dialog-footer\">\n      <slot name=\"footer\">\n        <view class=\"alert-dialog-actions\">\n          <view \n            class=\"alert-dialog-cancel-btn\" \n            bindtap=\"onCancelTap\"\n          >\n            {{cancelText || '取消'}}\n          </view>\n          <view \n            class=\"alert-dialog-confirm-btn\" \n            bindtap=\"onConfirmTap\"\n          >\n            {{confirmText || '确认'}}\n          </view>\n        </view>\n      </slot>\n    </view>\n  </view>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/alert-dialog.wxss",
          "target": "components/ui/alert-dialog.wxss",
          "type": "registry:component",
          "content": ".alert-dialog-backdrop {\n  position: fixed;\n  inset: 0;\n  background: rgba(0, 0, 0, 0.45);\n  z-index: 1000;\n}\n\n.alert-dialog-content {\n  position: fixed;\n  left: 50%;\n  top: 50%;\n  transform: translate(-50%, -50%);\n  width: 80%;\n  max-width: 640rpx;\n  background: #fff;\n  border-radius: 16rpx;\n  box-shadow: 0 16rpx 48rpx rgba(0, 0, 0, 0.18);\n  z-index: 1001;\n  overflow: hidden;\n}\n\n.alert-dialog-header {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  padding: 28rpx 28rpx 12rpx;\n}\n\n.alert-dialog-title {\n  font-size: 32rpx;\n  font-weight: 600;\n  color: #111827;\n}\n\n.alert-dialog-close {\n  font-size: 36rpx;\n  line-height: 1;\n  color: #6b7280;\n}\n\n.alert-dialog-body {\n  padding: 0 28rpx 20rpx;\n  font-size: 28rpx;\n  line-height: 1.6;\n  color: #374151;\n}\n\n.alert-dialog-footer {\n  padding: 0 28rpx 28rpx;\n}\n\n.alert-dialog-actions {\n  display: flex;\n  gap: 16rpx;\n}\n\n.alert-dialog-cancel-btn,\n.alert-dialog-confirm-btn {\n  flex: 1;\n  text-align: center;\n  border-radius: 12rpx;\n  padding: 18rpx 0;\n  font-size: 28rpx;\n}\n\n.alert-dialog-cancel-btn {\n  background: #f3f4f6;\n  color: #374151;\n}\n\n.alert-dialog-confirm-btn {\n  background: #111827;\n  color: #ffffff;\n}\n"
        },
        {
          "path": "registry/default/weapp/alert-dialog.ts",
          "target": "components/ui/alert-dialog.ts",
          "type": "registry:component",
          "content": "import {\n  alertDialogCancelVariants,\n  buttonVariants,\n  dialogCloseVariants,\n  dialogContentVariants,\n  dialogDescriptionVariants,\n  dialogFooterVariants,\n  dialogHeaderVariants,\n  dialogOverlayVariants,\n  dialogTitleVariants,\n} from '@timui/core'\n\nimport { resolveClasses } from '../utils'\nimport { setupAlertDialogMachine } from './use-alert-dialog'\n\ntype AlertDialogApi = {\n  open?: boolean\n  backdropProps?: { onClick?: () => void }\n  closeTriggerProps?: { onClick?: () => void }\n  contentProps?: Record<string, string>\n  titleProps?: Record<string, string>\n  descriptionProps?: Record<string, string>\n}\n\ntype MachineEvent = string | { type: string; [key: string]: object }\ntype MachineSend = (event: MachineEvent) => void\n\ntype AlertDialogInstance = WechatMiniprogram.Component.InstanceMethods<AlertDialogApi> & {\n  _service?: object\n  _cleanup?: () => void\n  _send?: MachineSend\n  _connect?: (state: object, send: MachineSend) => AlertDialogApi\n  data: {\n    api: AlertDialogApi\n  }\n  properties: {\n    id: string\n    open: boolean\n  }\n}\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    id: { type: String, value: 'alert-dialog' },\n    open: { type: Boolean, value: false },\n    showTrigger: { type: Boolean, value: true },\n    showClose: { type: Boolean, value: true },\n    className: { type: String, value: '' },\n    extClass: { type: String, value: '' },\n    title: { type: String, value: '' },\n    description: { type: String, value: '' },\n    cancelText: { type: String, value: '' },\n    confirmText: { type: String, value: '' },\n  },\n\n  data: {\n    api: {} as AlertDialogApi,\n    overlayClass: '',\n    contentClass: '',\n    titleClass: '',\n    descriptionClass: '',\n    footerClass: '',\n    headerClass: '',\n    cancelClass: '',\n    confirmClass: '',\n    closeClass: '',\n  },\n\n  lifetimes: {\n    attached() {\n      const self = this as AlertDialogInstance\n      const { controller, connect } = setupAlertDialogMachine(this)\n\n      self._service = controller.service\n      self._cleanup = controller.start()\n      self._send = controller.send as MachineSend\n      self._connect = connect\n    },\n    detached() {\n      const self = this as AlertDialogInstance\n      self._cleanup?.()\n    },\n  },\n\n  observers: {\n    state: function (state) {\n      const self = this as AlertDialogInstance\n      if (!state || !self._send || !self._connect) return\n\n      const api = self._connect(state, self._send) as AlertDialogApi\n\n      const overlayClass = resolveClasses(dialogOverlayVariants())\n      const contentClass = resolveClasses(dialogContentVariants(), this.properties.className)\n      const titleClass = resolveClasses(dialogTitleVariants())\n      const descriptionClass = resolveClasses(dialogDescriptionVariants())\n      const footerClass = resolveClasses(dialogFooterVariants())\n      const headerClass = resolveClasses(dialogHeaderVariants())\n      const cancelClass = resolveClasses(alertDialogCancelVariants())\n      const confirmClass = resolveClasses(buttonVariants())\n      const closeClass = resolveClasses(dialogCloseVariants())\n\n      this.setData({\n        api,\n        overlayClass,\n        contentClass,\n        titleClass,\n        descriptionClass,\n        footerClass,\n        headerClass,\n        cancelClass,\n        confirmClass,\n        closeClass,\n      })\n    },\n\n    open: function (val) {\n      const self = this as AlertDialogInstance\n      if (self._service) {\n        if (val !== self.data.api.open) {\n          self._send?.(val ? 'OPEN' : 'CLOSE')\n        }\n      }\n    },\n  },\n\n  methods: {\n    onTriggerTap() {\n      const self = this as AlertDialogInstance\n      self._send?.('OPEN')\n    },\n    onBackdropTap() {\n      const self = this as AlertDialogInstance\n      self.data.api.backdropProps?.onClick?.()\n    },\n    onCloseTap() {\n      const self = this as AlertDialogInstance\n      self.data.api.closeTriggerProps?.onClick?.()\n    },\n    onCancelTap() {\n      this.triggerEvent('cancel')\n      const self = this as AlertDialogInstance\n      self._send?.('CLOSE')\n    },\n    onConfirmTap() {\n      this.triggerEvent('confirm')\n      const self = this as AlertDialogInstance\n      self._send?.('CLOSE')\n    },\n    noop() {},\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/alert-dialog.json",
          "target": "components/ui/alert-dialog.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        }
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@zag-js/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@zag-js/vue"
            ]
          },
          "weapp": {
            "dependencies": [
              "@timui/core"
            ]
          },
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      },
      "categories": [
        "alerts"
      ]
    },
    {
      "name": "alert",
      "type": "registry:ui",
      "dependencies": [
        "@timui/core"
      ],
      "files": [
        {
          "path": "registry/default/ui/alert.tsx",
          "type": "registry:ui",
          "target": "components/ui/alert.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport type { AssertNoExtraKeys, AlertProps as CoreAlertProps } from '@timui/core'\nimport { alertDescriptionVariants, alertTitleVariants, alertVariants, cn } from '@timui/core'\n\ntype AlertProps = CoreAlertProps & React.HTMLAttributes<HTMLDivElement>\ntype _AlertPropsGuard = AssertNoExtraKeys<\n  AlertProps,\n  CoreAlertProps & React.HTMLAttributes<HTMLDivElement>\n>\n\nconst Alert = React.forwardRef<HTMLDivElement, AlertProps>(\n  ({ className, variant, ...props }, ref) => (\n    <div\n      ref={ref}\n      role=\"alert\"\n      data-slot=\"alert\"\n      className={cn(alertVariants({ variant }), className)}\n      {...props}\n    />\n  )\n)\nAlert.displayName = 'Alert'\n\nconst AlertTitle = React.forwardRef<HTMLHeadingElement, React.HTMLAttributes<HTMLHeadingElement>>(\n  ({ className, ...props }, ref) => (\n    <h5\n      ref={ref}\n      data-slot=\"alert-title\"\n      className={cn(alertTitleVariants(), className)}\n      {...props}\n    />\n  )\n)\nAlertTitle.displayName = 'AlertTitle'\n\nconst AlertDescription = React.forwardRef<\n  HTMLParagraphElement,\n  React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n  <div\n    ref={ref}\n    data-slot=\"alert-description\"\n    className={cn(alertDescriptionVariants(), className)}\n    {...props}\n  />\n))\nAlertDescription.displayName = 'AlertDescription'\n\nexport { Alert, AlertTitle, AlertDescription }\n"
        },
        {
          "path": "registry/default/vue/alert/alert-description.vue",
          "target": "components/ui/alert/alert-description.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes } from 'vue'\nimport { alertDescriptionVariants } from '@timui/core'\nimport { cn } from '@timui/core'\n\ninterface Props {\n  class?: HTMLAttributes['class']\n}\n\nconst props = defineProps<Props>()\n</script>\n\n<template>\n  <div data-slot=\"alert-description\" :class=\"cn(alertDescriptionVariants(), props.class)\">\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/alert/alert-dialog.vue",
          "target": "components/ui/alert/alert-dialog.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { useAlertDialog, type UseAlertDialogProps, type UseAlertDialogEmits } from \"../alert-dialog/use-alert-dialog\";\nimport { provideAlertDialogContext } from \"../alert-dialog/use-alert-dialog-context\";\n\nconst props = defineProps<UseAlertDialogProps>();\nconst emit = defineEmits<UseAlertDialogEmits>();\n\nconst api = useAlertDialog(props, emit);\nprovideAlertDialogContext(api);\n</script>\n\n<template>\n  <slot />\n</template>\n"
        },
        {
          "path": "registry/default/vue/alert/alert-title.vue",
          "target": "components/ui/alert/alert-title.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes } from 'vue'\nimport { alertTitleVariants } from '@timui/core'\nimport { cn } from '@timui/core'\n\ninterface Props {\n  class?: HTMLAttributes['class']\n}\n\nconst props = defineProps<Props>()\n</script>\n\n<template>\n  <h5 data-slot=\"alert-title\" :class=\"cn(alertTitleVariants(), props.class)\">\n    <slot />\n  </h5>\n</template>\n"
        },
        {
          "path": "registry/default/vue/alert/alert.vue",
          "target": "components/ui/alert/alert.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes } from 'vue'\nimport { alertVariants } from '@timui/core'\nimport { cn } from '@timui/core'\n\ntype Props = {\n  variant?: 'default' | 'destructive'\n  class?: HTMLAttributes['class']\n}\n\nconst props = defineProps<Props>()\n</script>\n\n<template>\n  <div\n    role=\"alert\"\n    data-slot=\"alert\"\n    :class=\"cn(alertVariants({ variant: props.variant }), props.class)\"\n  >\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/html/alert.html",
          "target": "components/ui/alert.html",
          "type": "registry:component",
          "content": "<div\n  class=\"relative w-full rounded-lg border border-border bg-background p-4 text-foreground bg-background text-foreground\"\n  role=\"alert\"\n  data-slot=\"alert\"\n>\n  <h5 class=\"mb-1 font-medium leading-none tracking-tight\" data-slot=\"alert-title\">Heads up!</h5>\n  <div class=\"text-sm text-muted-foreground\" data-slot=\"alert-description\">\n    You can add components to your app using the cli.\n  </div>\n</div>"
        },
        {
          "path": "registry/default/weapp/alert.wxml",
          "target": "components/ui/alert.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\" data-slot=\"alert\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/alert.wxss",
          "target": "components/ui/alert.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/alert.ts",
          "target": "components/ui/alert.ts",
          "type": "registry:component",
          "content": "import { alertVariants } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    variant: {\n      type: String,\n      value: 'default',\n    },\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    'variant, extClass': function (variant, extClass) {\n      this.setData({\n        className: alertVariants({ variant, className: extClass }),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/alert.json",
          "target": "components/ui/alert.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/alert-description/alert-description.wxml",
          "target": "components/ui/alert-description/alert-description.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\" data-slot=\"alert-description\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/alert-description/alert-description.wxss",
          "target": "components/ui/alert-description/alert-description.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/alert-description/alert-description.json",
          "target": "components/ui/alert-description/alert-description.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/alert-description/alert-description.ts",
          "target": "components/ui/alert-description/alert-description.ts",
          "type": "registry:component",
          "content": "import { alertDescriptionVariants } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass) {\n      this.setData({\n        className: alertDescriptionVariants({ className: extClass }),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/alert-dialog/alert-dialog.wxml",
          "target": "components/ui/alert-dialog/alert-dialog.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\">\n  <!-- Trigger (optional) -->\n  <view \n    wx:if=\"{{showTrigger}}\"\n    bindtap=\"onTriggerTap\"\n  >\n    <slot name=\"trigger\"></slot>\n  </view>\n\n  <!-- Backdrop -->\n  <view \n    wx:if=\"{{api.open}}\"\n    class=\"alert-dialog-backdrop\"\n    bindtap=\"onBackdropTap\"\n    data-state=\"{{api.open ? 'open' : 'closed'}}\"\n  ></view>\n\n  <!-- Dialog Content -->\n  <view \n    wx:if=\"{{api.open}}\"\n    id=\"{{api.contentProps.id}}\"\n    class=\"alert-dialog-content\"\n    role=\"{{role}}\"\n    data-state=\"{{api.open ? 'open' : 'closed'}}\"\n  >\n    <!-- Header -->\n    <view class=\"alert-dialog-header\">\n      <text \n        id=\"{{api.titleProps.id}}\"\n        class=\"alert-dialog-title\"\n      >\n        <slot name=\"title\">{{title}}</slot>\n      </text>\n      <view \n        wx:if=\"{{showClose}}\"\n        class=\"alert-dialog-close\" \n        bindtap=\"onCloseTap\"\n      >×</view>\n    </view>\n\n    <!-- Body -->\n    <view \n      id=\"{{api.descriptionProps.id}}\"\n      class=\"alert-dialog-body\"\n    >\n      <slot name=\"description\">{{description}}</slot>\n    </view>\n\n    <!-- Footer -->\n    <view class=\"alert-dialog-footer\">\n      <slot name=\"footer\">\n        <view class=\"alert-dialog-actions\">\n          <view \n            class=\"alert-dialog-cancel-btn\" \n            bindtap=\"onCancelTap\"\n          >\n            {{cancelText || '取消'}}\n          </view>\n          <view \n            class=\"alert-dialog-confirm-btn\" \n            bindtap=\"onConfirmTap\"\n          >\n            {{confirmText || '确认'}}\n          </view>\n        </view>\n      </slot>\n    </view>\n  </view>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/alert-dialog/alert-dialog.wxss",
          "target": "components/ui/alert-dialog/alert-dialog.wxss",
          "type": "registry:component",
          "content": ".alert-dialog-backdrop {\n  position: fixed;\n  inset: 0;\n  background: rgba(0, 0, 0, 0.45);\n  z-index: 1000;\n}\n\n.alert-dialog-content {\n  position: fixed;\n  left: 50%;\n  top: 50%;\n  transform: translate(-50%, -50%);\n  width: 80%;\n  max-width: 640rpx;\n  background: #fff;\n  border-radius: 16rpx;\n  box-shadow: 0 16rpx 48rpx rgba(0, 0, 0, 0.18);\n  z-index: 1001;\n  overflow: hidden;\n}\n\n.alert-dialog-header {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  padding: 28rpx 28rpx 12rpx;\n}\n\n.alert-dialog-title {\n  font-size: 32rpx;\n  font-weight: 600;\n  color: #111827;\n}\n\n.alert-dialog-close {\n  font-size: 36rpx;\n  line-height: 1;\n  color: #6b7280;\n}\n\n.alert-dialog-body {\n  padding: 0 28rpx 20rpx;\n  font-size: 28rpx;\n  line-height: 1.6;\n  color: #374151;\n}\n\n.alert-dialog-footer {\n  padding: 0 28rpx 28rpx;\n}\n\n.alert-dialog-actions {\n  display: flex;\n  gap: 16rpx;\n}\n\n.alert-dialog-cancel-btn,\n.alert-dialog-confirm-btn {\n  flex: 1;\n  text-align: center;\n  border-radius: 12rpx;\n  padding: 18rpx 0;\n  font-size: 28rpx;\n}\n\n.alert-dialog-cancel-btn {\n  background: #f3f4f6;\n  color: #374151;\n}\n\n.alert-dialog-confirm-btn {\n  background: #111827;\n  color: #ffffff;\n}\n"
        },
        {
          "path": "registry/default/weapp/alert-dialog/alert-dialog.json",
          "target": "components/ui/alert-dialog/alert-dialog.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        },
        {
          "path": "registry/default/weapp/alert-dialog/alert-dialog.ts",
          "target": "components/ui/alert-dialog/alert-dialog.ts",
          "type": "registry:component",
          "content": "import {\n  alertDialogCancelVariants,\n  buttonVariants,\n  dialogCloseVariants,\n  dialogContentVariants,\n  dialogDescriptionVariants,\n  dialogFooterVariants,\n  dialogHeaderVariants,\n  dialogOverlayVariants,\n  dialogTitleVariants,\n} from '@timui/core'\n\nimport { resolveClasses } from '../utils'\nimport { setupAlertDialogMachine } from './use-alert-dialog'\n\ntype AlertDialogApi = {\n  open?: boolean\n  backdropProps?: { onClick?: () => void }\n  closeTriggerProps?: { onClick?: () => void }\n  contentProps?: Record<string, string>\n  titleProps?: Record<string, string>\n  descriptionProps?: Record<string, string>\n}\n\ntype MachineEvent = string | { type: string; [key: string]: object }\ntype MachineSend = (event: MachineEvent) => void\n\ntype AlertDialogInstance = WechatMiniprogram.Component.InstanceMethods<AlertDialogApi> & {\n  _service?: object\n  _cleanup?: () => void\n  _send?: MachineSend\n  _connect?: (state: object, send: MachineSend) => AlertDialogApi\n  data: {\n    api: AlertDialogApi\n  }\n  properties: {\n    id: string\n    open: boolean\n  }\n}\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    id: { type: String, value: 'alert-dialog' },\n    open: { type: Boolean, value: false },\n    showTrigger: { type: Boolean, value: true },\n    showClose: { type: Boolean, value: true },\n    className: { type: String, value: '' },\n    extClass: { type: String, value: '' },\n    title: { type: String, value: '' },\n    description: { type: String, value: '' },\n    cancelText: { type: String, value: '' },\n    confirmText: { type: String, value: '' },\n  },\n\n  data: {\n    api: {} as AlertDialogApi,\n    overlayClass: '',\n    contentClass: '',\n    titleClass: '',\n    descriptionClass: '',\n    footerClass: '',\n    headerClass: '',\n    cancelClass: '',\n    confirmClass: '',\n    closeClass: '',\n  },\n\n  lifetimes: {\n    attached() {\n      const self = this as AlertDialogInstance\n      const { controller, connect } = setupAlertDialogMachine(this)\n\n      self._service = controller.service\n      self._cleanup = controller.start()\n      self._send = controller.send as MachineSend\n      self._connect = connect\n    },\n    detached() {\n      const self = this as AlertDialogInstance\n      self._cleanup?.()\n    },\n  },\n\n  observers: {\n    state: function (state) {\n      const self = this as AlertDialogInstance\n      if (!state || !self._send || !self._connect) return\n\n      const api = self._connect(state, self._send) as AlertDialogApi\n\n      const overlayClass = resolveClasses(dialogOverlayVariants())\n      const contentClass = resolveClasses(dialogContentVariants(), this.properties.className)\n      const titleClass = resolveClasses(dialogTitleVariants())\n      const descriptionClass = resolveClasses(dialogDescriptionVariants())\n      const footerClass = resolveClasses(dialogFooterVariants())\n      const headerClass = resolveClasses(dialogHeaderVariants())\n      const cancelClass = resolveClasses(alertDialogCancelVariants())\n      const confirmClass = resolveClasses(buttonVariants())\n      const closeClass = resolveClasses(dialogCloseVariants())\n\n      this.setData({\n        api,\n        overlayClass,\n        contentClass,\n        titleClass,\n        descriptionClass,\n        footerClass,\n        headerClass,\n        cancelClass,\n        confirmClass,\n        closeClass,\n      })\n    },\n\n    open: function (val) {\n      const self = this as AlertDialogInstance\n      if (self._service) {\n        if (val !== self.data.api.open) {\n          self._send?.(val ? 'OPEN' : 'CLOSE')\n        }\n      }\n    },\n  },\n\n  methods: {\n    onTriggerTap() {\n      const self = this as AlertDialogInstance\n      self._send?.('OPEN')\n    },\n    onBackdropTap() {\n      const self = this as AlertDialogInstance\n      self.data.api.backdropProps?.onClick?.()\n    },\n    onCloseTap() {\n      const self = this as AlertDialogInstance\n      self.data.api.closeTriggerProps?.onClick?.()\n    },\n    onCancelTap() {\n      this.triggerEvent('cancel')\n      const self = this as AlertDialogInstance\n      self._send?.('CLOSE')\n    },\n    onConfirmTap() {\n      this.triggerEvent('confirm')\n      const self = this as AlertDialogInstance\n      self._send?.('CLOSE')\n    },\n    noop() {},\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/alert-title/alert-title.wxml",
          "target": "components/ui/alert-title/alert-title.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\" data-slot=\"alert-title\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/alert-title/alert-title.wxss",
          "target": "components/ui/alert-title/alert-title.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/alert-title/alert-title.json",
          "target": "components/ui/alert-title/alert-title.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/alert-title/alert-title.ts",
          "target": "components/ui/alert-title/alert-title.ts",
          "type": "registry:component",
          "content": "import { alertTitleVariants } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass) {\n      this.setData({\n        className: alertTitleVariants({ className: extClass }),\n      })\n    },\n  },\n})\n"
        }
      ],
      "categories": [
        "alerts"
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core"
            ]
          },
          "weapp": {
            "dependencies": [
              "@timui/core"
            ]
          },
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "avatar",
      "type": "registry:ui",
      "dependencies": [
        "@timui/core",
        "@zag-js/react"
      ],
      "registryDependencies": [
        "use-machine"
      ],
      "files": [
        {
          "path": "registry/default/ui/avatar.tsx",
          "type": "registry:ui",
          "target": "components/ui/avatar.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport { avatarFallbackVariants, avatarImageVariants, avatarVariants, cn } from '@timui/core'\n\nimport { useAvatar } from './avatar/use-avatar'\nimport { AvatarProvider, useAvatarContext } from './avatar/use-avatar-context'\n\nconst Avatar = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, ...props }, ref) => {\n    const api = useAvatar({ id: React.useId() })\n\n    return (\n      <AvatarProvider value={api}>\n        <div\n          ref={ref}\n          className={cn(avatarVariants(), className)}\n          {...api.getRootProps()}\n          {...props}\n        />\n      </AvatarProvider>\n    )\n  }\n)\nAvatar.displayName = 'Avatar'\n\nconst AvatarImage = React.forwardRef<\n  HTMLImageElement,\n  React.ImgHTMLAttributes<HTMLImageElement> & {\n    onLoadingStatusChange?: (status: 'loaded' | 'error') => void\n  }\n>(\n  (\n    { className, src, srcSet, alt, onLoadingStatusChange: _onLoadingStatusChange, ...props },\n    ref\n  ) => {\n    const api = useAvatarContext()\n    void _onLoadingStatusChange\n\n    return (\n      <img\n        ref={ref}\n        src={src}\n        srcSet={srcSet}\n        alt={alt}\n        className={cn(avatarImageVariants(), className)}\n        {...api.getImageProps()}\n        {...props}\n      />\n    )\n  }\n)\nAvatarImage.displayName = 'AvatarImage'\n\nconst AvatarFallback = React.forwardRef<HTMLSpanElement, React.HTMLAttributes<HTMLSpanElement>>(\n  ({ className, ...props }, ref) => {\n    const api = useAvatarContext()\n\n    return (\n      <span\n        ref={ref}\n        className={cn(avatarFallbackVariants(), className)}\n        {...api.getFallbackProps()}\n        {...props}\n      />\n    )\n  }\n)\nAvatarFallback.displayName = 'AvatarFallback'\n\nexport { Avatar, AvatarImage, AvatarFallback }\n"
        },
        {
          "path": "registry/default/ui/avatar/use-avatar-context.tsx",
          "target": "components/ui/avatar/use-avatar-context.tsx",
          "type": "registry:ui",
          "content": "import * as React from 'react'\nimport type { AvatarApi } from '@timui/core'\n\nexport const AvatarContext: React.Context<AvatarApi | null> = React.createContext<AvatarApi | null>(\n  null\n)\n\nexport function useAvatarContext(): AvatarApi {\n  const context = React.useContext(AvatarContext)\n  if (!context) {\n    throw new Error('Avatar components must be used within an AvatarProvider')\n  }\n  return context\n}\n\nexport function AvatarProvider({\n  children,\n  value,\n}: {\n  children: React.ReactNode\n  value: AvatarApi\n}) {\n  return <AvatarContext.Provider value={value}>{children}</AvatarContext.Provider>\n}\n"
        },
        {
          "path": "registry/default/ui/avatar/use-avatar.ts",
          "target": "components/ui/avatar/use-avatar.ts",
          "type": "registry:ui",
          "content": "import * as React from 'react'\nimport { avatarConnect, avatarMachine, type AvatarApi } from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/react'\n\ntype UseAvatarProps = {\n  id?: string\n  dir?: 'ltr' | 'rtl'\n  getRootNode?: (() => ShadowRoot | Document | Node) | undefined\n}\n\nexport function useAvatar(props: UseAvatarProps = {}): AvatarApi {\n  const generatedId = React.useId()\n  const service = useMachine(avatarMachine, {\n    id: props.id ?? generatedId,\n    dir: props.dir,\n    getRootNode: props.getRootNode,\n  })\n\n  return React.useMemo(() => avatarConnect(service, normalizeProps), [service])\n}\n"
        },
        {
          "path": "registry/default/vue/avatar/avatar-fallback.vue",
          "target": "components/ui/avatar/avatar-fallback.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { avatarFallbackVariants, cn } from \"@timui/core\";\nimport { useAvatarContext } from \"./use-avatar-context\";\n\nconst props = defineProps<{ class?: string }>();\n\nconst api = useAvatarContext();\n</script>\n\n<template>\n  <div\n    v-bind=\"api.getFallbackProps()\"\n    :class=\"cn(avatarFallbackVariants(), props.class)\"\n  >\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/avatar/avatar-image.vue",
          "target": "components/ui/avatar/avatar-image.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { avatarImageVariants, cn } from \"@timui/core\";\nimport { useAvatarContext } from \"./use-avatar-context\";\n\nconst props = defineProps<{\n  src?: string;\n  srcset?: string;\n  alt?: string;\n  class?: string;\n}>();\n\nconst api = useAvatarContext();\n</script>\n\n<template>\n  <img\n    :src=\"props.src\"\n    :srcset=\"props.srcset\"\n    :alt=\"props.alt\"\n    v-bind=\"api.getImageProps()\"\n    :class=\"cn(avatarImageVariants(), props.class)\"\n  />\n</template>\n"
        },
        {
          "path": "registry/default/vue/avatar/avatar.vue",
          "target": "components/ui/avatar/avatar.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { avatarVariants } from \"@timui/core\";\nimport { cn } from '@timui/core';\nimport { useAvatar } from './use-avatar'\nimport { provideAvatarContext } from './use-avatar-context'\n\nconst props = defineProps<{ class?: string }>();\n\nconst api = useAvatar()\nprovideAvatarContext(api)\n</script>\n\n<template>\n  <div\n    v-bind=\"api.getRootProps()\"\n    :class=\"cn(avatarVariants(), props.class)\"\n  >\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/avatar/use-avatar-context.ts",
          "target": "components/ui/avatar/use-avatar-context.ts",
          "type": "registry:component",
          "content": "import type { AvatarApi } from '@timui/core'\nimport { inject, provide, type ComputedRef } from 'vue'\n\nexport const AvatarContextKey = Symbol('AvatarContext')\n\nexport function provideAvatarContext(api: ComputedRef<AvatarApi>) {\n  provide(AvatarContextKey, api)\n}\n\nexport function useAvatarContext(): ComputedRef<AvatarApi> {\n  const context = inject<ComputedRef<AvatarApi>>(AvatarContextKey)\n  if (!context) {\n    throw new Error('useAvatarContext must be used within an AvatarProvider')\n  }\n  return context\n}\n"
        },
        {
          "path": "registry/default/vue/avatar/use-avatar.ts",
          "target": "components/ui/avatar/use-avatar.ts",
          "type": "registry:component",
          "content": "import { avatarConnect, avatarMachine } from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/vue'\nimport { computed, useId } from 'vue'\n\nexport type UseAvatarProps = {\n  id?: string\n}\n\nexport function useAvatar(props: UseAvatarProps = {}) {\n  const generatedId = useId()\n\n  const service = useMachine(avatarMachine, {\n    id: props.id ?? generatedId,\n  })\n\n  return computed(() => avatarConnect(service, normalizeProps))\n}\n"
        },
        {
          "path": "registry/default/html/avatar.html",
          "target": "components/ui/avatar.html",
          "type": "registry:component",
          "content": "<div class=\"relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full\" data-slot=\"avatar\">\n  <img\n    class=\"aspect-square h-full w-full\"\n    src=\"https://github.com/shadcn.png\"\n    alt=\"@shadcn\"\n    data-slot=\"avatar-image\"\n  />\n  <div class=\"bg-muted flex h-full w-full items-center justify-center rounded-full\" data-slot=\"avatar-fallback\">\n    CN\n  </div>\n</div>"
        },
        {
          "path": "registry/default/weapp/avatar.wxml",
          "target": "components/ui/avatar.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}} avatar avatar-{{size}} avatar-{{shape}}\">\n  <image \n    wx:if=\"{{src}}\"\n    class=\"avatar-image\"\n    src=\"{{src}}\"\n    mode=\"aspectFill\"\n    bindload=\"onImageLoad\"\n    binderror=\"onImageError\"\n  />\n  <view wx:elif=\"{{fallback}}\" class=\"avatar-fallback\">\n    {{fallback}}\n  </view>\n  <slot wx:else></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/avatar.wxss",
          "target": "components/ui/avatar.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/avatar.ts",
          "target": "components/ui/avatar.ts",
          "type": "registry:component",
          "content": "// @ts-nocheck\nimport {\n  connectAvatarMachine,\n  setupAvatarMachine,\n  type WeappAvatarApi,\n  type WeappAvatarService,\n} from './use-avatar'\n\ntype MachineEvent =\n  | string\n  | {\n      type: string\n      [key: string]: string | number | boolean | string[] | number[] | null | undefined\n    }\n\ntype AvatarStatus = 'idle' | 'loading' | 'loaded' | 'error'\n\ntype AvatarStatusDetails = {\n  status: AvatarStatus\n}\n\ntype WeappAvatarInternal = WechatMiniprogram.Component.InstanceMethods<{}> & {\n  _service?: WeappAvatarService\n  _cleanup?: () => void\n  _send?: (event: MachineEvent) => void\n  data: {\n    api: WeappAvatarApi\n    imageLoaded: boolean\n  }\n  properties: {\n    src: string\n    alt: string\n    fallback: string\n    size: string\n    shape: string\n    id: string\n    extClass: string\n  }\n}\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    src: { type: String, value: '' },\n    alt: { type: String, value: '' },\n    fallback: { type: String, value: '' },\n    size: { type: String, value: 'default' },\n    shape: { type: String, value: 'circle' },\n    id: { type: String, value: 'avatar' },\n    extClass: { type: String, value: '' },\n  },\n\n  data: {\n    api: {} as WeappAvatarApi,\n    className: '',\n    imageLoaded: false,\n  },\n\n  lifetimes: {\n    attached() {\n      const self = this as WeappAvatarInternal\n      const controller = setupAvatarMachine(this, {\n        id: this.properties.id,\n        onStatusChange: (details: AvatarStatusDetails) => {\n          if (details.status === 'loaded') {\n            this.setData({ imageLoaded: true })\n          }\n        },\n      })\n\n      self._service = controller.service as WeappAvatarService\n      self._cleanup = controller.start()\n      self._send = controller.send as (event: MachineEvent) => void\n    },\n    detached() {\n      const self = this as WeappAvatarInternal\n      self._cleanup?.()\n    },\n  },\n\n  observers: {\n    state: function (state) {\n      const self = this as WeappAvatarInternal\n      if (!state || !self._send) return\n      const api = connectAvatarMachine(state, self._send) as WeappAvatarApi\n      this.setData({ api, className: this.properties.extClass })\n    },\n  },\n\n  methods: {\n    onImageLoad() {\n      this.setData({ imageLoaded: true })\n    },\n    onImageError() {\n      this.setData({ imageLoaded: false })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/avatar.json",
          "target": "components/ui/avatar.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        },
        {
          "path": "registry/default/weapp/avatar-fallback/index.wxml",
          "target": "components/ui/avatar-fallback/index.wxml",
          "type": "registry:component",
          "content": "<view\n  wx:if=\"{{!hidden}}\"\n  class=\"{{className}}\"\n  data-slot=\"avatar-fallback\"\n>\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/avatar-fallback/index.wxss",
          "target": "components/ui/avatar-fallback/index.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/avatar-fallback/index.json",
          "target": "components/ui/avatar-fallback/index.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/avatar-fallback/index.ts",
          "target": "components/ui/avatar-fallback/index.ts",
          "type": "registry:component",
          "content": "import { avatarFallbackVariants } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n  relations: {\n    '../avatar/index': {\n      type: 'parent',\n      linked(target) {\n        this.parent = target\n      },\n      unlinked() {\n        this.parent = null\n      },\n    },\n  },\n  properties: {\n    extClass: { type: String, value: '' },\n  },\n  data: {\n    className: '',\n    hidden: false,\n  },\n  lifetimes: {\n    attached() {\n      this._syncClassName()\n    },\n  },\n  observers: {\n    extClass() {\n      this._syncClassName()\n    },\n  },\n  methods: {\n    _syncClassName() {\n      this.setData({\n        className: avatarFallbackVariants({ className: this.properties.extClass }),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/avatar-image/index.wxml",
          "target": "components/ui/avatar-image/index.wxml",
          "type": "registry:component",
          "content": "<image\n  wx:if=\"{{!hidden}}\"\n  class=\"{{className}}\"\n  src=\"{{src}}\"\n  alt=\"{{alt}}\"\n  mode=\"aspectFill\"\n  bindload=\"onLoad\"\n  binderror=\"onError\"\n  data-slot=\"avatar-image\"\n/>\n"
        },
        {
          "path": "registry/default/weapp/avatar-image/index.wxss",
          "target": "components/ui/avatar-image/index.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/avatar-image/index.json",
          "target": "components/ui/avatar-image/index.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/avatar-image/index.ts",
          "target": "components/ui/avatar-image/index.ts",
          "type": "registry:component",
          "content": "import { avatarImageVariants } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n  relations: {\n    '../avatar/index': {\n      type: 'parent',\n      linked(target) {\n        this.parent = target\n      },\n      unlinked() {\n        this.parent = null\n      },\n    },\n  },\n  properties: {\n    src: { type: String, value: '' },\n    alt: { type: String, value: '' },\n    extClass: { type: String, value: '' },\n  },\n  data: {\n    className: '',\n    hidden: false,\n  },\n  lifetimes: {\n    attached() {\n      this._syncClassName()\n    },\n  },\n  observers: {\n    extClass() {\n      this._syncClassName()\n    },\n  },\n  methods: {\n    _syncClassName() {\n      this.setData({\n        className: avatarImageVariants({ className: this.properties.extClass }),\n      })\n    },\n    onLoad() {\n      if (this.parent?.handleImageLoaded) {\n        this.parent.handleImageLoaded()\n      }\n    },\n    onError() {\n      if (this.parent?.handleImageError) {\n        this.parent.handleImageError()\n      }\n    },\n  },\n})\n"
        }
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@zag-js/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@zag-js/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "badge",
      "type": "registry:ui",
      "files": [
        {
          "path": "registry/default/ui/badge.tsx",
          "type": "registry:ui",
          "target": "components/ui/badge.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport type { AssertNoExtraKeys, BadgeProps as CoreBadgeProps } from '@timui/core'\nimport { badgeVariants, cn } from '@timui/core'\n\nimport { Slot } from './slot'\n\ntype BadgeProps = CoreBadgeProps & React.ComponentProps<'span'> & { asChild?: boolean }\ntype _BadgePropsGuard = AssertNoExtraKeys<\n  BadgeProps,\n  CoreBadgeProps & React.ComponentProps<'span'> & { asChild?: boolean }\n>\n\nfunction Badge({ className, variant, asChild = false, ...props }: BadgeProps) {\n  const Comp = asChild ? Slot : 'span'\n\n  return <Comp data-slot=\"badge\" className={cn(badgeVariants({ variant }), className)} {...props} />\n}\n\nexport { Badge, badgeVariants }\n"
        },
        {
          "path": "registry/default/vue/badge/badge.vue",
          "target": "components/ui/badge/badge.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes } from 'vue'\nimport { badgeVariants } from '@timui/core'\nimport { cn } from '@timui/core'\n\ntype Props = {\n  variant?: 'default' | 'secondary' | 'destructive' | 'outline'\n  class?: HTMLAttributes['class']\n}\n\nconst props = defineProps<Props>()\n</script>\n\n<template>\n  <span\n    data-slot=\"badge\"\n    :class=\"cn(badgeVariants({ variant: props.variant }), props.class)\"\n  >\n    <slot />\n  </span>\n</template>\n"
        },
        {
          "path": "registry/default/html/badge.html",
          "target": "components/ui/badge.html",
          "type": "registry:component",
          "content": "<span data-slot=\"badge\" class=\"inline-flex items-center justify-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80\">\n    Badge\n</span>"
        },
        {
          "path": "registry/default/weapp/badge.wxml",
          "target": "components/ui/badge.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/badge.wxss",
          "target": "components/ui/badge.wxss",
          "type": "registry:component",
          "content": "/* Badge specific styles */\n"
        },
        {
          "path": "registry/default/weapp/badge.ts",
          "target": "components/ui/badge.ts",
          "type": "registry:component",
          "content": "import { badgeVariants } from '../utils'\nimport {\n  createWeappBaseProps,\n  createWeappOptions,\n  WEAPP_EXTERNAL_CLASSES,\n} from '../utils/component'\n\nComponent({\n  options: createWeappOptions({ pureData: true }),\n\n  externalClasses: WEAPP_EXTERNAL_CLASSES,\n\n  properties: {\n    variant: { type: String, value: 'default' },\n    size: { type: String, value: 'default' },\n    ...createWeappBaseProps(),\n  },\n\n  data: {\n    className: '',\n  },\n\n  lifetimes: {\n    attached() {\n      this.updateClassName()\n    },\n  },\n\n  observers: {\n    'variant, size, extClass': function () {\n      this.updateClassName()\n    },\n  },\n\n  methods: {\n    updateClassName() {\n      // Use core package's badgeVariants for consistent styling\n      const { baseClass } = badgeVariants({\n        variant: this.properties.variant || 'default',\n        className: this.properties.extClass,\n      })\n\n      const classes = [baseClass]\n\n      if (this.properties.size && this.properties.size !== 'default') {\n        classes.push(`badge-${this.properties.size}`)\n      }\n\n      this.setData({ className: classes.join(' ') })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/badge.json",
          "target": "components/ui/badge.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        }
      ],
      "dependencies": [
        "@timui/core"
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "banner",
      "type": "registry:ui",
      "dependencies": [
        "@timui/core"
      ],
      "files": [
        {
          "path": "registry/default/ui/banner.tsx",
          "type": "registry:ui",
          "target": "components/ui/banner.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport {\n  bannerActionsVariants,\n  bannerContentVariants,\n  bannerDescriptionVariants,\n  bannerIconVariants,\n  bannerTitleVariants,\n  bannerVariants,\n  cn,\n} from '@timui/core'\n\nconst Banner = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, ...props }, ref) => (\n    <div ref={ref} data-slot=\"banner\" className={cn(bannerVariants(), className)} {...props} />\n  )\n)\nBanner.displayName = 'Banner'\n\nconst BannerContent = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, ...props }, ref) => (\n    <div\n      ref={ref}\n      data-slot=\"banner-content\"\n      className={cn(bannerContentVariants(), className)}\n      {...props}\n    />\n  )\n)\nBannerContent.displayName = 'BannerContent'\n\nconst BannerIcon = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, ...props }, ref) => (\n    <div\n      ref={ref}\n      data-slot=\"banner-icon\"\n      className={cn(bannerIconVariants(), className)}\n      {...props}\n    />\n  )\n)\nBannerIcon.displayName = 'BannerIcon'\n\nconst BannerTitle = React.forwardRef<HTMLHeadingElement, React.HTMLAttributes<HTMLHeadingElement>>(\n  ({ className, ...props }, ref) => (\n    <h5\n      ref={ref}\n      data-slot=\"banner-title\"\n      className={cn(bannerTitleVariants(), className)}\n      {...props}\n    />\n  )\n)\nBannerTitle.displayName = 'BannerTitle'\n\nconst BannerDescription = React.forwardRef<\n  HTMLParagraphElement,\n  React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n  <div\n    ref={ref}\n    data-slot=\"banner-description\"\n    className={cn(bannerDescriptionVariants(), className)}\n    {...props}\n  />\n))\nBannerDescription.displayName = 'BannerDescription'\n\nconst BannerActions = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, ...props }, ref) => (\n    <div\n      ref={ref}\n      data-slot=\"banner-actions\"\n      className={cn(bannerActionsVariants(), className)}\n      {...props}\n    />\n  )\n)\nBannerActions.displayName = 'BannerActions'\n\nexport { Banner, BannerActions, BannerContent, BannerDescription, BannerIcon, BannerTitle }\n"
        },
        {
          "path": "registry/default/vue/banner/banner-actions.vue",
          "target": "components/ui/banner/banner-actions.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes } from 'vue'\nimport { bannerActionsVariants } from '@timui/core'\nimport { cn } from '@timui/core'\n\ninterface Props {\n  class?: HTMLAttributes['class']\n}\n\nconst props = defineProps<Props>()\n</script>\n\n<template>\n  <div data-slot=\"banner-actions\" :class=\"cn(bannerActionsVariants(), props.class)\">\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/banner/banner-content.vue",
          "target": "components/ui/banner/banner-content.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes } from 'vue'\nimport { bannerContentVariants } from '@timui/core'\nimport { cn } from '@timui/core'\n\ninterface Props {\n  class?: HTMLAttributes['class']\n}\n\nconst props = defineProps<Props>()\n</script>\n\n<template>\n  <div data-slot=\"banner-content\" :class=\"cn(bannerContentVariants(), props.class)\">\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/banner/banner-description.vue",
          "target": "components/ui/banner/banner-description.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes } from 'vue'\nimport { bannerDescriptionVariants } from '@timui/core'\nimport { cn } from '@timui/core'\n\ninterface Props {\n  class?: HTMLAttributes['class']\n}\n\nconst props = defineProps<Props>()\n</script>\n\n<template>\n  <div data-slot=\"banner-description\" :class=\"cn(bannerDescriptionVariants(), props.class)\">\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/banner/banner-icon.vue",
          "target": "components/ui/banner/banner-icon.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes } from 'vue'\nimport { bannerIconVariants } from '@timui/core'\nimport { cn } from '@timui/core'\n\ninterface Props {\n  class?: HTMLAttributes['class']\n}\n\nconst props = defineProps<Props>()\n</script>\n\n<template>\n  <div data-slot=\"banner-icon\" :class=\"cn(bannerIconVariants(), props.class)\">\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/banner/banner-title.vue",
          "target": "components/ui/banner/banner-title.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes } from 'vue'\nimport { bannerTitleVariants } from '@timui/core'\nimport { cn } from '@timui/core'\n\ninterface Props {\n  class?: HTMLAttributes['class']\n}\n\nconst props = defineProps<Props>()\n</script>\n\n<template>\n  <h5 data-slot=\"banner-title\" :class=\"cn(bannerTitleVariants(), props.class)\">\n    <slot />\n  </h5>\n</template>\n"
        },
        {
          "path": "registry/default/vue/banner/banner.vue",
          "target": "components/ui/banner/banner.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes } from 'vue'\nimport { bannerVariants } from '@timui/core'\nimport { cn } from '@timui/core'\n\ninterface Props {\n  class?: HTMLAttributes['class']\n}\n\nconst props = defineProps<Props>()\n</script>\n\n<template>\n  <div data-slot=\"banner\" :class=\"cn(bannerVariants(), props.class)\">\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/html/banner.html",
          "target": "components/ui/banner.html",
          "type": "registry:component",
          "content": "<div class=\"relative flex w-full items-center justify-between gap-4 border-b bg-muted/30 px-4 py-3\" data-slot=\"banner\">\n  <div class=\"flex items-center gap-3\" data-slot=\"banner-content\">\n    <div class=\"size-5 shrink-0\" data-slot=\"banner-icon\">!</div>\n    <div class=\"flex items-center gap-3\">\n      <h5 class=\"text-sm font-medium\" data-slot=\"banner-title\">Update available</h5>\n      <div class=\"text-muted-foreground text-sm\" data-slot=\"banner-description\">\n        A newer version is ready to install.\n      </div>\n    </div>\n    <div class=\"flex items-center gap-2\" data-slot=\"banner-actions\">\n      <button class=\"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground shadow hover:bg-primary/90 h-9 px-4 py-2\">\n        Update\n      </button>\n    </div>\n  </div>\n</div>"
        },
        {
          "path": "registry/default/weapp/banner.wxml",
          "target": "components/ui/banner.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\" data-slot=\"banner\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/banner.wxss",
          "target": "components/ui/banner.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/banner.ts",
          "target": "components/ui/banner.ts",
          "type": "registry:component",
          "content": "import { bannerVariants } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass) {\n      this.setData({\n        className: bannerVariants({ className: extClass }),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/banner.json",
          "target": "components/ui/banner.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/banner-actions/banner-actions.wxml",
          "target": "components/ui/banner-actions/banner-actions.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\" data-slot=\"banner-actions\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/banner-actions/banner-actions.wxss",
          "target": "components/ui/banner-actions/banner-actions.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/banner-actions/banner-actions.json",
          "target": "components/ui/banner-actions/banner-actions.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/banner-actions/banner-actions.ts",
          "target": "components/ui/banner-actions/banner-actions.ts",
          "type": "registry:component",
          "content": "import { bannerActionsVariants } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass) {\n      this.setData({\n        className: bannerActionsVariants({ className: extClass }),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/banner-content/banner-content.wxml",
          "target": "components/ui/banner-content/banner-content.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\" data-slot=\"banner-content\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/banner-content/banner-content.wxss",
          "target": "components/ui/banner-content/banner-content.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/banner-content/banner-content.json",
          "target": "components/ui/banner-content/banner-content.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/banner-content/banner-content.ts",
          "target": "components/ui/banner-content/banner-content.ts",
          "type": "registry:component",
          "content": "import { bannerContentVariants } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass) {\n      this.setData({\n        className: bannerContentVariants({ className: extClass }),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/banner-description/banner-description.wxml",
          "target": "components/ui/banner-description/banner-description.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\" data-slot=\"banner-description\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/banner-description/banner-description.wxss",
          "target": "components/ui/banner-description/banner-description.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/banner-description/banner-description.json",
          "target": "components/ui/banner-description/banner-description.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/banner-description/banner-description.ts",
          "target": "components/ui/banner-description/banner-description.ts",
          "type": "registry:component",
          "content": "import { bannerDescriptionVariants } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass) {\n      this.setData({\n        className: bannerDescriptionVariants({ className: extClass }),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/banner-icon/banner-icon.wxml",
          "target": "components/ui/banner-icon/banner-icon.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\" data-slot=\"banner-icon\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/banner-icon/banner-icon.wxss",
          "target": "components/ui/banner-icon/banner-icon.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/banner-icon/banner-icon.json",
          "target": "components/ui/banner-icon/banner-icon.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/banner-icon/banner-icon.ts",
          "target": "components/ui/banner-icon/banner-icon.ts",
          "type": "registry:component",
          "content": "import { bannerIconVariants } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass) {\n      this.setData({\n        className: bannerIconVariants({ className: extClass }),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/banner-title/banner-title.wxml",
          "target": "components/ui/banner-title/banner-title.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\" data-slot=\"banner-title\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/banner-title/banner-title.wxss",
          "target": "components/ui/banner-title/banner-title.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/banner-title/banner-title.json",
          "target": "components/ui/banner-title/banner-title.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/banner-title/banner-title.ts",
          "target": "components/ui/banner-title/banner-title.ts",
          "type": "registry:component",
          "content": "import { bannerTitleVariants } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass) {\n      this.setData({\n        className: bannerTitleVariants({ className: extClass }),\n      })\n    },\n  },\n})\n"
        }
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "breadcrumb",
      "type": "registry:ui",
      "dependencies": [
        "@timui/core"
      ],
      "files": [
        {
          "path": "registry/default/ui/breadcrumb.tsx",
          "type": "registry:ui",
          "target": "components/ui/breadcrumb.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport {\n  breadcrumbEllipsisVariants,\n  breadcrumbItemVariants,\n  breadcrumbLinkVariants,\n  breadcrumbListVariants,\n  breadcrumbPageVariants,\n  breadcrumbSeparatorVariants,\n  cn,\n} from '@timui/core'\n\nimport { Slot } from './slot'\n\nfunction Breadcrumb({ ...props }: React.ComponentProps<'nav'>) {\n  return <nav aria-label=\"breadcrumb\" data-slot=\"breadcrumb\" {...props} />\n}\n\nfunction BreadcrumbList({ className, ...props }: React.ComponentProps<'ol'>) {\n  return (\n    <ol\n      data-slot=\"breadcrumb-list\"\n      className={cn(breadcrumbListVariants(), className)}\n      {...props}\n    />\n  )\n}\n\nfunction BreadcrumbItem({ className, ...props }: React.ComponentProps<'li'>) {\n  return (\n    <li\n      data-slot=\"breadcrumb-item\"\n      className={cn(breadcrumbItemVariants(), className)}\n      {...props}\n    />\n  )\n}\n\nfunction BreadcrumbLink({\n  asChild,\n  className,\n  ...props\n}: React.ComponentProps<'a'> & {\n  asChild?: boolean\n}) {\n  const Comp = asChild ? Slot : 'a'\n\n  return (\n    <Comp\n      data-slot=\"breadcrumb-link\"\n      className={cn(breadcrumbLinkVariants(), className)}\n      {...props}\n    />\n  )\n}\n\nfunction BreadcrumbPage({ className, ...props }: React.ComponentProps<'span'>) {\n  return (\n    <span\n      data-slot=\"breadcrumb-page\"\n      role=\"link\"\n      aria-disabled=\"true\"\n      aria-current=\"page\"\n      className={cn(breadcrumbPageVariants(), className)}\n      {...props}\n    />\n  )\n}\n\nfunction BreadcrumbSeparator({ children, className, ...props }: React.ComponentProps<'li'>) {\n  return (\n    <li\n      data-slot=\"breadcrumb-separator\"\n      role=\"presentation\"\n      aria-hidden=\"true\"\n      className={cn(breadcrumbSeparatorVariants(), className)}\n      {...props}\n    >\n      {children ?? (\n        <svg\n          width={16}\n          height={16}\n          viewBox=\"0 0 24 24\"\n          fill=\"none\"\n          stroke=\"currentColor\"\n          strokeWidth=\"2\"\n          strokeLinecap=\"round\"\n          strokeLinejoin=\"round\"\n          aria-hidden=\"true\"\n        >\n          <path d=\"m9 18 6-6-6-6\" />\n        </svg>\n      )}\n    </li>\n  )\n}\n\nfunction BreadcrumbEllipsis({ className, ...props }: React.ComponentProps<'span'>) {\n  return (\n    <span\n      data-slot=\"breadcrumb-ellipsis\"\n      role=\"presentation\"\n      aria-hidden=\"true\"\n      className={cn(breadcrumbEllipsisVariants(), className)}\n      {...props}\n    >\n      <svg\n        width={16}\n        height={16}\n        viewBox=\"0 0 24 24\"\n        fill=\"none\"\n        stroke=\"currentColor\"\n        strokeWidth=\"2\"\n        strokeLinecap=\"round\"\n        strokeLinejoin=\"round\"\n        aria-hidden=\"true\"\n      >\n        <circle cx=\"5\" cy=\"12\" r=\"1.5\" />\n        <circle cx=\"12\" cy=\"12\" r=\"1.5\" />\n        <circle cx=\"19\" cy=\"12\" r=\"1.5\" />\n      </svg>\n      <span className=\"sr-only\">More</span>\n    </span>\n  )\n}\n\nexport {\n  Breadcrumb,\n  BreadcrumbEllipsis,\n  BreadcrumbItem,\n  BreadcrumbLink,\n  BreadcrumbList,\n  BreadcrumbPage,\n  BreadcrumbSeparator,\n}\n"
        },
        {
          "path": "registry/default/vue/breadcrumb/breadcrumb-ellipsis.vue",
          "target": "components/ui/breadcrumb/breadcrumb-ellipsis.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes } from 'vue'\nimport { breadcrumbEllipsisVariants, cn } from '@timui/core'\n\nconst props = defineProps<{\n  class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n  <span\n    data-slot=\"breadcrumb-ellipsis\"\n    role=\"presentation\"\n    aria-hidden=\"true\"\n    :class=\"cn(breadcrumbEllipsisVariants(), props.class)\"\n  >\n    <slot>\n      <svg\n        width=\"16\"\n        height=\"16\"\n        viewBox=\"0 0 24 24\"\n        fill=\"none\"\n        stroke=\"currentColor\"\n        stroke-width=\"2\"\n        stroke-linecap=\"round\"\n        stroke-linejoin=\"round\"\n        aria-hidden=\"true\"\n      >\n        <circle cx=\"5\" cy=\"12\" r=\"1.5\" />\n        <circle cx=\"12\" cy=\"12\" r=\"1.5\" />\n        <circle cx=\"19\" cy=\"12\" r=\"1.5\" />\n      </svg>\n    </slot>\n    <span class=\"sr-only\">More</span>\n  </span>\n</template>\n"
        },
        {
          "path": "registry/default/vue/breadcrumb/breadcrumb-item.vue",
          "target": "components/ui/breadcrumb/breadcrumb-item.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { breadcrumbItemVariants, cn } from '@timui/core'\n\nconst props = defineProps<{\n  class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n  <li data-slot=\"breadcrumb-item\" :class=\"cn(breadcrumbItemVariants(), props.class)\">\n    <slot />\n  </li>\n</template>\n"
        },
        {
          "path": "registry/default/vue/breadcrumb/breadcrumb-link.vue",
          "target": "components/ui/breadcrumb/breadcrumb-link.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Primitive, type PrimitiveProps } from '../../primitive'\nimport { breadcrumbLinkVariants, cn } from '@timui/core'\nimport type { HTMLAttributes } from 'vue'\n\nconst props = withDefaults(defineProps<PrimitiveProps & { class?: HTMLAttributes['class'] }>(), {\n  as: 'a',\n})\n</script>\n\n<template>\n  <Primitive\n    :as=\"as\"\n    :as-child=\"asChild\"\n    data-slot=\"breadcrumb-link\"\n    :class=\"cn(breadcrumbLinkVariants(), props.class)\"\n  >\n    <slot />\n  </Primitive>\n</template>\n"
        },
        {
          "path": "registry/default/vue/breadcrumb/breadcrumb-list.vue",
          "target": "components/ui/breadcrumb/breadcrumb-list.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { breadcrumbListVariants, cn } from '@timui/core'\n\nconst props = defineProps<{\n  class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n  <ol data-slot=\"breadcrumb-list\" :class=\"cn(breadcrumbListVariants(), props.class)\">\n    <slot />\n  </ol>\n</template>\n"
        },
        {
          "path": "registry/default/vue/breadcrumb/breadcrumb-page.vue",
          "target": "components/ui/breadcrumb/breadcrumb-page.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes } from 'vue'\nimport { breadcrumbPageVariants, cn } from '@timui/core'\n\nconst props = defineProps<{\n  class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n  <span\n    data-slot=\"breadcrumb-page\"\n    role=\"link\"\n    aria-disabled=\"true\"\n    aria-current=\"page\"\n    :class=\"cn(breadcrumbPageVariants(), props.class)\"\n  >\n    <slot />\n  </span>\n</template>\n"
        },
        {
          "path": "registry/default/vue/breadcrumb/breadcrumb-separator.vue",
          "target": "components/ui/breadcrumb/breadcrumb-separator.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes } from 'vue'\nimport { breadcrumbSeparatorVariants, cn } from '@timui/core'\n\nconst props = defineProps<{\n  class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n  <li\n    data-slot=\"breadcrumb-separator\"\n    role=\"presentation\"\n    aria-hidden=\"true\"\n    :class=\"cn(breadcrumbSeparatorVariants(), props.class)\"\n  >\n    <slot>\n      <svg\n        width=\"16\"\n        height=\"16\"\n        viewBox=\"0 0 24 24\"\n        fill=\"none\"\n        stroke=\"currentColor\"\n        stroke-width=\"2\"\n        stroke-linecap=\"round\"\n        stroke-linejoin=\"round\"\n        aria-hidden=\"true\"\n      >\n        <path d=\"m9 18 6-6-6-6\" />\n      </svg>\n    </slot>\n  </li>\n</template>\n"
        },
        {
          "path": "registry/default/vue/breadcrumb/breadcrumb.vue",
          "target": "components/ui/breadcrumb/breadcrumb.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@timui/core'\n\nconst props = defineProps<{\n  class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n  <nav aria-label=\"breadcrumb\" data-slot=\"breadcrumb\" :class=\"cn(props.class)\">\n    <slot />\n  </nav>\n</template>\n"
        },
        {
          "path": "registry/default/vue/breadcrumb/index.ts",
          "target": "components/ui/breadcrumb/index.ts",
          "type": "registry:component",
          "content": "export { default } from './breadcrumb.vue'\nexport { default as BreadcrumbEllipsis } from './breadcrumb-ellipsis.vue'\nexport { default as BreadcrumbItem } from './breadcrumb-item.vue'\nexport { default as BreadcrumbLink } from './breadcrumb-link.vue'\nexport { default as BreadcrumbList } from './breadcrumb-list.vue'\nexport { default as BreadcrumbPage } from './breadcrumb-page.vue'\nexport { default as BreadcrumbSeparator } from './breadcrumb-separator.vue'\nexport { default as Breadcrumb } from './breadcrumb.vue'\n"
        },
        {
          "path": "registry/default/html/breadcrumb.html",
          "target": "components/ui/breadcrumb.html",
          "type": "registry:component",
          "content": "<nav aria-label=\"breadcrumb\" data-slot=\"breadcrumb\">\n  <ol data-slot=\"breadcrumb-list\" class=\"text-muted-foreground flex flex-wrap items-center gap-1.5 text-sm break-words sm:gap-2.5\">\n    <li data-slot=\"breadcrumb-item\" class=\"inline-flex items-center gap-1.5\">\n      <a data-slot=\"breadcrumb-link\" href=\"#\" class=\"transition-colors hover:text-foreground\">Home</a>\n    </li>\n    <li data-slot=\"breadcrumb-separator\" role=\"presentation\" aria-hidden=\"true\">\n      <svg\n        width=\"16\"\n        height=\"16\"\n        viewBox=\"0 0 24 24\"\n        fill=\"none\"\n        stroke=\"currentColor\"\n        stroke-width=\"2\"\n        stroke-linecap=\"round\"\n        stroke-linejoin=\"round\"\n        aria-hidden=\"true\"\n      >\n        <path d=\"m9 18 6-6-6-6\" />\n      </svg>\n    </li>\n    <li data-slot=\"breadcrumb-item\" class=\"inline-flex items-center gap-1.5\">\n      <span data-slot=\"breadcrumb-page\" role=\"link\" aria-disabled=\"true\" aria-current=\"page\" class=\"text-foreground font-normal\">\n        Breadcrumb\n      </span>\n    </li>\n  </ol>\n</nav>"
        },
        {
          "path": "registry/default/weapp/breadcrumb.wxml",
          "target": "components/ui/breadcrumb.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}} breadcrumb\">\n  <block wx:for=\"{{items}}\" wx:key=\"index\">\n    <view \n      class=\"breadcrumb-item\"\n      data-index=\"{{index}}\"\n      bindtap=\"onItemTap\"\n      data-current=\"{{index === items.length - 1}}\"\n    >\n      <text class=\"breadcrumb-link\">{{item.label || item}}</text>\n    </view>\n    <text \n      wx:if=\"{{index < items.length - 1}}\" \n      class=\"breadcrumb-separator\"\n    >\n      {{separator}}\n    </text>\n  </block>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/breadcrumb.wxss",
          "target": "components/ui/breadcrumb.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/breadcrumb.ts",
          "target": "components/ui/breadcrumb.ts",
          "type": "registry:component",
          "content": "import { breadcrumbListVariants } from '../utils'\n\ntype BreadcrumbItem =\n  | string\n  | {\n      label?: string\n      value?: string\n      href?: string\n    }\n\ntype BreadcrumbTapEvent = WechatMiniprogram.BaseEvent & {\n  currentTarget: {\n    dataset: {\n      index?: number\n    }\n  }\n}\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    items: { type: Array, value: [] },\n    separator: { type: String, value: '/' },\n    extClass: { type: String, value: '' },\n  },\n\n  data: {\n    className: '',\n  },\n\n  lifetimes: {\n    attached() {\n      this.updateClassName()\n    },\n  },\n\n  observers: {\n    extClass: function () {\n      this.updateClassName()\n    },\n  },\n\n  methods: {\n    updateClassName() {\n      // Use core package's breadcrumbListVariants for consistent styling\n      const baseClass = breadcrumbListVariants({\n        className: this.properties.extClass,\n      })\n\n      this.setData({ className: baseClass })\n    },\n\n    onItemTap(e: BreadcrumbTapEvent) {\n      const index = e.currentTarget.dataset.index\n      if (typeof index === 'number') {\n        const items = this.properties.items as BreadcrumbItem[]\n        const item = items[index]\n        this.triggerEvent('tap', { index, item })\n      }\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/breadcrumb.json",
          "target": "components/ui/breadcrumb.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        },
        {
          "path": "registry/default/weapp/breadcrumb-ellipsis/breadcrumb-ellipsis.wxml",
          "target": "components/ui/breadcrumb-ellipsis/breadcrumb-ellipsis.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\" data-slot=\"breadcrumb-ellipsis\" role=\"presentation\" aria-hidden=\"true\">\n  <slot>\n    <svg\n      width=\"16\"\n      height=\"16\"\n      viewBox=\"0 0 24 24\"\n      fill=\"none\"\n      stroke=\"currentColor\"\n      stroke-width=\"2\"\n      stroke-linecap=\"round\"\n      stroke-linejoin=\"round\"\n      aria-hidden=\"true\"\n    >\n      <circle cx=\"5\" cy=\"12\" r=\"1.5\" />\n      <circle cx=\"12\" cy=\"12\" r=\"1.5\" />\n      <circle cx=\"19\" cy=\"12\" r=\"1.5\" />\n    </svg>\n  </slot>\n  <text class=\"sr-only\">More</text>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/breadcrumb-ellipsis/breadcrumb-ellipsis.wxss",
          "target": "components/ui/breadcrumb-ellipsis/breadcrumb-ellipsis.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/breadcrumb-ellipsis/breadcrumb-ellipsis.json",
          "target": "components/ui/breadcrumb-ellipsis/breadcrumb-ellipsis.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/breadcrumb-ellipsis/breadcrumb-ellipsis.ts",
          "target": "components/ui/breadcrumb-ellipsis/breadcrumb-ellipsis.ts",
          "type": "registry:component",
          "content": "import { breadcrumbEllipsisVariants } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass) {\n      this.setData({\n        className: breadcrumbEllipsisVariants({ className: extClass }),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/breadcrumb-item/breadcrumb-item.wxml",
          "target": "components/ui/breadcrumb-item/breadcrumb-item.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\" data-slot=\"breadcrumb-item\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/breadcrumb-item/breadcrumb-item.wxss",
          "target": "components/ui/breadcrumb-item/breadcrumb-item.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/breadcrumb-item/breadcrumb-item.json",
          "target": "components/ui/breadcrumb-item/breadcrumb-item.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/breadcrumb-item/breadcrumb-item.ts",
          "target": "components/ui/breadcrumb-item/breadcrumb-item.ts",
          "type": "registry:component",
          "content": "import { breadcrumbItemVariants } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass) {\n      this.setData({\n        className: breadcrumbItemVariants({ className: extClass }),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/breadcrumb-link/breadcrumb-link.wxml",
          "target": "components/ui/breadcrumb-link/breadcrumb-link.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\" data-slot=\"breadcrumb-link\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/breadcrumb-link/breadcrumb-link.wxss",
          "target": "components/ui/breadcrumb-link/breadcrumb-link.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/breadcrumb-link/breadcrumb-link.json",
          "target": "components/ui/breadcrumb-link/breadcrumb-link.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/breadcrumb-link/breadcrumb-link.ts",
          "target": "components/ui/breadcrumb-link/breadcrumb-link.ts",
          "type": "registry:component",
          "content": "import { breadcrumbLinkVariants } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass) {\n      this.setData({\n        className: breadcrumbLinkVariants({ className: extClass }),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/breadcrumb-list/breadcrumb-list.wxml",
          "target": "components/ui/breadcrumb-list/breadcrumb-list.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\" data-slot=\"breadcrumb-list\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/breadcrumb-list/breadcrumb-list.wxss",
          "target": "components/ui/breadcrumb-list/breadcrumb-list.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/breadcrumb-list/breadcrumb-list.json",
          "target": "components/ui/breadcrumb-list/breadcrumb-list.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/breadcrumb-list/breadcrumb-list.ts",
          "target": "components/ui/breadcrumb-list/breadcrumb-list.ts",
          "type": "registry:component",
          "content": "import { breadcrumbListVariants } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass) {\n      this.setData({\n        className: breadcrumbListVariants({ className: extClass }),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/breadcrumb-page/breadcrumb-page.wxml",
          "target": "components/ui/breadcrumb-page/breadcrumb-page.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\" data-slot=\"breadcrumb-page\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/breadcrumb-page/breadcrumb-page.wxss",
          "target": "components/ui/breadcrumb-page/breadcrumb-page.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/breadcrumb-page/breadcrumb-page.json",
          "target": "components/ui/breadcrumb-page/breadcrumb-page.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/breadcrumb-page/breadcrumb-page.ts",
          "target": "components/ui/breadcrumb-page/breadcrumb-page.ts",
          "type": "registry:component",
          "content": "import { breadcrumbPageVariants } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass) {\n      this.setData({\n        className: breadcrumbPageVariants({ className: extClass }),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/breadcrumb-separator/breadcrumb-separator.wxml",
          "target": "components/ui/breadcrumb-separator/breadcrumb-separator.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\" data-slot=\"breadcrumb-separator\" role=\"presentation\" aria-hidden=\"true\">\n  <slot>\n    <svg\n      width=\"16\"\n      height=\"16\"\n      viewBox=\"0 0 24 24\"\n      fill=\"none\"\n      stroke=\"currentColor\"\n      stroke-width=\"2\"\n      stroke-linecap=\"round\"\n      stroke-linejoin=\"round\"\n      aria-hidden=\"true\"\n    >\n      <path d=\"m9 18 6-6-6-6\" />\n    </svg>\n  </slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/breadcrumb-separator/breadcrumb-separator.wxss",
          "target": "components/ui/breadcrumb-separator/breadcrumb-separator.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/breadcrumb-separator/breadcrumb-separator.json",
          "target": "components/ui/breadcrumb-separator/breadcrumb-separator.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/breadcrumb-separator/breadcrumb-separator.ts",
          "target": "components/ui/breadcrumb-separator/breadcrumb-separator.ts",
          "type": "registry:component",
          "content": "import { breadcrumbSeparatorVariants } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass) {\n      this.setData({\n        className: breadcrumbSeparatorVariants({ className: extClass }),\n      })\n    },\n  },\n})\n"
        }
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "button",
      "type": "registry:ui",
      "dependencies": [
        "@timui/core"
      ],
      "files": [
        {
          "path": "registry/default/ui/button.tsx",
          "type": "registry:ui",
          "target": "components/ui/button.tsx",
          "content": "import * as React from 'react'\nimport type { ButtonProps as CoreButtonProps } from '@timui/core'\nimport { buttonVariants, cn, createTimEvent } from '@timui/core'\n\nimport { Slot } from './slot'\n\nexport type ButtonProps = CoreButtonProps &\n  Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, keyof CoreButtonProps>\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n  ({ className, variant, size, id, asChild = false, onClick, onPress, ...props }, ref) => {\n    const Comp = asChild ? Slot : 'button'\n    const generatedId = React.useId()\n    const buttonId = id ?? generatedId\n\n    return (\n      <Comp\n        data-slot=\"button\"\n        id={buttonId}\n        className={cn(buttonVariants({ variant, size, className }))}\n        ref={ref}\n        onClick={(event: React.MouseEvent<HTMLButtonElement>) => {\n          onClick?.(event)\n          onPress?.(createTimEvent('press', buttonId, {}))\n        }}\n        {...props}\n      />\n    )\n  }\n)\nButton.displayName = 'Button'\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "registry/default/vue/button.vue",
          "type": "registry:ui",
          "target": "components/ui/button.vue",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed, useId } from 'vue'\nimport type { AssertNoExtraKeys, ButtonProps as CoreButtonProps, ButtonPressEvent } from '@timui/core'\nimport { type PrimitiveProps, Primitive } from '../../primitive'\nimport { cn, buttonVariants, createTimEvent } from '@timui/core'\n\ntype ButtonProps = CoreButtonProps &\n  /* @vue-ignore */ PrimitiveProps & {\n    class?: HTMLAttributes['class']\n    id?: string\n  }\ntype _ButtonPropsGuard = AssertNoExtraKeys<\n  ButtonProps,\n  CoreButtonProps & PrimitiveProps & { class?: HTMLAttributes['class'], id?: string }\n>\n\ninterface Props extends ButtonProps {}\n\nconst emit = defineEmits<{\n  (e: 'press', event: ButtonPressEvent): void\n}>()\n\nconst props = withDefaults(defineProps<Props>(), {\n  as: 'button',\n})\n\nconst calculatedClass = computed(() =>\n  cn(buttonVariants({ variant: props.variant, size: props.size }), props.class)\n)\n\nconst generatedId = useId()\nconst buttonId = computed(() => props.id ?? generatedId)\n\nconst handlePress = (event: MouseEvent) => {\n  // Emit the custom TimEvent (cross-platform press protocol)\n  emit('press', createTimEvent('press', buttonId.value, {}))\n  // Also call onPress prop directly if provided (matches React's onPress prop pattern)\n  props.onPress?.(createTimEvent('press', buttonId.value, {}))\n}\n</script>\n\n<template>\n  <Primitive\n    data-slot=\"button\"\n    :id=\"buttonId\"\n    :as=\"as\"\n    :as-child=\"asChild\"\n    :class=\"calculatedClass\"\n    @click=\"handlePress\"\n  >\n    <slot />\n  </Primitive>\n</template>\n"
        },
        {
          "path": "registry/default/vue/button/button.vue",
          "target": "components/ui/button/button.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed, useId } from 'vue'\nimport type { AssertNoExtraKeys, ButtonProps as CoreButtonProps, ButtonPressEvent } from '@timui/core'\nimport { type PrimitiveProps, Primitive } from '../../primitive'\nimport { cn, buttonVariants, createTimEvent } from '@timui/core'\n\ntype ButtonProps = CoreButtonProps &\n  /* @vue-ignore */ PrimitiveProps & {\n    class?: HTMLAttributes['class']\n    id?: string\n  }\ntype _ButtonPropsGuard = AssertNoExtraKeys<\n  ButtonProps,\n  CoreButtonProps & PrimitiveProps & { class?: HTMLAttributes['class'], id?: string }\n>\n\ninterface Props extends ButtonProps {}\n\nconst emit = defineEmits<{\n  (e: 'press', event: ButtonPressEvent): void\n}>()\n\nconst props = withDefaults(defineProps<Props>(), {\n  as: 'button',\n})\n\nconst calculatedClass = computed(() =>\n  cn(buttonVariants({ variant: props.variant, size: props.size }), props.class)\n)\n\nconst generatedId = useId()\nconst buttonId = computed(() => props.id ?? generatedId)\n\nconst handlePress = (event: MouseEvent) => {\n  // Emit the custom TimEvent (cross-platform press protocol)\n  emit('press', createTimEvent('press', buttonId.value, {}))\n  // Also call onPress prop directly if provided (matches React's onPress prop pattern)\n  props.onPress?.(createTimEvent('press', buttonId.value, {}))\n}\n</script>\n\n<template>\n  <Primitive\n    data-slot=\"button\"\n    :id=\"buttonId\"\n    :as=\"as\"\n    :as-child=\"asChild\"\n    :class=\"calculatedClass\"\n    @click=\"handlePress\"\n  >\n    <slot />\n  </Primitive>\n</template>\n"
        },
        {
          "path": "registry/default/html/button.html",
          "target": "components/ui/button.html",
          "type": "registry:component",
          "content": "<button\n  data-slot=\"button\"\n  class=\"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground shadow hover:bg-primary/90 h-9 px-4 py-2\"\n>\n    Button\n</button>"
        },
        {
          "path": "registry/default/weapp/button.wxml",
          "target": "components/ui/button.wxml",
          "type": "registry:component",
          "content": "<button\n  class=\"{{className}}\"\n  disabled=\"{{disabled}}\"\n  loading=\"{{loading}}\"\n  open-type=\"{{openType}}\"\n  form-type=\"{{formType}}\"\n  hover-class=\"{{hoverClass}}\"\n  hover-stop-propagation=\"{{hoverStopPropagation}}\"\n  hover-start-time=\"{{hoverStartTime}}\"\n  hover-stay-time=\"{{hoverStayTime}}\"\n  bindtap=\"onTap\"\n  bindgetphonenumber=\"onGetPhoneNumber\"\n  bindgetuserinfo=\"onGetUserInfo\"\n  bindopensetting=\"onOpenSetting\"\n  binderror=\"onError\"\n  bindcontact=\"onContact\"\n  data-disabled=\"{{disabled}}\"\n  data-loading=\"{{loading}}\"\n>\n  <view wx:if=\"{{loading}}\" class=\"button-loading-icon\">⏳</view>\n  <slot></slot>\n</button>\n"
        },
        {
          "path": "registry/default/weapp/button.wxss",
          "target": "components/ui/button.wxss",
          "type": "registry:component",
          "content": "/* packages/weapp/src/button/button.wxss */\n\n/* Additional resets for Weapp Button if not covered by tailwind utilities */\nbutton {\n  margin: 0;\n  padding: 0;\n  border: none;\n  background-color: transparent;\n  line-height: normal; /* Check shared config 'leading-normal' matches */\n  border-radius: 0;\n}\n\n/* Button variants use 'bg-primary' etc from utilities */\n/* Hover uses 'hover-bg-primary' etc from utilities */\n\n/* Because we use <button> tag, some user agent styles might persist. \n   The 'w-full' or 'inline-flex' from shared should override display. \n*/\n"
        },
        {
          "path": "registry/default/weapp/button.ts",
          "target": "components/ui/button.ts",
          "type": "registry:component",
          "content": "import { buttonVariants, createTimEvent, type JsonValue } from '../utils'\nimport {\n  createWeappBaseProps,\n  createWeappOptions,\n  WEAPP_EXTERNAL_CLASSES,\n} from '../utils/component'\n\ntype TapEvent = WechatMiniprogram.BaseEvent<{\n  value?: string\n}>\n\nComponent({\n  options: createWeappOptions({ pureData: true }),\n\n  externalClasses: WEAPP_EXTERNAL_CLASSES,\n\n  properties: {\n    variant: { type: String, value: 'default' },\n    size: { type: String, value: 'default' },\n    disabled: { type: Boolean, value: false },\n    loading: { type: Boolean, value: false },\n    plain: { type: Boolean, value: false },\n    ...createWeappBaseProps('button'),\n    // 微信原生 <button> 能力\n    openType: { type: String, value: '' },\n    formType: { type: String, value: '' },\n    hoverClass: { type: String, value: 'button-hover' },\n    hoverStopPropagation: { type: Boolean, value: false },\n    hoverStartTime: { type: Number, value: 20 },\n    hoverStayTime: { type: Number, value: 70 },\n  },\n\n  data: {\n    className: '',\n  },\n\n  lifetimes: {\n    attached() {\n      this.updateClassName()\n    },\n  },\n\n  observers: {\n    'variant, size, disabled, loading, plain, extClass': function () {\n      this.updateClassName()\n    },\n  },\n\n  methods: {\n    updateClassName() {\n      // buttonVariants is a CVA function returning a string (not {baseClass})\n      const baseClass = buttonVariants({\n        variant: (this.properties.variant || 'default') as\n          | 'default'\n          | 'destructive'\n          | 'outline'\n          | 'secondary'\n          | 'ghost'\n          | 'link',\n        size: (this.properties.size === 'icon' ? 'icon' : this.properties.size || 'default') as\n          | 'default'\n          | 'sm'\n          | 'lg'\n          | 'icon',\n      })\n\n      const classes = [baseClass]\n\n      if (this.properties.extClass) {\n        classes.push(this.properties.extClass)\n      }\n      if (this.properties.disabled) {\n        classes.push('button-disabled')\n      }\n      if (this.properties.loading) {\n        classes.push('button-loading')\n      }\n      if (this.properties.plain) {\n        classes.push('button-plain')\n      }\n\n      this.setData({ className: classes.join(' ') })\n    },\n\n    onTap(_e: TapEvent) {\n      if (!this.properties.disabled && !this.properties.loading) {\n        this.triggerEvent('tap', {})\n        const buttonId = this.properties.id || 'button'\n        this.triggerEvent(\n          'press',\n          createTimEvent('press', buttonId, {}) as Record<string, JsonValue>\n        )\n      }\n    },\n    // 微信原生 button 事件透传\n    onGetPhoneNumber(e: WechatMiniprogram.CustomEvent) {\n      this.triggerEvent('getphonenumber', e.detail)\n    },\n    onGetUserInfo(e: WechatMiniprogram.CustomEvent) {\n      this.triggerEvent('getuserinfo', e.detail)\n    },\n    onOpenSetting(e: WechatMiniprogram.CustomEvent) {\n      this.triggerEvent('opensetting', e.detail)\n    },\n    onError(e: WechatMiniprogram.CustomEvent) {\n      this.triggerEvent('error', e.detail)\n    },\n    onContact(e: WechatMiniprogram.CustomEvent) {\n      this.triggerEvent('contact', e.detail)\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/button.json",
          "target": "components/ui/button.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        }
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "calendar",
      "type": "registry:ui",
      "dependencies": [
        "@timui/core",
        "@zag-js/react"
      ],
      "registryDependencies": [
        "button"
      ],
      "files": [
        {
          "path": "registry/default/ui/calendar.tsx",
          "type": "registry:ui",
          "target": "components/ui/calendar.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport { getLocalTimeZone } from '@internationalized/date'\nimport type { DateValue } from '@internationalized/date'\nimport {\n  calendarCaptionLabelVariants,\n  calendarDayButtonVariants,\n  calendarDayVariants,\n  calendarGridVariants,\n  calendarHiddenVariants,\n  calendarMonthCaptionVariants,\n  calendarMonthsVariants,\n  calendarMonthVariants,\n  calendarNavButtonVariants,\n  calendarNavVariants,\n  calendarOutsideVariants,\n  calendarRangeEndVariants,\n  calendarRangeMiddleVariants,\n  calendarRangeStartVariants,\n  calendarRootVariants,\n  calendarTodayVariants,\n  calendarWeekdayVariants,\n  calendarWeekNumberVariants,\n  calendarConnect,\n  calendarMachine,\n  cn,\n} from '@timui/core'\nimport { mergeProps, normalizeProps, useMachine } from '@zag-js/react'\n\nimport { buttonVariants } from './button'\nimport type {\n  CalendarClassNames,\n  CalendarComponents,\n  CalendarDayButtonProps,\n  CalendarDropdownOption,\n  CalendarDropdownProps,\n  CalendarMode,\n  CalendarProps,\n  CalendarSelectedValue,\n  CalendarWeekNumberProps,\n} from './calendar/calendar-types'\nimport {\n  addMonths,\n  clampMonth,\n  compareMonth,\n  dateFromSelected,\n  getIsoWeekNumber,\n  hasUnavailableBetween,\n  matchDisabled,\n  selectedToDateValues,\n  toDateValue,\n  toMonthEnd,\n  toMonthStart,\n  valuesToSelected,\n} from './calendar/calendar-utils'\n\nfunction Calendar({\n  className,\n  classNames,\n  components: userComponents,\n  mode = 'single',\n  selected,\n  onSelect,\n  month,\n  onMonthChange,\n  defaultMonth,\n  startMonth,\n  endMonth,\n  showOutsideDays = true,\n  numberOfMonths = 1,\n  pagedNavigation = false,\n  captionLayout = 'label',\n  hideNavigation = false,\n  fixedWeeks = false,\n  showWeekNumber = false,\n  disabled,\n  excludeDisabled = false,\n  ...props\n}: CalendarProps) {\n  const timeZone = React.useMemo(() => getLocalTimeZone(), [])\n  const generatedId = React.useId()\n  const disabledMatchers = React.useMemo(\n    () => (disabled === undefined ? [] : Array.isArray(disabled) ? disabled : [disabled]),\n    [disabled]\n  )\n\n  const minMonth = React.useMemo(() => (startMonth ? toMonthStart(startMonth) : undefined), [startMonth])\n  const maxMonth = React.useMemo(() => {\n    if (!endMonth) return undefined\n    return addMonths(toMonthStart(endMonth), -(numberOfMonths - 1))\n  }, [endMonth, numberOfMonths])\n\n  const initialMonth = React.useMemo(() => {\n    const base = month ?? defaultMonth ?? dateFromSelected(selected, mode) ?? new Date()\n    return clampMonth(toMonthStart(base), minMonth, maxMonth)\n  }, [month, defaultMonth, selected, mode, minMonth, maxMonth])\n\n  const [uncontrolledMonth, setUncontrolledMonth] = React.useState(initialMonth)\n  const viewMonth = React.useMemo(\n    () => (month ? clampMonth(toMonthStart(month), minMonth, maxMonth) : uncontrolledMonth),\n    [month, minMonth, maxMonth, uncontrolledMonth]\n  )\n  const focusedValue = React.useMemo(\n    () => (month ? toDateValue(viewMonth) : undefined),\n    [month, viewMonth]\n  )\n  const defaultFocusedValue = React.useMemo(\n    () => (month ? undefined : toDateValue(initialMonth)),\n    [initialMonth, month]\n  )\n\n  React.useEffect(() => {\n    if (!month) return\n    setUncontrolledMonth(clampMonth(toMonthStart(month), minMonth, maxMonth))\n  }, [month, minMonth, maxMonth])\n\n  const selectedValues = React.useMemo(() => selectedToDateValues(selected, mode), [selected, mode])\n\n  const handleUnavailable = React.useCallback(\n    (value: DateValue) => {\n      const date = value.toDate(timeZone)\n      return disabledMatchers.some((matcher) => matchDisabled(date, matcher))\n    },\n    [disabledMatchers, timeZone]\n  )\n\n  const lastVisibleMonthRef = React.useRef<string>('')\n\n  const service = useMachine(calendarMachine, {\n    id: generatedId,\n    inline: true,\n    selectionMode: mode,\n    numOfMonths: numberOfMonths,\n    outsideDaySelectable: showOutsideDays,\n    fixedWeeks,\n    min: startMonth ? toDateValue(toMonthStart(startMonth)) : undefined,\n    max: endMonth ? toDateValue(toMonthEnd(endMonth)) : undefined,\n    focusedValue,\n    defaultFocusedValue,\n    timeZone,\n    value: selected === undefined ? undefined : selectedValues,\n    isDateUnavailable: disabledMatchers.length > 0 ? handleUnavailable : undefined,\n    onValueChange(details) {\n      const rawNext = valuesToSelected(details.value, mode, timeZone)\n      if (\n        excludeDisabled &&\n        mode === 'range' &&\n        rawNext &&\n        !Array.isArray(rawNext) &&\n        !(rawNext instanceof Date) &&\n        rawNext.from &&\n        rawNext.to\n      ) {\n        const hasUnavailable = hasUnavailableBetween(rawNext.from, rawNext.to, (date) =>\n          disabledMatchers.some((matcher) => matchDisabled(date, matcher))\n        )\n        if (hasUnavailable) {\n          onSelect?.({ from: rawNext.to, to: undefined })\n          return\n        }\n      }\n      onSelect?.(rawNext)\n    },\n    onVisibleRangeChange(details) {\n      const nextMonth = toMonthStart(details.visibleRange.start.toDate(timeZone))\n      const nextKey = `${nextMonth.getFullYear()}-${nextMonth.getMonth()}`\n      if (nextKey === lastVisibleMonthRef.current) return\n      lastVisibleMonthRef.current = nextKey\n      if (!month) {\n        setUncontrolledMonth(nextMonth)\n      }\n      onMonthChange?.(nextMonth)\n    },\n  })\n\n  const api = React.useMemo(() => calendarConnect(service, normalizeProps), [service])\n\n  const setCalendarMonth = React.useCallback(\n    (next: Date) => {\n      const clamped = clampMonth(toMonthStart(next), minMonth, maxMonth)\n      const key = `${clamped.getFullYear()}-${clamped.getMonth()}`\n      if (key === `${viewMonth.getFullYear()}-${viewMonth.getMonth()}`) return\n      if (!month) {\n        setUncontrolledMonth(clamped)\n      }\n      onMonthChange?.(clamped)\n    },\n    [minMonth, maxMonth, viewMonth, month, onMonthChange]\n  )\n\n  const canGoPrev = minMonth ? compareMonth(viewMonth, minMonth) > 0 : true\n  const canGoNext = maxMonth ? compareMonth(viewMonth, maxMonth) < 0 : true\n  const navStep = pagedNavigation ? numberOfMonths : 1\n\n  const defaultClassNames = {\n    months: calendarMonthsVariants(),\n    month: calendarMonthVariants(),\n    month_caption: calendarMonthCaptionVariants(),\n    caption_label: calendarCaptionLabelVariants(),\n    nav: calendarNavVariants(),\n    button_previous: cn(buttonVariants({ variant: 'ghost' }), calendarNavButtonVariants()),\n    button_next: cn(buttonVariants({ variant: 'ghost' }), calendarNavButtonVariants()),\n    weekday: calendarWeekdayVariants(),\n    day_button: calendarDayButtonVariants(),\n    day: calendarDayVariants(),\n    range_start: calendarRangeStartVariants(),\n    range_end: calendarRangeEndVariants(),\n    range_middle: calendarRangeMiddleVariants(),\n    today: calendarTodayVariants(),\n    outside: calendarOutsideVariants(),\n    hidden: calendarHiddenVariants(),\n    week_number: calendarWeekNumberVariants(),\n  }\n\n  const mergedClassNames: typeof defaultClassNames = Object.keys(defaultClassNames).reduce(\n    (acc, key) => ({\n      ...acc,\n      [key]: classNames?.[key as keyof typeof classNames]\n        ? cn(\n            defaultClassNames[key as keyof typeof defaultClassNames],\n            classNames[key as keyof typeof classNames]\n          )\n        : defaultClassNames[key as keyof typeof defaultClassNames],\n    }),\n    {} as typeof defaultClassNames\n  )\n\n  const rootProps = api.getRootProps()\n  const mergedRootProps = mergeProps(rootProps, props) as React.HTMLAttributes<HTMLDivElement>\n  const { className: rootClassName, ...rootRest } = mergedRootProps as {\n    className?: string\n  }\n\n  const ChevronComponent = userComponents?.Chevron\n  const CaptionLabelComponent = userComponents?.CaptionLabel\n  const MonthGridComponent = userComponents?.MonthGrid\n  const DayButtonComponent = userComponents?.DayButton\n  const WeekNumberComponent = userComponents?.WeekNumber\n  const DropdownNavComponent = userComponents?.DropdownNav\n  const MonthDropdownComponent = userComponents?.MonthsDropdown ?? userComponents?.Dropdown\n  const YearDropdownComponent = userComponents?.YearsDropdown ?? userComponents?.Dropdown\n\n  const renderChevron = (orientation: 'left' | 'right') => {\n    if (ChevronComponent) {\n      return <ChevronComponent orientation={orientation} />\n    }\n    if (orientation === 'left') {\n      return (\n        <svg\n          width={16}\n          height={16}\n          viewBox=\"0 0 24 24\"\n          fill=\"none\"\n          stroke=\"currentColor\"\n          strokeWidth=\"2\"\n          strokeLinecap=\"round\"\n          strokeLinejoin=\"round\"\n          aria-hidden=\"true\"\n        >\n          <path d=\"m15 18-6-6 6-6\" />\n        </svg>\n      )\n    }\n    return (\n      <svg\n        width={16}\n        height={16}\n        viewBox=\"0 0 24 24\"\n        fill=\"none\"\n        stroke=\"currentColor\"\n        strokeWidth=\"2\"\n        strokeLinecap=\"round\"\n        strokeLinejoin=\"round\"\n        aria-hidden=\"true\"\n      >\n        <path d=\"m9 18 6-6-6-6\" />\n      </svg>\n    )\n  }\n\n  const renderDropdown = (\n    dropdownProps: React.SelectHTMLAttributes<HTMLSelectElement>,\n    options: CalendarDropdownOption[],\n    customDropdown?: React.ComponentType<CalendarDropdownProps>\n  ) => {\n    if (customDropdown) {\n      const DropdownComponent = customDropdown\n      return (\n        <DropdownComponent\n          value={dropdownProps.value as string | number | undefined}\n          options={options}\n          onChange={dropdownProps.onChange as React.ChangeEventHandler<HTMLSelectElement> | undefined}\n        />\n      )\n    }\n    return (\n      <select {...dropdownProps} className={cn('h-8 rounded-md border px-2 text-sm', dropdownProps.className)}>\n        {options.map((option) => (\n          <option key={option.value} value={String(option.value)} disabled={option.disabled}>\n            {option.label}\n          </option>\n        ))}\n      </select>\n    )\n  }\n\n  const monthSelectProps = api.getMonthSelectProps()\n  const yearSelectProps = api.getYearSelectProps()\n  const monthOptions = api.getMonths({ format: 'long' }).map((item) => ({\n    value: item.value,\n    label: item.label,\n    disabled: item.disabled,\n  }))\n  const yearOptions = api.getYears().map((item) => ({\n    value: item.value,\n    label: item.label,\n    disabled: item.disabled,\n  }))\n\n  const showDropdownCaption = captionLayout === 'dropdown' || captionLayout === 'dropdown-years'\n  const currentMonthLabel = api.format(toDateValue(viewMonth), { month: 'long', year: 'numeric' })\n\n  const renderCaptionContent = () => {\n    if (showDropdownCaption) {\n      const monthControl =\n        captionLayout === 'dropdown' ? (\n          <span>\n            {renderDropdown(monthSelectProps, monthOptions, MonthDropdownComponent)}\n          </span>\n        ) : (\n          <span className={mergedClassNames.caption_label}>\n            {api.format(toDateValue(viewMonth), { month: 'long' })}\n          </span>\n        )\n\n      const yearControl = (\n        <span>{renderDropdown(yearSelectProps, yearOptions, YearDropdownComponent)}</span>\n      )\n\n      const controls = (\n        <>\n          {monthControl}\n          {yearControl}\n        </>\n      )\n\n      if (DropdownNavComponent) {\n        return <DropdownNavComponent>{controls}</DropdownNavComponent>\n      }\n      return <div className=\"flex items-center gap-2\">{controls}</div>\n    }\n\n    if (CaptionLabelComponent) {\n      return <CaptionLabelComponent className={mergedClassNames.caption_label}>{currentMonthLabel}</CaptionLabelComponent>\n    }\n\n    return <div className={mergedClassNames.caption_label}>{currentMonthLabel}</div>\n  }\n\n  const monthData = React.useMemo(() => {\n    const count = Math.max(1, numberOfMonths)\n    const start = api.visibleRange?.start\n    if (!start) return []\n\n    return Array.from({ length: count }, (_, index) => {\n      const monthStart = start.add({ months: index })\n      const id = `month-${index}`\n      const visibleRange = {\n        start: monthStart,\n        end: monthStart.add({ months: 1 }).subtract({ days: 1 }),\n      }\n\n      const weeks = api.getMonthWeeks(monthStart).map((week) => {\n        const weekNumber = getIsoWeekNumber(week[0].toDate(timeZone))\n        const days = week.map((dayValue) => {\n          const state = api.getDayTableCellState({ value: dayValue, visibleRange })\n          const cellProps = api.getDayTableCellProps({ value: dayValue, visibleRange })\n          const triggerProps = api.getDayTableCellTriggerProps({ value: dayValue, visibleRange })\n          const dayDate = dayValue.toDate(timeZone)\n          const rangeMiddle = state.inRange && !state.firstInRange && !state.lastInRange\n          const hidden = !showOutsideDays && state.outsideRange\n\n          return {\n            key: dayValue.toString(),\n            label: dayValue.day,\n            dayDate,\n            state,\n            cellProps,\n            triggerProps,\n            className: cn(\n              mergedClassNames.day,\n              state.outsideRange && mergedClassNames.outside,\n              hidden && mergedClassNames.hidden,\n              state.firstInRange && mergedClassNames.range_start,\n              state.lastInRange && mergedClassNames.range_end,\n              rangeMiddle && mergedClassNames.range_middle,\n              state.today && mergedClassNames.today\n            ),\n            modifiers: {\n              selected: state.selected,\n              disabled: !state.selectable || state.unavailable,\n              outside: state.outsideRange,\n              today: state.today,\n              range_start: state.firstInRange,\n              range_end: state.lastInRange,\n              range_middle: rangeMiddle,\n            },\n          }\n        })\n\n        return { key: `${id}-${week[0].toString()}`, weekNumber, days }\n      })\n\n      return {\n        id,\n        label: api.format(monthStart, { month: 'long', year: 'numeric' }),\n        tableProps: api.getTableProps({ view: 'day', id }),\n        tableHeadProps: api.getTableHeadProps({ view: 'day', id }),\n        tableBodyProps: api.getTableBodyProps({ view: 'day', id }),\n        tableRowProps: api.getTableRowProps({ view: 'day', id }),\n        tableHeaderProps: api.getTableHeaderProps({ view: 'day', id }),\n        weeks,\n      }\n    })\n  }, [api, numberOfMonths, mergedClassNames, showOutsideDays, timeZone])\n\n  const defaultComponents = {\n    DayButton: (buttonProps: CalendarDayButtonProps) => <button {...buttonProps} />,\n    WeekNumber: ({ week, ...weekProps }: CalendarWeekNumberProps) => <th {...weekProps}>{week.weekNumber}</th>,\n    MonthGrid: (tableProps: React.TableHTMLAttributes<HTMLTableElement>) => <table {...tableProps} />,\n    CaptionLabel: (captionProps: React.HTMLAttributes<HTMLElement>) => <div {...captionProps} />,\n  }\n\n  const mergedComponents = {\n    ...defaultComponents,\n    ...userComponents,\n  }\n\n  const prevTriggerProps = api.getPrevTriggerProps({ view: 'day' })\n  const nextTriggerProps = api.getNextTriggerProps({ view: 'day' })\n\n  return (\n    <div\n      {...(rootRest as React.HTMLAttributes<HTMLDivElement>)}\n      data-slot=\"calendar\"\n      className={cn(calendarRootVariants(), rootClassName, className)}\n    >\n      <div className={mergedClassNames.months}>\n        {monthData.map((monthItem, monthIndex) => {\n          const MonthGrid = mergedComponents.MonthGrid\n          const DayButton = mergedComponents.DayButton\n          const WeekNumber = mergedComponents.WeekNumber\n          const renderTable = (\n            <>\n              <thead {...monthItem.tableHeadProps}>\n                <tr {...monthItem.tableRowProps}>\n                  {showWeekNumber ? (\n                    <th className={mergedClassNames.week_number} aria-hidden=\"true\">\n                      #\n                    </th>\n                  ) : null}\n                  {api.weekDays.map((day) => (\n                    <th key={`${monthItem.id}-${day.short}`} {...monthItem.tableHeaderProps} className={mergedClassNames.weekday}>\n                      {day.short}\n                    </th>\n                  ))}\n                </tr>\n              </thead>\n              <tbody {...monthItem.tableBodyProps}>\n                {monthItem.weeks.map((week) => (\n                  <tr key={week.key} {...monthItem.tableRowProps}>\n                    {showWeekNumber ? (\n                      <WeekNumber className={mergedClassNames.week_number} week={{ weekNumber: week.weekNumber }} />\n                    ) : null}\n                    {week.days.map((dayCell) => {\n                      const triggerClassName = (dayCell.triggerProps as { className?: string }).className\n                      const buttonProps = {\n                        ...(dayCell.triggerProps as React.ButtonHTMLAttributes<HTMLButtonElement>),\n                        className: cn(mergedClassNames.day_button, triggerClassName),\n                      }\n\n                      return (\n                        <td\n                          key={dayCell.key}\n                          {...(dayCell.cellProps as React.TdHTMLAttributes<HTMLTableCellElement>)}\n                          className={cn(\n                            dayCell.className,\n                            (dayCell.cellProps as { className?: string }).className\n                          )}\n                        >\n                          <DayButton\n                            {...buttonProps}\n                            day={{ date: dayCell.dayDate }}\n                            modifiers={dayCell.modifiers}\n                          >\n                            {dayCell.label}\n                          </DayButton>\n                        </td>\n                      )\n                    })}\n                  </tr>\n                ))}\n              </tbody>\n            </>\n          )\n\n          return (\n            <div key={monthItem.id} className={mergedClassNames.month}>\n              <div className={mergedClassNames.month_caption}>\n                {monthIndex === 0 ? renderCaptionContent() : (\n                  <div className={mergedClassNames.caption_label}>{monthItem.label}</div>\n                )}\n                {monthIndex === 0 && !hideNavigation ? (\n                  <div className={mergedClassNames.nav}>\n                    <button\n                      {...(prevTriggerProps as React.ButtonHTMLAttributes<HTMLButtonElement>)}\n                      type=\"button\"\n                      className={cn(mergedClassNames.button_previous, prevTriggerProps.className)}\n                      disabled={!canGoPrev}\n                      onClick={(event) => {\n                        event.preventDefault()\n                        if (!canGoPrev) return\n                        setCalendarMonth(addMonths(viewMonth, -navStep))\n                      }}\n                    >\n                      {renderChevron('left')}\n                    </button>\n                    <button\n                      {...(nextTriggerProps as React.ButtonHTMLAttributes<HTMLButtonElement>)}\n                      type=\"button\"\n                      className={cn(mergedClassNames.button_next, nextTriggerProps.className)}\n                      disabled={!canGoNext}\n                      onClick={(event) => {\n                        event.preventDefault()\n                        if (!canGoNext) return\n                        setCalendarMonth(addMonths(viewMonth, navStep))\n                      }}\n                    >\n                      {renderChevron('right')}\n                    </button>\n                  </div>\n                ) : null}\n              </div>\n              <MonthGrid\n                {...(monthItem.tableProps as React.TableHTMLAttributes<HTMLTableElement>)}\n                className={cn(\n                  calendarGridVariants(),\n                  (monthItem.tableProps as { className?: string }).className\n                )}\n              >\n                {renderTable}\n              </MonthGrid>\n            </div>\n          )\n        })}\n      </div>\n    </div>\n  )\n}\n\nexport { Calendar }\nexport type {\n  CalendarClassNames,\n  CalendarComponents,\n  CalendarDayButtonProps,\n  CalendarDropdownProps,\n  CalendarMode,\n  CalendarProps,\n  CalendarRangeValue,\n  CalendarSelectedValue,\n  CalendarWeekNumberProps,\n  DisabledMatcher,\n} from './calendar/calendar-types'\n"
        },
        {
          "path": "registry/default/ui/calendar/calendar-types.ts",
          "target": "components/ui/calendar/calendar-types.ts",
          "type": "registry:ui",
          "content": "import type * as React from 'react'\n\nexport type CalendarMode = 'single' | 'range' | 'multiple'\nexport type CalendarRangeValue = { from: Date | undefined; to?: Date }\nexport type DisabledMatcher =\n  | Date\n  | {\n      before?: Date\n      after?: Date\n      from?: Date\n      to?: Date\n      dayOfWeek?: number[]\n    }\n  | ((date: Date) => boolean)\n\nexport type CalendarDropdownOption = {\n  value: string | number\n  label: string\n  disabled?: boolean\n}\n\nexport type CalendarDropdownProps = {\n  value?: string | number\n  options?: CalendarDropdownOption[]\n  onChange?: React.ChangeEventHandler<HTMLSelectElement>\n}\n\nexport type CalendarWeekNumberProps = React.ThHTMLAttributes<HTMLTableCellElement> & {\n  week: { weekNumber: number }\n}\n\nexport type CalendarDayButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {\n  day: { date: Date }\n  modifiers: Record<string, boolean>\n  children?: React.ReactNode\n}\n\nexport type CalendarComponents = {\n  Chevron?: React.ComponentType<{\n    className?: string\n    size?: number\n    disabled?: boolean\n    orientation?: 'left' | 'right' | 'up' | 'down'\n  }>\n  DayButton?: React.ComponentType<CalendarDayButtonProps>\n  WeekNumber?: React.ComponentType<CalendarWeekNumberProps>\n  CaptionLabel?: React.ComponentType<React.HTMLAttributes<HTMLElement>>\n  MonthGrid?: React.ComponentType<React.TableHTMLAttributes<HTMLTableElement>>\n  DropdownNav?: React.ComponentType<{ children?: React.ReactNode }>\n  Dropdown?: React.ComponentType<CalendarDropdownProps>\n  YearsDropdown?: React.ComponentType<CalendarDropdownProps>\n  MonthsDropdown?: React.ComponentType<CalendarDropdownProps>\n}\n\nexport type CalendarClassNames = Partial<\n  Record<\n    | 'months'\n    | 'month'\n    | 'month_caption'\n    | 'caption_label'\n    | 'nav'\n    | 'button_previous'\n    | 'button_next'\n    | 'weekday'\n    | 'day_button'\n    | 'day'\n    | 'range_start'\n    | 'range_end'\n    | 'range_middle'\n    | 'today'\n    | 'outside'\n    | 'hidden'\n    | 'week_number',\n    string\n  >\n>\n\nexport type CalendarSelectedValue = Date | Date[] | CalendarRangeValue | undefined\n\nexport interface CalendarProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onSelect'> {\n  mode?: CalendarMode\n  selected?: CalendarSelectedValue\n  onSelect?: (value: CalendarSelectedValue) => void\n  month?: Date\n  onMonthChange?: (month: Date) => void\n  defaultMonth?: Date\n  startMonth?: Date\n  endMonth?: Date\n  showOutsideDays?: boolean\n  numberOfMonths?: number\n  pagedNavigation?: boolean\n  captionLayout?: 'label' | 'dropdown' | 'dropdown-years'\n  hideNavigation?: boolean\n  fixedWeeks?: boolean\n  showWeekNumber?: boolean\n  disabled?: DisabledMatcher | DisabledMatcher[]\n  excludeDisabled?: boolean\n  classNames?: CalendarClassNames\n  components?: CalendarComponents\n}\n"
        },
        {
          "path": "registry/default/ui/calendar/calendar-utils.ts",
          "target": "components/ui/calendar/calendar-utils.ts",
          "type": "registry:ui",
          "content": "import { CalendarDate } from '@internationalized/date'\nimport type { DateValue } from '@internationalized/date'\n\nimport type { CalendarMode, CalendarSelectedValue, DisabledMatcher } from './calendar-types'\n\nconst toDateOnly = (date: Date) => new Date(date.getFullYear(), date.getMonth(), date.getDate())\n\nexport const toMonthStart = (date: Date) => new Date(date.getFullYear(), date.getMonth(), 1)\nexport const toMonthEnd = (date: Date) => new Date(date.getFullYear(), date.getMonth() + 1, 0)\nexport const addMonths = (date: Date, count: number) =>\n  new Date(date.getFullYear(), date.getMonth() + count, 1)\n\nexport const toDateValue = (date: Date) =>\n  new CalendarDate(date.getFullYear(), date.getMonth() + 1, date.getDate())\n\nexport const isRangeValue = (\n  value: CalendarSelectedValue\n): value is Exclude<CalendarSelectedValue, Date | Date[] | undefined> =>\n  Boolean(value) && typeof value === 'object' && !Array.isArray(value) && !(value instanceof Date)\n\nexport const dateFromSelected = (selected: CalendarSelectedValue, mode: CalendarMode) => {\n  if (!selected) return undefined\n  if (selected instanceof Date) return selected\n  if (Array.isArray(selected) && mode === 'multiple') return selected[0]\n  if (isRangeValue(selected)) return selected.from ?? selected.to\n  return undefined\n}\n\nexport const selectedToDateValues = (selected: CalendarSelectedValue, mode: CalendarMode) => {\n  if (!selected) return undefined\n  if (mode === 'single') {\n    if (selected instanceof Date) return [toDateValue(selected)]\n    if (isRangeValue(selected)) {\n      const fallback = selected.from ?? selected.to\n      return fallback ? [toDateValue(fallback)] : undefined\n    }\n    return undefined\n  }\n\n  if (mode === 'multiple') {\n    if (!Array.isArray(selected)) return undefined\n    const values = selected.map(toDateValue)\n    return values.length > 0 ? values : undefined\n  }\n\n  if (!isRangeValue(selected)) return undefined\n  const values: DateValue[] = []\n  if (selected.from) values.push(toDateValue(selected.from))\n  if (selected.to) values.push(toDateValue(selected.to))\n  return values.length > 0 ? values : undefined\n}\n\nexport const valuesToSelected = (values: DateValue[], mode: CalendarMode, timeZone: string) => {\n  if (mode === 'single') {\n    return values[0]?.toDate(timeZone)\n  }\n\n  if (mode === 'multiple') {\n    const dates = values.map((value) => value.toDate(timeZone))\n    return dates.length > 0 ? dates : undefined\n  }\n\n  const from = values[0]?.toDate(timeZone)\n  const to = values[1]?.toDate(timeZone)\n  return from || to ? { from, to } : undefined\n}\n\nexport const compareMonth = (a: Date, b: Date) =>\n  a.getFullYear() - b.getFullYear() || a.getMonth() - b.getMonth()\n\nexport const clampMonth = (date: Date, min?: Date, max?: Date) => {\n  if (min && compareMonth(date, min) < 0) return min\n  if (max && compareMonth(date, max) > 0) return max\n  return date\n}\n\nconst isSameDay = (a: Date, b: Date) =>\n  a.getFullYear() === b.getFullYear() &&\n  a.getMonth() === b.getMonth() &&\n  a.getDate() === b.getDate()\n\nconst isMatchObject = (\n  date: Date,\n  matcher: {\n    before?: Date\n    after?: Date\n    from?: Date\n    to?: Date\n    dayOfWeek?: number[]\n  }\n) => {\n  const current = toDateOnly(date).getTime()\n  const before = matcher.before ? toDateOnly(matcher.before).getTime() : undefined\n  const after = matcher.after ? toDateOnly(matcher.after).getTime() : undefined\n  const from = matcher.from ? toDateOnly(matcher.from).getTime() : undefined\n  const to = matcher.to ? toDateOnly(matcher.to).getTime() : undefined\n  const weekdayMatched = Array.isArray(matcher.dayOfWeek) && matcher.dayOfWeek.includes(date.getDay())\n\n  if (from !== undefined || to !== undefined) {\n    const min = from ?? Number.NEGATIVE_INFINITY\n    const max = to ?? Number.POSITIVE_INFINITY\n    if (current >= min && current <= max) return true\n  }\n\n  if (before !== undefined && current < before) return true\n  if (after !== undefined && current > after) return true\n  if (weekdayMatched) return true\n  return false\n}\n\nexport const matchDisabled = (date: Date, matcher: DisabledMatcher) => {\n  if (matcher instanceof Date) return isSameDay(date, matcher)\n  if (typeof matcher === 'function') return matcher(date)\n  return isMatchObject(date, matcher)\n}\n\nexport const hasUnavailableBetween = (\n  from: Date,\n  to: Date,\n  isUnavailable: (date: Date) => boolean\n) => {\n  const start = toDateOnly(from)\n  const end = toDateOnly(to)\n  const min = start.getTime() <= end.getTime() ? start : end\n  const max = start.getTime() <= end.getTime() ? end : start\n  for (let cursor = new Date(min); cursor.getTime() <= max.getTime(); cursor.setDate(cursor.getDate() + 1)) {\n    if (isUnavailable(cursor)) return true\n  }\n  return false\n}\n\nexport const getIsoWeekNumber = (date: Date) => {\n  const target = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()))\n  const day = target.getUTCDay() || 7\n  target.setUTCDate(target.getUTCDate() + 4 - day)\n  const yearStart = new Date(Date.UTC(target.getUTCFullYear(), 0, 1))\n  return Math.ceil((((target.getTime() - yearStart.getTime()) / 86400000) + 1) / 7)\n}\n"
        },
        {
          "path": "registry/default/vue/calendar/calendar-rac.vue",
          "target": "components/ui/calendar/calendar-rac.vue",
          "type": "registry:component",
          "content": "<script lang=\"ts\">\nimport { defineComponent, h, type PropType } from 'vue'\nimport Calendar from './calendar.vue'\n\ntype CalendarModelValue = Date | Date[] | { from?: Date; to?: Date } | undefined\n\nexport const CalendarRAC = defineComponent({\n  name: 'CalendarRAC',\n  inheritAttrs: false,\n  props: {\n    modelValue: {\n      type: [Date, Object, Array] as PropType<Date | Date[] | Record<string, never>>,\n      default: undefined,\n    },\n    class: {\n      type: String,\n      default: undefined,\n    },\n  },\n  emits: ['update:modelValue', 'change'],\n  setup(props, { attrs, emit }) {\n    return () =>\n      h(Calendar, {\n        ...attrs,\n        class: props.class,\n        mode: 'single',\n        modelValue: props.modelValue,\n        'onUpdate:modelValue': (value: CalendarModelValue) => emit('update:modelValue', value),\n        onChange: (value: CalendarModelValue) => emit('change', value),\n      })\n  },\n})\n\nexport const RangeCalendar = defineComponent({\n  name: 'RangeCalendar',\n  inheritAttrs: false,\n  props: {\n    modelValue: {\n      type: Object as PropType<{ from?: Date; to?: Date }>,\n      default: undefined,\n    },\n    class: {\n      type: String,\n      default: undefined,\n    },\n  },\n  emits: ['update:modelValue', 'change'],\n  setup(props, { attrs, emit }) {\n    return () =>\n      h(Calendar, {\n        ...attrs,\n        class: props.class,\n        mode: 'range',\n        modelValue: props.modelValue,\n        'onUpdate:modelValue': (value: CalendarModelValue) =>\n          emit('update:modelValue', value),\n        onChange: (value: CalendarModelValue) => emit('change', value),\n      })\n  },\n})\n\nexport default CalendarRAC\n</script>\n"
        },
        {
          "path": "registry/default/vue/calendar/calendar.vue",
          "target": "components/ui/calendar/calendar.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport type {\n  AssertNoExtraKeys,\n  CalendarApi,\n  CalendarVueValue,\n  CalendarVueProps,\n} from \"@timui/core\";\nimport {\n  calendarCaptionLabelVariants,\n  calendarDayButtonVariants,\n  calendarDayVariants,\n  calendarGridVariants,\n  calendarHiddenVariants,\n  calendarMonthCaptionVariants,\n  calendarMonthVariants,\n  calendarMonthsVariants,\n  calendarNavButtonVariants,\n  calendarNavVariants,\n  calendarOutsideVariants,\n  calendarRangeEndVariants,\n  calendarRangeMiddleVariants,\n  calendarRangeStartVariants,\n  calendarRootVariants,\n  calendarTodayVariants,\n  calendarWeekNumberVariants,\n  calendarWeekdayVariants,\n  cn,\n  buttonVariants,\n} from \"@timui/core\";\nimport type { VisibleRange } from \"@zag-js/date-picker\";\nimport { useCalendar } from \"./use-calendar\";\n\ntype CalendarProps = CalendarVueProps & {\n  id?: string;\n  selected?: CalendarVueValue;\n  onSelect?: (value?: CalendarVueValue) => void;\n  class?: string;\n  classNames?: Partial<Record<string, string>>;\n  externalApi?: CalendarApi;\n};\n\ntype _CalendarPropsGuard = AssertNoExtraKeys<\n  CalendarProps,\n  CalendarVueProps & {\n    id?: string;\n    selected?: CalendarVueValue;\n    onSelect?: (value?: CalendarVueValue) => void;\n    class?: string;\n    classNames?: Partial<Record<string, string>>;\n    externalApi?: CalendarApi;\n  }\n>;\n\nconst props = withDefaults(defineProps<CalendarProps>(), {\n  mode: \"single\",\n  showOutsideDays: true,\n  numberOfMonths: 1,\n});\n\nconst emit = defineEmits<{\n  (e: \"update:modelValue\", value?: Date | Date[] | { from?: Date; to?: Date }): void;\n  (e: \"change\", value?: Date | Date[] | { from?: Date; to?: Date }): void;\n}>();\n\nconst { api: internalApi, localTimeZone } = useCalendar(props, emit);\nconst api = computed(() => props.externalApi ?? internalApi.value);\n\nconst defaultClassNames = {\n  months: calendarMonthsVariants(),\n  month: calendarMonthVariants(),\n  month_caption: calendarMonthCaptionVariants(),\n  caption_label: calendarCaptionLabelVariants(),\n  nav: calendarNavVariants(),\n  button_previous: cn(buttonVariants({ variant: \"ghost\" }), calendarNavButtonVariants()),\n  button_next: cn(buttonVariants({ variant: \"ghost\" }), calendarNavButtonVariants()),\n  weekday: calendarWeekdayVariants(),\n  day_button: calendarDayButtonVariants(),\n  day: calendarDayVariants(),\n  range_start: calendarRangeStartVariants(),\n  range_end: calendarRangeEndVariants(),\n  range_middle: calendarRangeMiddleVariants(),\n  today: calendarTodayVariants(),\n  outside: calendarOutsideVariants(),\n  hidden: calendarHiddenVariants(),\n  week_number: calendarWeekNumberVariants(),\n};\n\nconst mergedClassNames = computed(() => {\n  const merged: Record<string, string> = {};\n  Object.keys(defaultClassNames).forEach((key) => {\n    merged[key] = props.classNames?.[key]\n      ? cn(defaultClassNames[key as keyof typeof defaultClassNames], props.classNames[key])\n      : defaultClassNames[key as keyof typeof defaultClassNames];\n  });\n  return merged;\n});\n\nconst weekDays = computed(() => api.value?.weekDays ?? []);\n\nconst monthSelectProps = computed(() => api.value?.getMonthSelectProps?.() ?? {});\nconst yearSelectProps = computed(() => api.value?.getYearSelectProps?.() ?? {});\nconst monthOptions = computed(() =>\n  api.value?.getMonths?.({ format: \"long\" }).map((item) => ({\n    value: item.value,\n    label: item.label,\n    disabled: item.disabled,\n  })) ?? []\n);\nconst yearOptions = computed(() =>\n  api.value?.getYears?.().map((item) => ({\n    value: item.value,\n    label: item.label,\n    disabled: item.disabled,\n  })) ?? []\n);\nconst showDropdownCaption = computed(\n  () => props.captionLayout === \"dropdown\" || props.captionLayout === \"dropdown-years\"\n);\n\nconst getIsoWeekNumber = (date: Date) => {\n  const target = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));\n  const day = target.getUTCDay() || 7;\n  target.setUTCDate(target.getUTCDate() + 4 - day);\n  const yearStart = new Date(Date.UTC(target.getUTCFullYear(), 0, 1));\n  return Math.ceil(((target.getTime() - yearStart.getTime()) / 86400000 + 1) / 7);\n};\n\nconst monthData = computed(() => {\n  const instance = api.value;\n  if (!instance) return [];\n\n  const count = Math.max(1, props.numberOfMonths ?? 1);\n  const start = instance.visibleRange?.start;\n  if (!start) return [];\n\n  return Array.from({ length: count }, (_, index) => {\n    const monthStart = start.add({ months: index });\n    const id = `month-${index}`;\n    const visibleRange: VisibleRange = {\n      start: monthStart,\n      end: monthStart.add({ months: 1 }).subtract({ days: 1 }),\n    };\n    const weeks = instance.getMonthWeeks(monthStart).map((week, weekIndex) => {\n      const weekNumber = getIsoWeekNumber(week[0].toDate(localTimeZone));\n      const days = week.map((day, dayIndex) => {\n        const state = instance.getDayTableCellState?.({\n          value: day,\n          visibleRange,\n        }) ?? {};\n        const cellProps = instance.getDayTableCellProps?.({ value: day, visibleRange }) ?? {};\n        const triggerProps =\n          instance.getDayTableCellTriggerProps?.({ value: day, visibleRange }) ?? {};\n\n        return {\n          key: `${id}-${weekIndex}-${dayIndex}-${day.toString()}`,\n          label: day.day,\n          cellProps,\n          triggerProps,\n          state,\n          className: cn(\n            mergedClassNames.value.day,\n            state.outsideRange && mergedClassNames.value.outside,\n            !props.showOutsideDays && state.outsideRange && mergedClassNames.value.hidden,\n            state.firstInRange && mergedClassNames.value.range_start,\n            state.lastInRange && mergedClassNames.value.range_end,\n            state.inRange &&\n              !state.firstInRange &&\n              !state.lastInRange &&\n              mergedClassNames.value.range_middle,\n            state.today && mergedClassNames.value.today\n          ),\n        };\n      });\n\n      return {\n        key: `${id}-${weekIndex}`,\n        weekNumber,\n        days,\n      };\n    });\n\n    return {\n      id,\n      weeks,\n      label: instance.format(monthStart, { month: \"long\", year: \"numeric\" }),\n      tableProps: instance.getTableProps?.({ view: \"day\", id }) ?? {},\n      tableHeadProps: instance.getTableHeadProps?.({ view: \"day\", id }) ?? {},\n      tableBodyProps: instance.getTableBodyProps?.({ view: \"day\", id }) ?? {},\n      tableRowProps: instance.getTableRowProps?.({ view: \"day\", id }) ?? {},\n      tableHeaderProps: instance.getTableHeaderProps?.({ view: \"day\", id }) ?? {},\n    };\n  });\n});\n\nconst rootProps = computed(() => api.value?.getRootProps?.() ?? {});\nconst prevTriggerProps = computed(() => api.value?.getPrevTriggerProps?.({ view: \"day\" }) ?? {});\nconst nextTriggerProps = computed(() => api.value?.getNextTriggerProps?.({ view: \"day\" }) ?? {});\n\nconst getTriggerClass = (triggerProps: object) => {\n  if (!triggerProps || typeof triggerProps !== \"object\") return \"\";\n  const className = (triggerProps as { class?: object }).class;\n  return typeof className === \"string\" ? className : \"\";\n};\n</script>\n\n<template>\n  <div\n    v-bind=\"rootProps\"\n    data-slot=\"calendar\"\n    :class=\"cn(calendarRootVariants(), rootProps.class, props.class)\"\n  >\n    <div :class=\"mergedClassNames.months\">\n      <div\n        v-for=\"(month, index) in monthData\"\n        :key=\"month.id\"\n        :class=\"mergedClassNames.month\"\n      >\n        <div :class=\"mergedClassNames.month_caption\">\n          <div :class=\"mergedClassNames.caption_label\">\n            <template v-if=\"index === 0 && showDropdownCaption\">\n              <div class=\"flex items-center gap-2\">\n                <select\n                  v-if=\"props.captionLayout === 'dropdown'\"\n                  v-bind=\"monthSelectProps\"\n                  :class=\"cn('h-8 rounded-md border px-2 text-sm', monthSelectProps.class)\"\n                >\n                  <option\n                    v-for=\"option in monthOptions\"\n                    :key=\"option.value\"\n                    :value=\"String(option.value)\"\n                    :disabled=\"option.disabled\"\n                  >\n                    {{ option.label }}\n                  </option>\n                </select>\n                <span v-else>{{ month.label.replace(/\\s+\\d{4}$/, '') }}</span>\n                <select\n                  v-bind=\"yearSelectProps\"\n                  :class=\"cn('h-8 rounded-md border px-2 text-sm', yearSelectProps.class)\"\n                >\n                  <option\n                    v-for=\"option in yearOptions\"\n                    :key=\"option.value\"\n                    :value=\"String(option.value)\"\n                    :disabled=\"option.disabled\"\n                  >\n                    {{ option.label }}\n                  </option>\n                </select>\n              </div>\n            </template>\n            <template v-else>\n              {{ month.label }}\n            </template>\n          </div>\n          <div v-if=\"index === 0 && !props.hideNavigation\" :class=\"mergedClassNames.nav\">\n            <button\n              v-bind=\"prevTriggerProps\"\n              type=\"button\"\n              :class=\"cn(mergedClassNames.button_previous, prevTriggerProps.class)\"\n            >\n              <svg\n                width=\"16\"\n                height=\"16\"\n                viewBox=\"0 0 24 24\"\n                fill=\"none\"\n                stroke=\"currentColor\"\n                stroke-width=\"2\"\n                stroke-linecap=\"round\"\n                stroke-linejoin=\"round\"\n                aria-hidden=\"true\"\n              >\n                <path d=\"m15 18-6-6 6-6\" />\n              </svg>\n            </button>\n            <button\n              v-bind=\"nextTriggerProps\"\n              type=\"button\"\n              :class=\"cn(mergedClassNames.button_next, nextTriggerProps.class)\"\n            >\n              <svg\n                width=\"16\"\n                height=\"16\"\n                viewBox=\"0 0 24 24\"\n                fill=\"none\"\n                stroke=\"currentColor\"\n                stroke-width=\"2\"\n                stroke-linecap=\"round\"\n                stroke-linejoin=\"round\"\n                aria-hidden=\"true\"\n              >\n                <path d=\"m9 18 6-6-6-6\" />\n              </svg>\n            </button>\n          </div>\n        </div>\n        <table v-bind=\"month.tableProps\" :class=\"calendarGridVariants()\">\n          <thead v-bind=\"month.tableHeadProps\">\n            <tr v-bind=\"month.tableRowProps\">\n              <th v-if=\"props.showWeekNumber\" :class=\"mergedClassNames.week_number\" aria-hidden=\"true\">\n                #\n              </th>\n              <th\n                v-for=\"day in weekDays\"\n                :key=\"day.short\"\n                v-bind=\"month.tableHeaderProps\"\n                :class=\"mergedClassNames.weekday\"\n              >\n                {{ day.short }}\n              </th>\n            </tr>\n          </thead>\n          <tbody v-bind=\"month.tableBodyProps\">\n            <tr v-for=\"week in month.weeks\" :key=\"week.key\" v-bind=\"month.tableRowProps\">\n              <th v-if=\"props.showWeekNumber\" :class=\"mergedClassNames.week_number\">\n                {{ week.weekNumber }}\n              </th>\n              <td\n                v-for=\"dayCell in week.days\"\n                :key=\"dayCell.key\"\n                v-bind=\"dayCell.cellProps\"\n                :data-selected=\"\n                  dayCell.state.selected || dayCell.state.inRange || undefined\n                \"\n                :data-disabled=\"\n                  !dayCell.state.selectable || undefined\n                \"\n                :data-outside=\"\n                  dayCell.state.outsideRange || undefined\n                \"\n                :class=\"dayCell.className\"\n              >\n                <button\n                  v-bind=\"dayCell.triggerProps\"\n                  type=\"button\"\n                  :class=\"cn(mergedClassNames.day_button, getTriggerClass(dayCell.triggerProps))\"\n                >\n                  {{ dayCell.label }}\n                </button>\n              </td>\n            </tr>\n          </tbody>\n        </table>\n      </div>\n    </div>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/calendar/use-calendar.ts",
          "target": "components/ui/calendar/use-calendar.ts",
          "type": "registry:component",
          "content": "import { getLocalTimeZone } from '@internationalized/date'\nimport { calendarConnect, calendarMachine } from '@timui/core'\nimport type {\n  CalendarDisabledMatcher,\n  CalendarMode,\n  CalendarRangeValue,\n  CalendarVueProps,\n  CalendarVueValue,\n} from '@timui/core'\nimport { parse as parseDateValue } from '@zag-js/date-picker'\nimport type { DateValue } from '@zag-js/date-picker'\nimport { normalizeProps, useMachine } from '@zag-js/vue'\nimport { computed, useId } from 'vue'\n\nexport type UseCalendarProps = CalendarVueProps & {\n  id?: string\n  selected?: CalendarVueValue\n  onSelect?: (value: CalendarModelValue) => void\n}\n\ntype CalendarModelValue =\n  | Date\n  | Date[]\n  | {\n      from?: Date\n      to?: Date\n    }\n  | undefined\n\nexport type UseCalendarEmits = {\n  (e: 'update:modelValue', value: CalendarModelValue): void\n  (e: 'change', value: CalendarModelValue): void\n}\n\nconst toDateOnly = (date: Date) => new Date(date.getFullYear(), date.getMonth(), date.getDate())\nconst toMonthStart = (date: Date) => new Date(date.getFullYear(), date.getMonth(), 1)\nconst toMonthEnd = (date: Date) => new Date(date.getFullYear(), date.getMonth() + 1, 0)\nconst addMonths = (date: Date, count: number) => new Date(date.getFullYear(), date.getMonth() + count, 1)\n\nconst compareMonth = (a: Date, b: Date) => a.getFullYear() - b.getFullYear() || a.getMonth() - b.getMonth()\n\nconst clampMonth = (date: Date, min?: Date, max?: Date) => {\n  if (min && compareMonth(date, min) < 0) return min\n  if (max && compareMonth(date, max) > 0) return max\n  return date\n}\n\nconst isSameDay = (a: Date, b: Date) =>\n  a.getFullYear() === b.getFullYear() &&\n  a.getMonth() === b.getMonth() &&\n  a.getDate() === b.getDate()\n\nconst isMatchObject = (\n  date: Date,\n  matcher: {\n    before?: Date\n    after?: Date\n    from?: Date\n    to?: Date\n    dayOfWeek?: number[]\n  }\n) => {\n  const current = toDateOnly(date).getTime()\n  const before = matcher.before ? toDateOnly(matcher.before).getTime() : undefined\n  const after = matcher.after ? toDateOnly(matcher.after).getTime() : undefined\n  const from = matcher.from ? toDateOnly(matcher.from).getTime() : undefined\n  const to = matcher.to ? toDateOnly(matcher.to).getTime() : undefined\n  const weekdayMatched = Array.isArray(matcher.dayOfWeek) && matcher.dayOfWeek.includes(date.getDay())\n\n  if (from !== undefined || to !== undefined) {\n    const min = from ?? Number.NEGATIVE_INFINITY\n    const max = to ?? Number.POSITIVE_INFINITY\n    if (current >= min && current <= max) return true\n  }\n\n  if (before !== undefined && current < before) return true\n  if (after !== undefined && current > after) return true\n  if (weekdayMatched) return true\n  return false\n}\n\nconst matchDisabled = (date: Date, matcher: CalendarDisabledMatcher) => {\n  if (matcher instanceof Date) return isSameDay(date, matcher)\n  if (typeof matcher === 'function') return matcher(date)\n  return isMatchObject(date, matcher)\n}\n\nconst isRangeValue = (value: CalendarModelValue): value is Exclude<CalendarRangeValue, undefined> =>\n  Boolean(value) && typeof value === 'object' && !Array.isArray(value) && !(value instanceof Date)\n\nexport function useCalendar(props: UseCalendarProps, emit: UseCalendarEmits) {\n  const localTimeZone = getLocalTimeZone()\n  const generatedId = useId()\n  const toCalendarDate = (input: string | Date) =>\n    parseDateValue(\n      input instanceof Date\n        ? `${input.getFullYear()}-${String(input.getMonth() + 1).padStart(2, '0')}-${String(\n            input.getDate()\n          ).padStart(2, '0')}`\n        : input\n    )\n\n  const dateFromSelected = (value: CalendarVueValue | undefined, mode: CalendarMode) => {\n    if (!value) return undefined\n    if (value instanceof Date) return value\n    if (Array.isArray(value) && mode === 'multiple') return value[0]\n    const range = value as CalendarRangeValue\n    return range?.from ?? range?.to\n  }\n\n  const toDateValueArray = (value: CalendarVueValue | undefined, mode: CalendarMode) => {\n    if (!value) return undefined\n    if (mode === 'range') {\n      if (value instanceof Date) return [toCalendarDate(value)]\n      if (Array.isArray(value)) {\n        const values = value.slice(0, 2).map((item) => toCalendarDate(item))\n        return values.length ? values : undefined\n      }\n      const range = value as CalendarRangeValue\n      const parsed: DateValue[] = []\n      if (range?.from) parsed.push(toCalendarDate(range.from))\n      if (range?.to) parsed.push(toCalendarDate(range.to))\n      return parsed.length ? parsed : undefined\n    }\n\n    if (mode === 'multiple') {\n      if (Array.isArray(value)) {\n        const values = value.map((item) => toCalendarDate(item))\n        return values.length ? values : undefined\n      }\n      if (value instanceof Date) return [toCalendarDate(value)]\n      const range = value as CalendarRangeValue\n      const fallback = range?.from ?? range?.to\n      return fallback ? [toCalendarDate(fallback)] : undefined\n    }\n\n    if (value instanceof Date) return [toCalendarDate(value)]\n    if (Array.isArray(value)) return value[0] ? [toCalendarDate(value[0])] : undefined\n    const range = value as CalendarRangeValue\n    const fallback = range?.from ?? range?.to\n    return fallback ? [toCalendarDate(fallback)] : undefined\n  }\n\n  const toModelValue = (values: DateValue[], mode: CalendarMode) => {\n    if (mode === 'multiple') {\n      const dates = values.map((value) => value.toDate(localTimeZone))\n      return dates.length ? dates : undefined\n    }\n    if (mode === 'range') {\n      const from = values[0]?.toDate(localTimeZone)\n      const to = values[1]?.toDate(localTimeZone)\n      return from || to ? { from, to } : undefined\n    }\n    return values[0]?.toDate(localTimeZone)\n  }\n\n  const disabledMatchers = computed(() => {\n    const matcher = props.disabled\n    if (matcher === undefined || typeof matcher === 'boolean') return []\n    return Array.isArray(matcher) ? matcher : [matcher]\n  })\n\n  const matchesUnavailable = (date: Date) =>\n    disabledMatchers.value.some((matcher) => matchDisabled(date, matcher)) ||\n    !!props.isDateUnavailable?.(date)\n\n  const hasUnavailableBetween = (from: Date, to: Date) => {\n    const start = toDateOnly(from)\n    const end = toDateOnly(to)\n    const min = start.getTime() <= end.getTime() ? start : end\n    const max = start.getTime() <= end.getTime() ? end : start\n    for (let cursor = new Date(min); cursor.getTime() <= max.getTime(); cursor.setDate(cursor.getDate() + 1)) {\n      if (matchesUnavailable(cursor)) return true\n    }\n    return false\n  }\n\n  const normalizeExcludedRange = (value: CalendarModelValue, mode: CalendarMode) => {\n    if (!props.excludeDisabled || mode !== 'range' || !isRangeValue(value) || !value.from || !value.to) {\n      return value\n    }\n    if (!hasUnavailableBetween(value.from, value.to)) return value\n    return { from: value.to, to: undefined }\n  }\n\n  const machineProps = computed(() => {\n    const mode = props.mode || 'single'\n    const externalValue = props.modelValue !== undefined ? props.modelValue : props.selected\n    const controlledValue =\n      externalValue !== undefined ? toDateValueArray(externalValue, mode) : undefined\n\n    const defaultValue =\n      externalValue === undefined\n        ? toDateValueArray(props.defaultValue, mode)\n        : undefined\n\n    const numOfMonths = props.numberOfMonths || 1\n    const minMonth = props.startMonth\n      ? toMonthStart(props.startMonth)\n      : props.minDate\n        ? toMonthStart(props.minDate)\n        : undefined\n    const maxMonthBase = props.endMonth\n      ? toMonthStart(props.endMonth)\n      : props.maxDate\n        ? toMonthStart(props.maxDate)\n        : undefined\n    const maxMonth = maxMonthBase ? addMonths(maxMonthBase, -(numOfMonths - 1)) : undefined\n\n    const focusedBase = props.month\n      ? clampMonth(toMonthStart(props.month), minMonth, maxMonth)\n      : undefined\n    const defaultFocusedBase =\n      props.month === undefined\n        ? clampMonth(\n            toMonthStart(\n              props.defaultMonth ??\n                dateFromSelected(externalValue, mode) ??\n                new Date()\n            ),\n            minMonth,\n            maxMonth\n          )\n        : undefined\n\n    const minDate = props.minDate ?? (props.startMonth ? toMonthStart(props.startMonth) : undefined)\n    const maxDate = props.maxDate ?? (props.endMonth ? toMonthEnd(props.endMonth) : undefined)\n\n    return {\n      id: props.id ?? generatedId,\n      inline: true,\n      selectionMode: mode,\n      numOfMonths,\n      outsideDaySelectable: props.showOutsideDays ?? true,\n      fixedWeeks: props.fixedWeeks,\n      min: minDate ? toCalendarDate(minDate) : undefined,\n      max: maxDate ? toCalendarDate(maxDate) : undefined,\n      focusedValue: focusedBase ? toCalendarDate(focusedBase) : undefined,\n      defaultFocusedValue: defaultFocusedBase ? toCalendarDate(defaultFocusedBase) : undefined,\n      disabled: typeof props.disabled === 'boolean' ? props.disabled : undefined,\n      timeZone: localTimeZone,\n      value: controlledValue,\n      defaultValue,\n      isDateUnavailable: (date: DateValue) => matchesUnavailable(date.toDate(localTimeZone)),\n      onValueChange(details: { value: DateValue[] }) {\n        const rawNext = toModelValue(details.value, mode)\n        const next = normalizeExcludedRange(rawNext, mode)\n        props.onSelect?.(next)\n        emit('update:modelValue', next)\n        emit('change', next)\n      },\n      onVisibleRangeChange(details: { visibleRange: { start: DateValue } }) {\n        props.onMonthChange?.(toMonthStart(details.visibleRange.start.toDate(localTimeZone)))\n      },\n    }\n  })\n\n  const service = useMachine(calendarMachine, machineProps)\n  const api = computed(() => calendarConnect(service, normalizeProps))\n\n  return {\n    api,\n    localTimeZone,\n  }\n}\n"
        },
        {
          "path": "registry/default/html/calendar.html",
          "target": "components/ui/calendar.html",
          "type": "registry:component",
          "content": "<div data-slot=\"calendar\" class=\"w-full border-collapse space-y-1\">\n  <div class=\"relative flex size-9 items-center justify-center whitespace-nowrap rounded-md p-0 text-foreground group-[[data-selected]:not(.range-middle)]:[transition-property:color,background-color,border-radius,box-shadow] group-[[data-selected]:not(.range-middle)]:duration-150 group-data-disabled:pointer-events-none focus-visible:z-10 hover:not-in-data-selected:bg-accent group-data-selected:bg-primary hover:not-in-data-selected:text-foreground group-data-selected:text-primary-foreground group-data-disabled:text-foreground/30 group-data-disabled:line-through group-data-outside:text-foreground/30 group-data-selected:group-data-outside:text-primary-foreground outline-none focus-visible:ring-ring/50 focus-visible:ring-[3px] group-[.range-start:not(.range-end)]:rounded-e-none group-[.range-end:not(.range-start)]:rounded-s-none group-[.range-middle]:rounded-none group-[.range-middle]:group-data-selected:bg-accent group-[.range-middle]:group-data-selected:text-foreground\">\n    <button type=\"button\" class=\"rounded-sm px-2 py-1 hover:bg-accent\">&lt;</button>\n    <div class=\"text-sm font-medium\">March 2026</div>\n    <button type=\"button\" class=\"rounded-sm px-2 py-1 hover:bg-accent\">&gt;</button>\n  </div>\n  <div class=\"grid grid-cols-7 gap-1 text-center text-xs text-muted-foreground\">\n    <span>Su</span><span>Mo</span><span>Tu</span><span>We</span><span>Th</span><span>Fr</span><span>Sa</span>\n  </div>\n  <div class=\"mt-2 grid grid-cols-7 gap-1 text-center text-sm\">\n    <button class=\"h-8 rounded-sm hover:bg-accent\">1</button>\n    <button class=\"h-8 rounded-sm hover:bg-accent\">2</button>\n    <button class=\"h-8 rounded-sm bg-primary text-primary-foreground\">3</button>\n  </div>\n</div>"
        },
        {
          "path": "registry/default/weapp/calendar.wxml",
          "target": "components/ui/calendar.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\" data-slot=\"calendar\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/calendar.wxss",
          "target": "components/ui/calendar.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/calendar.ts",
          "target": "components/ui/calendar.ts",
          "type": "registry:component",
          "content": "import { cn } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass) {\n      this.setData({\n        className: cn('w-fit', extClass),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/calendar.json",
          "target": "components/ui/calendar.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        }
      ],
      "optionalPeerDependencies": [
        "@internationalized/date"
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@zag-js/react"
            ],
            "optionalPeerDependencies": [
              "@internationalized/date"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@zag-js/date-picker",
              "@zag-js/vue"
            ],
            "optionalPeerDependencies": [
              "@internationalized/date"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "date-picker",
      "type": "registry:ui",
      "dependencies": [
        "@timui/core",
        "@zag-js/popper",
        "@zag-js/react"
      ],
      "registryDependencies": [
        "calendar",
        "popover",
        "button"
      ],
      "files": [
        {
          "path": "registry/default/ui/date-picker.tsx",
          "type": "registry:ui",
          "target": "components/ui/date-picker.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport { CalendarDate, getLocalTimeZone } from '@internationalized/date'\nimport type { DateValue } from '@internationalized/date'\nimport {\n  cn,\n  datePickerConnect,\n  datePickerContentVariants,\n  datePickerMachine,\n  datePickerRootVariants,\n  datePickerTriggerButtonVariants,\n  datePickerTriggerIconVariants,\n  datePickerTriggerLabelEmptyVariants,\n  datePickerTriggerLabelVariants,\n  datePickerTriggerVariants,\n} from '@timui/core'\nimport type { Placement } from '@zag-js/popper'\nimport { normalizeProps, Portal, useMachine } from '@zag-js/react'\n\nimport { Button } from './button'\nimport { Calendar } from './calendar'\nimport type { CalendarProps, CalendarRangeValue, CalendarSelectedValue } from './calendar'\n\ntype DatePickerMode = 'single' | 'range'\n\ntype DatePickerValue = Date | CalendarRangeValue | undefined\n\ninterface DatePickerProps {\n  id?: string\n  mode?: DatePickerMode\n  value?: DatePickerValue\n  defaultValue?: DatePickerValue\n  onValueChange?: (value: DatePickerValue) => void\n  open?: boolean\n  defaultOpen?: boolean\n  onOpenChange?: (open: boolean) => void\n  disabled?: boolean\n  required?: boolean\n  name?: string\n  locale?: string\n  placeholder?: string\n  className?: string\n  triggerClassName?: string\n  contentClassName?: string\n  calendarProps?: Omit<CalendarProps, 'mode' | 'selected' | 'onSelect'>\n}\n\nconst toPickerDate = (input: Date) =>\n  new CalendarDate(input.getFullYear(), input.getMonth() + 1, input.getDate())\n\nconst toDateValueArray = (value: DatePickerValue, mode: DatePickerMode) => {\n  if (!value) return undefined\n  if (value instanceof Date) return [toPickerDate(value)]\n\n  if (mode === 'range') {\n    if (!value.from) return undefined\n    const parsed: DateValue[] = []\n    parsed.push(toPickerDate(value.from))\n    if (value.to) parsed.push(toPickerDate(value.to))\n    return parsed.length > 0 ? parsed : undefined\n  }\n\n  const fallback = value.from ?? value.to\n  return fallback ? [toPickerDate(fallback)] : undefined\n}\n\nconst toModelValue = (values: DateValue[], mode: DatePickerMode, timeZone: string): DatePickerValue => {\n  if (mode === 'range') {\n    const from = values[0]?.toDate(timeZone)\n    const to = values[1]?.toDate(timeZone)\n    return from || to ? { from, to } : undefined\n  }\n\n  return values[0]?.toDate(timeZone)\n}\n\nconst toCalendarSelected = (values: Date[], mode: DatePickerMode): CalendarSelectedValue => {\n  if (mode === 'range') {\n    return {\n      from: values[0],\n      to: values[1],\n    }\n  }\n\n  return values[0]\n}\n\nfunction DatePicker({\n  id,\n  mode = 'single',\n  value,\n  defaultValue,\n  onValueChange,\n  open,\n  defaultOpen,\n  onOpenChange,\n  disabled,\n  required,\n  name,\n  locale,\n  placeholder = 'Date',\n  className,\n  triggerClassName,\n  contentClassName,\n  calendarProps,\n}: DatePickerProps) {\n  const generatedId = React.useId()\n  const datePickerId = id ?? generatedId\n  const timeZone = getLocalTimeZone()\n  const formatter = React.useMemo(\n    () =>\n      new Intl.DateTimeFormat(locale, {\n        month: 'short',\n        day: '2-digit',\n        year: 'numeric',\n      }),\n    [locale]\n  )\n\n  const controlledValue = React.useMemo(\n    () => (value !== undefined ? toDateValueArray(value, mode) : undefined),\n    [mode, value]\n  )\n\n  const defaultMachineValue = React.useMemo(\n    () => (value === undefined ? toDateValueArray(defaultValue, mode) : undefined),\n    [defaultValue, mode, value]\n  )\n\n  const service = useMachine(datePickerMachine, {\n    id: datePickerId,\n    selectionMode: mode,\n    numOfMonths: calendarProps?.numberOfMonths ?? 1,\n    outsideDaySelectable: true,\n    timeZone,\n    value: controlledValue,\n    defaultValue: defaultMachineValue,\n    open,\n    defaultOpen,\n    disabled,\n    required,\n    name,\n    locale,\n    onOpenChange(details) {\n      onOpenChange?.(details.open)\n    },\n    onValueChange(details) {\n      onValueChange?.(toModelValue(details.value, mode, timeZone))\n    },\n    positioning: {\n      placement: 'bottom-start' as Placement,\n      gutter: 6,\n    },\n  })\n\n  const api = React.useMemo(() => datePickerConnect(service, normalizeProps), [service])\n\n  const calendarSelected = React.useMemo(\n    () => toCalendarSelected(api.valueAsDate ?? [], mode),\n    [api.valueAsDate, mode]\n  )\n\n  const label = React.useMemo(() => {\n    const formatSingle = (date: Date) => formatter.format(date)\n    const formatRange = (rangeValue: CalendarRangeValue) => {\n      if (rangeValue.from && rangeValue.to) {\n        return `${formatSingle(rangeValue.from)} - ${formatSingle(rangeValue.to)}`\n      }\n      if (rangeValue.from) {\n        return formatSingle(rangeValue.from)\n      }\n      return ''\n    }\n\n    if (mode === 'range') {\n      return calendarSelected && typeof calendarSelected === 'object' && 'from' in calendarSelected\n        ? formatRange(calendarSelected as CalendarRangeValue)\n        : ''\n    }\n\n    return calendarSelected instanceof Date ? formatSingle(calendarSelected) : ''\n  }, [calendarSelected, formatter, mode])\n\n  const handleCalendarSelect = React.useCallback(\n    (next: CalendarSelectedValue) => {\n      const values = toDateValueArray(next as DatePickerValue, mode)\n      api.setValue(values ?? [])\n\n      if (\n        !values ||\n        (mode === 'single' && values.length >= 1) ||\n        (mode === 'range' && values.length >= 2)\n      ) {\n        api.setOpen(false)\n      }\n    },\n    [api, mode]\n  )\n\n  const rootProps = api.getRootProps() as React.HTMLAttributes<HTMLDivElement>\n  const triggerProps = api.getTriggerProps() as React.ButtonHTMLAttributes<HTMLButtonElement>\n  const { className: triggerPropsClassName, ...restTriggerProps } = triggerProps\n\n  const positionerProps = api.getPositionerProps() as React.HTMLAttributes<HTMLDivElement> & {\n    style?: React.CSSProperties\n  }\n  const { style: positionerStyle, ...restPositionerProps } = positionerProps\n\n  const contentProps = api.getContentProps() as React.HTMLAttributes<HTMLDivElement>\n  const { className: contentPropsClassName, ...restContentProps } = contentProps\n\n  return (\n    <div\n      {...rootProps}\n      data-slot=\"date-picker\"\n      className={cn(datePickerRootVariants(), rootProps.className, className)}\n    >\n      <Button\n        asChild\n        variant=\"outline\"\n        size=\"sm\"\n        className={cn(\n          datePickerTriggerVariants(),\n          datePickerTriggerButtonVariants(),\n          triggerClassName,\n          triggerPropsClassName\n        )}\n      >\n        <button {...restTriggerProps}>\n          <svg\n            width={16}\n            height={16}\n            viewBox=\"0 0 24 24\"\n            fill=\"none\"\n            stroke=\"currentColor\"\n            strokeWidth=\"2\"\n            strokeLinecap=\"round\"\n            strokeLinejoin=\"round\"\n            className={datePickerTriggerIconVariants()}\n            aria-hidden=\"true\"\n          >\n            <rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\" />\n            <path d=\"M8 2v4\" />\n            <path d=\"M16 2v4\" />\n            <path d=\"M3 10h18\" />\n          </svg>\n          <span\n            className={cn(\n              datePickerTriggerLabelVariants(),\n              !label && datePickerTriggerLabelEmptyVariants()\n            )}\n          >\n            {label || placeholder}\n          </span>\n        </button>\n      </Button>\n\n      {api.open ? (\n        <Portal>\n          <div\n            {...restPositionerProps}\n            style={{\n              ...positionerStyle,\n              zIndex: 50,\n            }}\n          >\n            <div\n              {...restContentProps}\n              data-slot=\"date-picker-content\"\n              className={cn(datePickerContentVariants(), contentPropsClassName, contentClassName)}\n            >\n              <Calendar\n                {...calendarProps}\n                mode={mode}\n                selected={calendarSelected}\n                onSelect={handleCalendarSelect}\n              />\n            </div>\n          </div>\n        </Portal>\n      ) : null}\n    </div>\n  )\n}\n\nexport { DatePicker }\nexport type { DatePickerProps, DatePickerMode, DatePickerValue }\n"
        },
        {
          "path": "registry/default/vue/date-picker/date-picker.vue",
          "target": "components/ui/date-picker/date-picker.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport type { AssertNoExtraKeys, DatePickerVueProps } from '@timui/core'\nimport {\n  cn,\n  datePickerContentVariants,\n  datePickerRootVariants,\n  datePickerTriggerButtonVariants,\n  datePickerTriggerIconVariants,\n  datePickerTriggerLabelEmptyVariants,\n  datePickerTriggerLabelVariants,\n  datePickerTriggerVariants,\n} from '@timui/core'\nimport Button from '../button/button.vue'\nimport Calendar from '../calendar/calendar.vue'\nimport { useDatePicker } from './use-date-picker'\n\ntype DatePickerProps = DatePickerVueProps & {\n  class?: string\n  triggerClass?: string\n  contentClass?: string\n  calendarProps?: Record<string, unknown>\n}\n\ntype _DatePickerPropsGuard = AssertNoExtraKeys<\n  DatePickerProps,\n  DatePickerVueProps & {\n    class?: string\n    triggerClass?: string\n    contentClass?: string\n    calendarProps?: Record<string, unknown>\n  }\n>\n\nconst props = withDefaults(defineProps<DatePickerProps>(), {\n  mode: 'single',\n  placeholder: 'Date',\n  numberOfMonths: 1,\n})\n\nconst emit = defineEmits<{\n  (e: 'update:modelValue', value?: Date | { from?: Date; to?: Date }): void\n  (e: 'change', value?: Date | { from?: Date; to?: Date }): void\n}>()\n\nconst { api } = useDatePicker(props, emit)\n\nconst rootProps = computed(() => api.value?.getRootProps?.() ?? {})\nconst triggerProps = computed(() => api.value?.getTriggerProps?.() ?? {})\nconst positionerProps = computed(() => api.value?.getPositionerProps?.() ?? {})\nconst contentProps = computed(() => api.value?.getContentProps?.() ?? {})\n\nconst formatter = computed(\n  () =>\n    new Intl.DateTimeFormat(props.locale, {\n      month: 'short',\n      day: '2-digit',\n      year: 'numeric',\n    })\n)\n\nconst formatDate = (date: Date) => formatter.value.format(date)\n\nconst label = computed(() => {\n  const values = api.value?.valueAsDate ?? []\n  if (props.mode === 'range') {\n    if (!values.length) return ''\n    const from = values[0]\n    const to = values[1]\n    if (from && to) return `${formatDate(from)} - ${formatDate(to)}`\n    if (from) return formatDate(from)\n    return ''\n  }\n  return values[0] ? formatDate(values[0]) : ''\n})\n\nconst triggerClassName = computed(() =>\n  cn(\n    datePickerTriggerVariants(),\n    datePickerTriggerButtonVariants(),\n    (triggerProps.value as { class?: string }).class,\n    props.triggerClass\n  )\n)\n\nconst contentClassName = computed(() =>\n  cn(\n    datePickerContentVariants(),\n    (contentProps.value as { class?: string }).class,\n    props.contentClass\n  )\n)\n</script>\n\n<template>\n  <div\n    v-bind=\"rootProps\"\n    data-slot=\"date-picker\"\n    :class=\"cn(datePickerRootVariants(), rootProps.class, props.class)\"\n  >\n    <Button as-child variant=\"outline\" size=\"sm\" :class=\"triggerClassName\">\n      <button v-bind=\"triggerProps\">\n        <svg\n          width=\"16\"\n          height=\"16\"\n          viewBox=\"0 0 24 24\"\n          fill=\"none\"\n          stroke=\"currentColor\"\n          stroke-width=\"2\"\n          stroke-linecap=\"round\"\n          stroke-linejoin=\"round\"\n          :class=\"datePickerTriggerIconVariants()\"\n          aria-hidden=\"true\"\n        >\n          <rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\" />\n          <path d=\"M8 2v4\" />\n          <path d=\"M16 2v4\" />\n          <path d=\"M3 10h18\" />\n        </svg>\n        <span\n          :class=\"\n            cn(datePickerTriggerLabelVariants(), !label && datePickerTriggerLabelEmptyVariants())\n          \"\n        >\n          {{ label || props.placeholder }}\n        </span>\n      </button>\n    </Button>\n\n    <Teleport to=\"body\">\n      <div v-if=\"api?.open\" v-bind=\"positionerProps\" style=\"z-index: 50\">\n        <div v-bind=\"contentProps\" data-slot=\"date-picker-content\" :class=\"contentClassName\">\n          <Calendar v-bind=\"props.calendarProps\" :mode=\"props.mode\" :external-api=\"api\" />\n        </div>\n      </div>\n    </Teleport>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/date-picker/use-date-picker.ts",
          "target": "components/ui/date-picker/use-date-picker.ts",
          "type": "registry:component",
          "content": "import { getLocalTimeZone } from '@internationalized/date'\nimport { datePickerConnect, datePickerMachine } from '@timui/core'\nimport type {\n  DatePickerMode,\n  DatePickerRangeValue,\n  DatePickerVueProps,\n  DatePickerVueValue,\n} from '@timui/core'\nimport { parse as parseDateValue } from '@zag-js/date-picker'\nimport type { DateValue } from '@zag-js/date-picker'\nimport type { Placement } from '@zag-js/popper'\nimport { normalizeProps, useMachine } from '@zag-js/vue'\nimport { computed, useId } from 'vue'\n\nexport type UseDatePickerProps = DatePickerVueProps & {\n  numberOfMonths?: number\n}\n\ntype DatePickerModelValue =\n  | Date\n  | {\n      from?: Date\n      to?: Date\n    }\n  | undefined\n\nexport type UseDatePickerEmits = {\n  (e: 'update:modelValue', value: DatePickerModelValue): void\n  (e: 'change', value: DatePickerModelValue): void\n}\n\nexport function useDatePicker(props: UseDatePickerProps, emit: UseDatePickerEmits) {\n  const localTimeZone = getLocalTimeZone()\n  const generatedId = useId()\n  const toPickerDate = (input: string | Date) =>\n    parseDateValue(\n      input instanceof Date\n        ? `${input.getFullYear()}-${String(input.getMonth() + 1).padStart(2, '0')}-${String(\n            input.getDate()\n          ).padStart(2, '0')}`\n        : input\n    )\n\n  const toDateValueArray = (value: DatePickerVueValue | undefined, mode: DatePickerMode) => {\n    if (!value) return undefined\n    if (value instanceof Date) return [toPickerDate(value)]\n\n    const range = value as DatePickerRangeValue\n    if (mode === 'range') {\n      if (!range?.from) return undefined\n      const parsed: DateValue[] = []\n      parsed.push(toPickerDate(range.from))\n      if (range?.to) parsed.push(toPickerDate(range.to))\n      return parsed.length ? parsed : undefined\n    }\n\n    const fallback = range?.from ?? range?.to\n    return fallback ? [toPickerDate(fallback)] : undefined\n  }\n\n  const toModelValue = (values: DateValue[], mode: DatePickerMode) => {\n    if (mode === 'range') {\n      const from = values[0]?.toDate(localTimeZone)\n      const to = values[1]?.toDate(localTimeZone)\n      return from || to ? { from, to } : undefined\n    }\n    return values[0]?.toDate(localTimeZone)\n  }\n\n  const machineProps = computed(() => {\n    const mode = props.mode || 'single'\n    const currentValue = props.modelValue ?? props.value\n    const controlledValue =\n      currentValue !== undefined ? toDateValueArray(currentValue, mode) : undefined\n\n    const defaultValue =\n      currentValue === undefined ? toDateValueArray(props.defaultValue, mode) : undefined\n    const min = props.minDate ? toPickerDate(props.minDate) : undefined\n    const max = props.maxDate ? toPickerDate(props.maxDate) : undefined\n\n    return {\n      id: props.id ?? generatedId,\n      selectionMode: mode,\n      numOfMonths: props.numberOfMonths || 1,\n      outsideDaySelectable: true,\n      timeZone: localTimeZone,\n      min,\n      max,\n      value: controlledValue,\n      defaultValue,\n      open: props.open,\n      defaultOpen: props.defaultOpen,\n      disabled: props.disabled,\n      required: props.required,\n      name: props.name,\n      locale: props.locale,\n      isDateUnavailable: props.isDateUnavailable\n        ? (date: DateValue) => props.isDateUnavailable?.(date.toDate(localTimeZone)) ?? false\n        : undefined,\n      onValueChange(details: { value: DateValue[] }) {\n        const next = toModelValue(details.value, mode)\n        props.onValueChange?.(next)\n        emit('update:modelValue', next)\n        emit('change', next)\n      },\n      onOpenChange(details: { open: boolean }) {\n        props.onOpenChange?.(details.open)\n      },\n      positioning: {\n        placement: 'bottom-start' as Placement,\n        gutter: 6,\n      },\n    }\n  })\n\n  const service = useMachine(datePickerMachine, machineProps)\n  const api = computed(() => datePickerConnect(service, normalizeProps))\n\n  return {\n    api,\n    localTimeZone,\n  }\n}\n"
        },
        {
          "path": "registry/default/html/date-picker.html",
          "target": "components/ui/date-picker.html",
          "type": "registry:component",
          "content": "<div data-slot=\"date-picker\" class=\"w-full\">\n  <button\n    data-slot=\"date-picker-trigger\"\n    class=\"text-sm font-medium\"\n  >\n    <svg\n      width=\"16\"\n      height=\"16\"\n      viewBox=\"0 0 24 24\"\n      fill=\"none\"\n      stroke=\"currentColor\"\n      stroke-width=\"2\"\n      stroke-linecap=\"round\"\n      stroke-linejoin=\"round\"\n      class=\"text-muted-foreground/80 -ms-1 shrink-0\"\n      aria-hidden=\"true\"\n    >\n      <rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\" />\n      <path d=\"M8 2v4\" />\n      <path d=\"M16 2v4\" />\n      <path d=\"M3 10h18\" />\n    </svg>\n    <span class=\"font-medium\">Date</span>\n  </button>\n  <div data-slot=\"date-picker-content\" class=\"w-auto p-2\">\n    <div class=\"text-muted-foreground text-sm\">Calendar</div>\n  </div>\n</div>"
        },
        {
          "path": "registry/default/weapp/date-picker.wxml",
          "target": "components/ui/date-picker.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\" data-slot=\"date-picker\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/date-picker.wxss",
          "target": "components/ui/date-picker.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/date-picker.ts",
          "target": "components/ui/date-picker.ts",
          "type": "registry:component",
          "content": "import { cn } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass) {\n      this.setData({\n        className: cn('w-full', extClass),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/date-picker.json",
          "target": "components/ui/date-picker.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        }
      ],
      "categories": [
        "date"
      ],
      "optionalPeerDependencies": [
        "@internationalized/date"
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@zag-js/popper",
              "@zag-js/react"
            ],
            "optionalPeerDependencies": [
              "@internationalized/date"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@zag-js/date-picker",
              "@zag-js/popper",
              "@zag-js/vue"
            ],
            "optionalPeerDependencies": [
              "@internationalized/date"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "calendar-rac",
      "type": "registry:ui",
      "dependencies": [
        "@internationalized/date"
      ],
      "optionalPeerDependencies": [
        "@internationalized/date"
      ],
      "files": [
        {
          "path": "registry/default/ui/calendar-rac.tsx",
          "type": "registry:ui",
          "target": "components/ui/calendar-rac.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\n\nimport { Calendar } from './calendar'\nimport { RangeCalendar } from './range-calendar'\n\ntype CalendarRACProps = React.ComponentProps<typeof Calendar>\ntype RangeCalendarRACProps = React.ComponentProps<typeof RangeCalendar>\n\nfunction CalendarRAC(props: CalendarRACProps) {\n  return <Calendar {...props} />\n}\n\nfunction RangeCalendarRAC(props: RangeCalendarRACProps) {\n  return <RangeCalendar {...props} />\n}\n\nexport { CalendarRAC, RangeCalendarRAC }\n"
        },
        {
          "path": "registry/default/vue/calendar-rac.vue",
          "type": "registry:ui",
          "target": "components/ui/calendar-rac.vue",
          "content": "<script setup lang=\"ts\">\nimport CalendarRac from './calendar/calendar-rac.vue'\n</script>\n\n<template>\n  <CalendarRac v-bind=\"$attrs\" />\n</template>\n"
        }
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue"
        ],
        "dependenciesByFramework": {
          "react": {},
          "vue": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "checkbox",
      "type": "registry:ui",
      "dependencies": [
        "@timui/core",
        "@zag-js/react"
      ],
      "registryDependencies": [
        "use-machine"
      ],
      "files": [
        {
          "path": "registry/default/ui/checkbox.tsx",
          "type": "registry:ui",
          "target": "components/ui/checkbox.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport type { CheckboxProps as CoreCheckboxProps } from '@timui/core'\nimport {\n  checkboxConnect,\n  checkboxIndicatorCheckVariants,\n  checkboxIndicatorIconVariants,\n  checkboxIndicatorVariants,\n  checkboxMachine,\n  checkboxRootVariants,\n  checkboxVariants,\n  cn,\n  createTimEvent,\n} from '@timui/core'\nimport { mergeProps } from '@zag-js/react'\n\nimport { useCheckbox } from './checkbox/use-checkbox'\n\ntype CheckboxProps = CoreCheckboxProps &\n  Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, keyof CoreCheckboxProps>\n\nconst Checkbox = React.forwardRef<HTMLButtonElement, CheckboxProps>(\n  (\n    {\n      className,\n      checked,\n      defaultChecked,\n      required,\n      onCheckedChange,\n      value = 'on',\n      disabled,\n      name,\n      id,\n      ...props\n    },\n    ref\n  ) => {\n    const api = useCheckbox({\n      id,\n      checked,\n      defaultChecked,\n      disabled,\n      required,\n      name,\n      value: value ?? 'on',\n      onCheckedChange,\n    })\n    const rootProps = api.getRootProps()\n    const controlProps = api.getControlProps()\n    const indicatorProps = api.getIndicatorProps()\n    const hiddenInputProps = api.getHiddenInputProps()\n    const mergedControlProps = mergeProps(controlProps, props)\n    const {\n      className: controlClassName,\n      onClick: controlOnClick,\n      ...controlRest\n    } = mergedControlProps\n\n    return (\n      <label\n        {...rootProps}\n        data-slot=\"checkbox-root\"\n        className={cn(checkboxRootVariants(), rootProps.className)}\n      >\n        <button\n          {...controlRest}\n          ref={ref}\n          type=\"button\"\n          data-slot=\"checkbox\"\n          className={cn(checkboxVariants(), controlClassName, className)}\n          onClick={(event) => {\n            const prevCheckedState = api.checkedState\n            if (typeof controlOnClick === 'function') {\n              controlOnClick(event)\n            }\n\n            // Some composed demos rely on click bubbling and can miss Zag's default toggle.\n            // Keep behavior deterministic by applying a fallback toggle when state did not change.\n            if (!event.defaultPrevented && api.checkedState === prevCheckedState) {\n              api.toggleChecked()\n            }\n          }}\n        >\n          <span\n            {...indicatorProps}\n            data-slot=\"checkbox-indicator\"\n            className={cn(\n              checkboxIndicatorVariants(),\n              (api.checked || api.indeterminate) && 'opacity-100',\n              indicatorProps.className\n            )}\n          >\n            {api.indeterminate ? (\n              <span className={checkboxIndicatorCheckVariants()} />\n            ) : (\n              <svg\n                aria-hidden=\"true\"\n                viewBox=\"0 0 16 16\"\n                fill=\"none\"\n                stroke=\"currentColor\"\n                strokeWidth=\"3\"\n                strokeLinecap=\"round\"\n                strokeLinejoin=\"round\"\n                className={checkboxIndicatorIconVariants()}\n              >\n                <path d=\"M3.5 8.5l3 3 6-7\" />\n              </svg>\n            )}\n          </span>\n        </button>\n        <input {...hiddenInputProps} />\n      </label>\n    )\n  }\n)\nCheckbox.displayName = 'Checkbox'\n\nexport { Checkbox }\n"
        },
        {
          "path": "registry/default/ui/checkbox/use-checkbox.ts",
          "target": "components/ui/checkbox/use-checkbox.ts",
          "type": "registry:ui",
          "content": "import * as React from 'react'\nimport type { CheckboxProps as CoreCheckboxProps } from '@timui/core'\nimport { checkboxConnect, checkboxMachine, createTimEvent } from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/react'\n\nexport interface UseCheckboxProps extends Omit<CoreCheckboxProps, 'id'> {\n  id?: string\n}\n\nexport function useCheckbox(props: UseCheckboxProps) {\n  const generatedId = React.useId()\n  const checkboxId = props.id ?? generatedId\n\n  const service = useMachine(checkboxMachine, {\n    id: checkboxId,\n    checked: props.checked,\n    defaultChecked: props.defaultChecked,\n    disabled: props.disabled,\n    required: props.required,\n    name: props.name,\n    value: props.value ?? 'on',\n    onCheckedChange(details) {\n      props.onCheckedChange?.(createTimEvent('change', checkboxId, { checked: !!details.checked }))\n    },\n  })\n\n  const api = React.useMemo(() => checkboxConnect(service, normalizeProps), [service])\n\n  return api\n}\n"
        },
        {
          "path": "registry/default/vue/checkbox/checkbox-tree.vue",
          "target": "components/ui/checkbox/checkbox-tree.vue",
          "type": "registry:component",
          "content": "<script lang=\"ts\">\nimport { defineComponent, ref, type PropType, type VNodeChild } from \"vue\";\nimport type {\n  AssertNoExtraKeys,\n  CheckboxTreeNode,\n  CheckboxTreeProps as CoreCheckboxTreeProps,\n} from \"@timui/core\";\n\ntype CheckboxTreeProps = CoreCheckboxTreeProps<VNodeChild>;\ntype _CheckboxTreePropsGuard = AssertNoExtraKeys<\n  CheckboxTreeProps,\n  CoreCheckboxTreeProps<VNodeChild>\n>;\n\nexport default defineComponent({\n  name: \"CheckboxTree\",\n  props: {\n    tree: {\n      type: Object as () => CheckboxTreeNode,\n      required: true,\n    },\n    renderNode: {\n      type: Function as PropType<\n        (props: {\n          node: CheckboxTreeNode;\n          isChecked: boolean | \"indeterminate\";\n          onCheckedChange: () => void;\n          children: VNodeChild[] | undefined;\n        }) => VNodeChild\n      >,\n      required: true,\n    },\n  },\n  setup(props) {\n    const checkedNodes = ref(new Set<string>());\n\n    const initializeCheckedNodes = (node: CheckboxTreeNode) => {\n      if (node.defaultChecked) checkedNodes.value.add(node.id);\n      node.children?.forEach(initializeCheckedNodes);\n    };\n\n    initializeCheckedNodes(props.tree);\n\n    const isChecked = (node: CheckboxTreeNode): boolean | \"indeterminate\" => {\n      if (!node.children?.length) return checkedNodes.value.has(node.id);\n\n      const childrenChecked = node.children.map((child) => isChecked(child));\n      if (childrenChecked.every((status) => status === true)) return true;\n      if (childrenChecked.some((status) => status === true || status === \"indeterminate\")) {\n        return \"indeterminate\";\n      }\n      return false;\n    };\n\n    const handleCheck = (node: CheckboxTreeNode) => {\n      const next = new Set(checkedNodes.value);\n\n      const toggleNode = (current: CheckboxTreeNode, check: boolean) => {\n        if (check) next.add(current.id);\n        else next.delete(current.id);\n        current.children?.forEach((child) => toggleNode(child, check));\n      };\n\n      const currentStatus = isChecked(node);\n      const nextCheck = currentStatus !== true;\n      toggleNode(node, nextCheck);\n\n      checkedNodes.value = next;\n    };\n\n    const renderTreeNode = (node: CheckboxTreeNode): VNodeChild => {\n      const children = node.children?.map(renderTreeNode);\n      return props.renderNode({\n        node,\n        isChecked: isChecked(node),\n        onCheckedChange: () => handleCheck(node),\n        children,\n      });\n    };\n\n    return () => renderTreeNode(props.tree);\n  },\n});\n</script>\n"
        },
        {
          "path": "registry/default/vue/checkbox/checkbox.vue",
          "target": "components/ui/checkbox/checkbox.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { normalizeProps, useMachine } from \"@zag-js/vue\";\nimport type { AssertNoExtraKeys, CheckboxVueProps } from \"@timui/core\";\nimport {\n  checkboxConnect,\n  checkboxIndicatorCheckVariants,\n  checkboxIndicatorIconVariants,\n  checkboxIndicatorVariants,\n  checkboxMachine,\n  checkboxRootVariants,\n  checkboxVariants,\n  cn,\n} from \"@timui/core\";\n\nimport { useCheckbox } from \"./use-checkbox\";\n\ntype CheckboxProps = CheckboxVueProps & { class?: string };\ntype _CheckboxPropsGuard = AssertNoExtraKeys<CheckboxProps, CheckboxProps>;\n\nconst props = defineProps<CheckboxProps>();\n\nconst emit = defineEmits([\"update:modelValue\", \"update:checked\", \"change\"]);\ntype CheckedChangeDetails = Parameters<NonNullable<CheckboxVueProps[\"onCheckedChange\"]>>[0];\n\nconst api = useCheckbox(props, emit);\nconst rootProps = computed(() => api.value?.getRootProps?.() ?? {});\nconst controlProps = computed(() => api.value?.getControlProps?.() ?? {});\nconst indicatorProps = computed(() => api.value?.getIndicatorProps?.() ?? {});\nconst hiddenInputProps = computed(() => api.value?.getHiddenInputProps?.() ?? {});\n</script>\n\n<template>\n  <label\n    v-bind=\"rootProps\"\n    data-slot=\"checkbox-root\"\n    :class=\"cn(checkboxRootVariants(), rootProps.class)\"\n  >\n    <button\n      v-bind=\"controlProps\"\n      data-slot=\"checkbox\"\n      type=\"button\"\n      :class=\"\n        cn(\n          checkboxVariants(),\n          controlProps.class,\n          props.class\n        )\n      \"\n    >\n      <span\n        v-bind=\"indicatorProps\"\n        data-slot=\"checkbox-indicator\"\n        :class=\"\n          cn(\n            checkboxIndicatorVariants(),\n            (api?.checked || api?.indeterminate) && 'opacity-100',\n            indicatorProps.class\n          )\n        \"\n      >\n        <span v-if=\"api?.indeterminate\" :class=\"checkboxIndicatorCheckVariants()\" />\n        <svg\n          v-else\n          aria-hidden=\"true\"\n          viewBox=\"0 0 16 16\"\n          fill=\"none\"\n          stroke=\"currentColor\"\n          stroke-width=\"3\"\n          stroke-linecap=\"round\"\n          stroke-linejoin=\"round\"\n          :class=\"checkboxIndicatorIconVariants()\"\n        >\n          <path d=\"M3.5 8.5l3 3 6-7\" />\n        </svg>\n      </span>\n    </button>\n    <input v-bind=\"hiddenInputProps\" />\n  </label>\n</template>\n"
        },
        {
          "path": "registry/default/vue/checkbox/use-checkbox.ts",
          "target": "components/ui/checkbox/use-checkbox.ts",
          "type": "registry:component",
          "content": "import { checkboxConnect, checkboxMachine } from '@timui/core'\nimport type { CheckboxVueProps } from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/vue'\nimport { computed, useId } from 'vue'\n\ntype UseCheckboxEmit = {\n  (event: 'update:modelValue', value: boolean | 'indeterminate'): void\n  (event: 'update:checked', value: boolean | 'indeterminate'): void\n  (event: 'change', value: boolean | 'indeterminate'): void\n}\n\nexport function useCheckbox(props: CheckboxVueProps, emit: UseCheckboxEmit) {\n  const generatedId = useId()\n\n  const machineProps = computed(() => ({\n    id: props.id ?? generatedId,\n    checked: props.modelValue ?? props.checked,\n    defaultChecked:\n      props.modelValue === undefined && props.checked === undefined\n        ? props.defaultChecked\n        : undefined,\n    disabled: props.disabled,\n    required: props.required,\n    name: props.name,\n    value: props.value,\n    onCheckedChange(details: { checked: boolean | 'indeterminate' }) {\n      props.onCheckedChange?.(details.checked)\n      emit('update:modelValue', details.checked)\n      emit('update:checked', details.checked)\n      emit('change', details.checked)\n    },\n  }))\n\n  const service = useMachine(checkboxMachine, machineProps)\n  const api = computed(() => checkboxConnect(service, normalizeProps))\n\n  return api\n}\n"
        },
        {
          "path": "registry/default/html/checkbox.html",
          "target": "components/ui/checkbox.html",
          "type": "registry:component",
          "content": "<label data-slot=\"checkbox-root\" class=\"inline-flex items-center\">\n    <button type=\"button\" role=\"checkbox\" data-slot=\"checkbox\" data-state=\"unchecked\" class=\"peer border-input data-[state&#x3D;checked]:bg-primary data-[state&#x3D;checked]:text-primary-foreground data-[state&#x3D;checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive flex size-4 shrink-0 items-center justify-center rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50\">\n        <span data-slot=\"checkbox-indicator\"\n            class=\"flex items-center justify-center text-current opacity-0 transition-opacity duration-100 opacity-0\">\n            <svg aria-hidden=\"true\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\"\n                stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"size-3.5\">\n                <path d=\"M3.5 8.5l3 3 6-7\" />\n            </svg>\n        </span>\n    </button>\n    <input type=\"checkbox\"\n        style=\"border: 0px; clip: rect(0px, 0px, 0px, 0px); clip-path: inset(50%); height: 1px; margin: -1px; overflow: hidden; padding: 0px; position: absolute; width: 1px; white-space: nowrap; word-wrap: normal;\" />\n</label>"
        },
        {
          "path": "registry/default/weapp/checkbox.wxml",
          "target": "components/ui/checkbox.wxml",
          "type": "registry:component",
          "content": "<label \n    id=\"{{api.rootProps.id}}\"\n    class=\"flex items-center space-x-2 {{className}} opacity-{{api.disabled ? 50 : 100}}\"\n    style=\"min-height: 88rpx;\"\n    data-state=\"{{api.checked ? 'checked' : 'unchecked'}}\"\n    data-disabled=\"{{api.disabled}}\"\n    bindtap=\"onTap\"\n>\n    <!-- Visual Checkbox -->\n    <view class=\"peer h-5 w-5 shrink-0 rounded-sm border border-primary shadow focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[state=indeterminate]:bg-primary data-[state=indeterminate]:text-primary-foreground\"\n      data-state=\"{{api.checked ? 'checked' : api.checked === 'indeterminate' ? 'indeterminate' : 'unchecked'}}\">\n        <block wx:if=\"{{api.checked === true}}\">\n            <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"h-4 w-4\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n        </block>\n        <block wx:if=\"{{api.checked === 'indeterminate'}}\">\n             <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"h-4 w-4\"><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"></line></svg>\n        </block>\n    </view>\n    <!-- Label Slot -->\n    <slot />\n    <!-- Hidden Input for Form Submission -->\n    <input type=\"text\" class=\"hidden\" name=\"{{name}}\" value=\"{{api.checked}}\" style=\"display: none;\" />\n</label>\n"
        },
        {
          "path": "registry/default/weapp/checkbox.wxss",
          "target": "components/ui/checkbox.wxss",
          "type": "registry:component",
          "content": "/* packages/weapp/src/checkbox/checkbox.wxss */\n"
        },
        {
          "path": "registry/default/weapp/checkbox.ts",
          "target": "components/ui/checkbox.ts",
          "type": "registry:component",
          "content": "import { checkboxVariants } from '../utils'\nimport { setupCheckboxMachine } from './use-checkbox'\n\ntype CheckboxChecked = boolean | 'indeterminate'\n\ntype WeappCheckboxApi = {\n  checked?: CheckboxChecked\n  rootProps?: {\n    onClick?: (event: object) => void\n  }\n}\n\ntype WeappService = {\n  send: (event: object) => void\n}\ntype MachineEvent = string | { type: string; [key: string]: object }\ntype MachineSend = (event: MachineEvent) => void\n\ntype WeappCheckboxInternal = WechatMiniprogram.Component.InstanceMethods<{}, {}, {}> & {\n  _service?: WeappService\n  _cleanup?: () => void\n  _send?: (event: object) => void\n  _connect?: (state: object, send: MachineSend) => WeappCheckboxApi\n  data: {\n    api: WeappCheckboxApi\n  }\n  properties: {\n    checked: CheckboxChecked\n    defaultChecked: CheckboxChecked\n    disabled: boolean\n    required: boolean\n    readOnly: boolean\n    name: string\n    form: string\n    value: string\n    id: string\n    extClass: string\n  }\n}\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    checked: { type: null, value: false }, // boolean | 'indeterminate'\n    defaultChecked: { type: null, value: false },\n    disabled: { type: Boolean, value: false },\n    required: { type: Boolean, value: false },\n    readOnly: { type: Boolean, value: false },\n    name: { type: String, value: '' },\n    form: { type: String, value: '' },\n    value: { type: String, value: 'on' },\n    id: { type: String, value: 'checkbox' },\n    extClass: { type: String, value: '' },\n  },\n\n  data: {\n    api: {} as WeappCheckboxApi,\n    className: '',\n  },\n\n  lifetimes: {\n    attached() {\n      const self = this as WeappCheckboxInternal\n      const { controller, connect } = setupCheckboxMachine(this)\n      self._service = controller.service as WeappService\n      self._cleanup = controller.start()\n      self._send = controller.send as MachineSend\n      self._connect = connect\n\n      this.setData({\n        className: checkboxVariants({ className: this.properties.extClass }),\n      })\n    },\n    detached() {\n      const self = this as WeappCheckboxInternal\n      self._cleanup?.()\n    },\n  },\n\n  observers: {\n    state: function (state) {\n      const self = this as WeappCheckboxInternal\n      if (!state || !self._send || !self._connect) return\n      const api = self._connect(state, self._send) as WeappCheckboxApi\n\n      const { baseClass } = checkboxVariants({ className: self.properties.extClass })\n      this.setData({ api, className: baseClass })\n    },\n\n    checked: function (val) {\n      const self = this as WeappCheckboxInternal\n      if (self._service && val !== self.data.api.checked) {\n        self._send?.({ type: 'CHECKED.SET', checked: val })\n      }\n    },\n    disabled: function (val) {\n      const self = this as WeappCheckboxInternal\n      self._service?.send({ type: 'DISABLED.SET', disabled: val })\n    },\n  },\n\n  methods: {\n    onTap(e: WechatMiniprogram.BaseEvent) {\n      const self = this as WeappCheckboxInternal\n      self.data.api.rootProps?.onClick?.(e)\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/checkbox.json",
          "target": "components/ui/checkbox.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/checkbox-tree/checkbox-tree.wxml",
          "target": "components/ui/checkbox-tree/checkbox-tree.wxml",
          "type": "registry:component",
          "content": "<view class=\"checkbox-tree {{extClass}}\">\n  <view\n    wx:for=\"{{flatNodes}}\"\n    wx:key=\"id\"\n    class=\"checkbox-tree-item\"\n    style=\"padding-left: {{item.level * 20}}rpx;\"\n    data-id=\"{{item.id}}\"\n    bindtap=\"onToggle\"\n  >\n    <checkbox checked=\"{{checkedMap[item.id]}}\" disabled=\"{{item.disabled}}\" />\n    <text class=\"checkbox-tree-label\">{{item.label}}</text>\n  </view>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/checkbox-tree/checkbox-tree.wxss",
          "target": "components/ui/checkbox-tree/checkbox-tree.wxss",
          "type": "registry:component",
          "content": ".checkbox-tree {\n  display: flex;\n  flex-direction: column;\n  gap: 12rpx;\n}\n\n.checkbox-tree-item {\n  display: flex;\n  align-items: center;\n  gap: 12rpx;\n}\n\n.checkbox-tree-label {\n  font-size: 28rpx;\n  color: #111827;\n}\n"
        },
        {
          "path": "registry/default/weapp/checkbox-tree/checkbox-tree.json",
          "target": "components/ui/checkbox-tree/checkbox-tree.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/checkbox-tree/checkbox-tree.ts",
          "target": "components/ui/checkbox-tree/checkbox-tree.ts",
          "type": "registry:component",
          "content": "import { emitTimEvent } from '../utils'\n\ntype CheckboxTreeNode = {\n  id: string\n  label: string\n  checked?: boolean\n  disabled?: boolean\n  children?: CheckboxTreeNode[]\n}\n\ntype FlatNode = CheckboxTreeNode & { level: number }\n\nconst flattenNodes = (nodes: CheckboxTreeNode[], level = 0, acc: FlatNode[] = []) => {\n  nodes.forEach((node) => {\n    acc.push({\n      ...node,\n      level,\n    })\n    if (Array.isArray(node.children) && node.children.length > 0) {\n      flattenNodes(node.children, level + 1, acc)\n    }\n  })\n  return acc\n}\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    nodes: {\n      type: Array,\n      value: [],\n    },\n    checkedKeys: {\n      type: Array,\n      value: [],\n    },\n    id: {\n      type: String,\n      value: 'checkbox-tree',\n    },\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n\n  data: {\n    flatNodes: [] as FlatNode[],\n    checkedMap: {} as Record<string, boolean>,\n  },\n\n  lifetimes: {\n    attached() {\n      this.syncFromProps()\n    },\n  },\n\n  observers: {\n    'nodes, checkedKeys': function () {\n      this.syncFromProps()\n    },\n  },\n\n  methods: {\n    syncFromProps() {\n      const flatNodes = flattenNodes((this.properties.nodes || []) as CheckboxTreeNode[])\n      const checkedMap: Record<string, boolean> = {}\n      ;(this.properties.checkedKeys as string[]).forEach((id) => {\n        checkedMap[id] = true\n      })\n      flatNodes.forEach((node) => {\n        if (node.checked && checkedMap[node.id] === undefined) {\n          checkedMap[node.id] = true\n        }\n      })\n      this.setData({ flatNodes, checkedMap })\n    },\n\n    onToggle(e: WechatMiniprogram.BaseEvent) {\n      const id = e.currentTarget.dataset.id as string\n      if (!id) return\n      const checkedMap = { ...(this.data.checkedMap || {}) }\n      checkedMap[id] = !checkedMap[id]\n      const checkedKeys = Object.keys(checkedMap).filter((key) => checkedMap[key])\n      this.setData({ checkedMap })\n      emitTimEvent(this, 'change', 'change', this.properties.id || 'checkbox-tree', {\n        checkedKeys,\n      })\n      this.triggerEvent('update:checkedKeys', checkedKeys)\n    },\n  },\n})\n"
        }
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@zag-js/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@zag-js/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "checkbox-tree",
      "type": "registry:ui",
      "files": [
        {
          "path": "registry/default/ui/checkbox-tree.tsx",
          "type": "registry:ui",
          "target": "components/ui/checkbox-tree.tsx",
          "content": "/**\n * IMPORTANT: This component was built for demo purposes only and has not been tested in production.\n * It serves as a proof of concept for a checkbox tree implementation.\n * If you're interested in collaborating to create a more robust, production-ready\n * headless component, your contributions are welcome!\n */\n\n'use client'\n\nimport React, { useCallback, useMemo, useState } from 'react'\nimport type {\n  AssertNoExtraKeys,\n  CheckboxTreeNode,\n  CheckboxTreeProps as CoreCheckboxTreeProps,\n} from '@timui/core'\n\ntype CheckboxTreeProps = CoreCheckboxTreeProps<React.ReactNode>\ntype _CheckboxTreePropsGuard = AssertNoExtraKeys<\n  CheckboxTreeProps,\n  CoreCheckboxTreeProps<React.ReactNode>\n>\n\nfunction useCheckboxTree(initialTree: CheckboxTreeNode) {\n  const initialCheckedNodes = useMemo(() => {\n    const checkedSet = new Set<string>()\n    const initializeCheckedNodes = (node: CheckboxTreeNode) => {\n      if (node.defaultChecked) {\n        checkedSet.add(node.id)\n      }\n      node.children?.forEach(initializeCheckedNodes)\n    }\n    initializeCheckedNodes(initialTree)\n    return checkedSet\n  }, [initialTree])\n\n  const [checkedNodes, setCheckedNodes] = useState<Set<string>>(initialCheckedNodes)\n\n  const isChecked = useCallback(\n    (node: CheckboxTreeNode): boolean | 'indeterminate' => {\n      if (!node.children) {\n        return checkedNodes.has(node.id)\n      }\n\n      const childrenChecked = node.children.map((child) => isChecked(child))\n      if (childrenChecked.every((status) => status === true)) {\n        return true\n      }\n      if (childrenChecked.some((status) => status === true || status === 'indeterminate')) {\n        return 'indeterminate'\n      }\n      return false\n    },\n    [checkedNodes]\n  )\n\n  const handleCheck = useCallback(\n    (node: CheckboxTreeNode) => {\n      const newCheckedNodes = new Set(checkedNodes)\n\n      const toggleNode = (n: CheckboxTreeNode, check: boolean) => {\n        if (check) {\n          newCheckedNodes.add(n.id)\n        } else {\n          newCheckedNodes.delete(n.id)\n        }\n        n.children?.forEach((child) => toggleNode(child, check))\n      }\n\n      const currentStatus = isChecked(node)\n      const newCheck = currentStatus !== true\n\n      toggleNode(node, newCheck)\n      setCheckedNodes(newCheckedNodes)\n    },\n    [checkedNodes, isChecked]\n  )\n\n  return { isChecked, handleCheck }\n}\n\nexport function CheckboxTree({ tree, renderNode }: CheckboxTreeProps) {\n  const { isChecked, handleCheck } = useCheckboxTree(tree)\n\n  const renderTreeNode = (node: CheckboxTreeNode): React.ReactNode => {\n    const children = node.children?.map(renderTreeNode)\n\n    return renderNode({\n      node,\n      isChecked: isChecked(node),\n      onCheckedChange: () => handleCheck(node),\n      children,\n    }) as React.ReactNode\n  }\n\n  return renderTreeNode(tree)\n}\n"
        },
        {
          "path": "registry/default/vue/checkbox-tree/checkbox-tree.vue",
          "target": "components/ui/checkbox-tree/checkbox-tree.vue",
          "type": "registry:component",
          "content": "<script lang=\"ts\">\nexport { default } from '../checkbox/checkbox-tree.vue'\n</script>\n"
        },
        {
          "path": "registry/default/html/checkbox-tree.html",
          "target": "components/ui/checkbox-tree.html",
          "type": "registry:component",
          "content": "<div data-slot=\"checkbox-tree\" class=\"space-y-2\">\n  <label class=\"flex items-center gap-2 py-1\">\n    <input type=\"checkbox\" />\n    <span>Workspace</span>\n  </label>\n  <div class=\"ml-6 space-y-2\">\n    <label class=\"flex items-center gap-2 py-1\">\n      <input type=\"checkbox\" checked />\n      <span>Frontend</span>\n    </label>\n    <label class=\"flex items-center gap-2 py-1\">\n      <input type=\"checkbox\" />\n      <span>Backend</span>\n    </label>\n  </div>\n</div>"
        },
        {
          "path": "registry/default/weapp/checkbox-tree.wxml",
          "target": "components/ui/checkbox-tree.wxml",
          "type": "registry:component",
          "content": "<view class=\"checkbox-tree {{extClass}}\">\n  <view\n    wx:for=\"{{flatNodes}}\"\n    wx:key=\"id\"\n    class=\"checkbox-tree-item\"\n    style=\"padding-left: {{item.level * 20}}rpx;\"\n    data-id=\"{{item.id}}\"\n    bindtap=\"onToggle\"\n  >\n    <checkbox checked=\"{{checkedMap[item.id]}}\" disabled=\"{{item.disabled}}\" />\n    <text class=\"checkbox-tree-label\">{{item.label}}</text>\n  </view>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/checkbox-tree.wxss",
          "target": "components/ui/checkbox-tree.wxss",
          "type": "registry:component",
          "content": ".checkbox-tree {\n  display: flex;\n  flex-direction: column;\n  gap: 12rpx;\n}\n\n.checkbox-tree-item {\n  display: flex;\n  align-items: center;\n  gap: 12rpx;\n}\n\n.checkbox-tree-label {\n  font-size: 28rpx;\n  color: #111827;\n}\n"
        },
        {
          "path": "registry/default/weapp/checkbox-tree.ts",
          "target": "components/ui/checkbox-tree.ts",
          "type": "registry:component",
          "content": "import { emitTimEvent } from '../utils'\n\ntype CheckboxTreeNode = {\n  id: string\n  label: string\n  checked?: boolean\n  disabled?: boolean\n  children?: CheckboxTreeNode[]\n}\n\ntype FlatNode = CheckboxTreeNode & { level: number }\n\nconst flattenNodes = (nodes: CheckboxTreeNode[], level = 0, acc: FlatNode[] = []) => {\n  nodes.forEach((node) => {\n    acc.push({\n      ...node,\n      level,\n    })\n    if (Array.isArray(node.children) && node.children.length > 0) {\n      flattenNodes(node.children, level + 1, acc)\n    }\n  })\n  return acc\n}\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    nodes: {\n      type: Array,\n      value: [],\n    },\n    checkedKeys: {\n      type: Array,\n      value: [],\n    },\n    id: {\n      type: String,\n      value: 'checkbox-tree',\n    },\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n\n  data: {\n    flatNodes: [] as FlatNode[],\n    checkedMap: {} as Record<string, boolean>,\n  },\n\n  lifetimes: {\n    attached() {\n      this.syncFromProps()\n    },\n  },\n\n  observers: {\n    'nodes, checkedKeys': function () {\n      this.syncFromProps()\n    },\n  },\n\n  methods: {\n    syncFromProps() {\n      const flatNodes = flattenNodes((this.properties.nodes || []) as CheckboxTreeNode[])\n      const checkedMap: Record<string, boolean> = {}\n      ;(this.properties.checkedKeys as string[]).forEach((id) => {\n        checkedMap[id] = true\n      })\n      flatNodes.forEach((node) => {\n        if (node.checked && checkedMap[node.id] === undefined) {\n          checkedMap[node.id] = true\n        }\n      })\n      this.setData({ flatNodes, checkedMap })\n    },\n\n    onToggle(e: WechatMiniprogram.BaseEvent) {\n      const id = e.currentTarget.dataset.id as string\n      if (!id) return\n      const checkedMap = { ...(this.data.checkedMap || {}) }\n      checkedMap[id] = !checkedMap[id]\n      const checkedKeys = Object.keys(checkedMap).filter((key) => checkedMap[key])\n      this.setData({ checkedMap })\n      emitTimEvent(this, 'change', 'change', this.properties.id || 'checkbox-tree', {\n        checkedKeys,\n      })\n      this.triggerEvent('update:checkedKeys', checkedKeys)\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/checkbox-tree.json",
          "target": "components/ui/checkbox-tree.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        }
      ],
      "dependencies": [
        "@timui/core"
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core"
            ]
          },
          "vue": {},
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "collapsible",
      "type": "registry:ui",
      "dependencies": [
        "@timui/core",
        "@zag-js/react"
      ],
      "registryDependencies": [
        "use-machine"
      ],
      "files": [
        {
          "path": "registry/default/ui/collapsible.tsx",
          "type": "registry:ui",
          "target": "components/ui/collapsible.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport { cn, collapsibleConnect, collapsibleMachine } from '@timui/core'\nimport { mergeProps } from '@zag-js/react'\n\nimport { useCollapsible } from './collapsible/use-collapsible'\nimport { CollapsibleProvider, useCollapsibleContext } from './collapsible/use-collapsible-context'\nimport { Slot } from './slot'\n\n// Context is imported from ./collapsible/use-collapsible-context\n\nconst Collapsible = React.forwardRef<\n  HTMLDivElement,\n  React.HTMLAttributes<HTMLDivElement> & {\n    open?: boolean\n    defaultOpen?: boolean\n    onOpenChange?: (open: boolean) => void\n    disabled?: boolean\n  }\n>(({ className, ...props }, ref) => {\n  const api = useCollapsible(props)\n\n  const rootProps = api.getRootProps()\n  const mergedProps = mergeProps(rootProps, props) as React.HTMLAttributes<HTMLDivElement>\n  const { className: mergedClassName, ...restProps } = mergedProps\n\n  return (\n    <CollapsibleProvider value={api}>\n      <div\n        ref={ref}\n        data-slot=\"collapsible\"\n        className={cn(className, mergedClassName)}\n        {...restProps}\n      />\n    </CollapsibleProvider>\n  )\n})\nCollapsible.displayName = 'Collapsible'\n\nconst CollapsibleTrigger = React.forwardRef<\n  HTMLButtonElement,\n  React.ButtonHTMLAttributes<HTMLButtonElement> & { asChild?: boolean }\n>(({ className, asChild = false, ...props }, ref) => {\n  const api = useCollapsibleContext()\n  const Comp = asChild ? Slot : 'button'\n  const triggerProps = api.getTriggerProps()\n\n  return (\n    <Comp\n      ref={ref}\n      data-slot=\"collapsible-trigger\"\n      {...mergeProps(triggerProps, props)}\n      className={cn(className)}\n    />\n  )\n})\nCollapsibleTrigger.displayName = 'CollapsibleTrigger'\n\nconst CollapsibleContent = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, children, ...props }, ref) => {\n    const api = useCollapsibleContext()\n    const contentProps = api.getContentProps()\n    const mergedProps = mergeProps(contentProps, props)\n    const { className: mergedClassName, ...restProps } = mergedProps\n\n    return (\n      <div\n        ref={ref}\n        data-slot=\"collapsible-content\"\n        className={cn('overflow-hidden', className, mergedClassName)}\n        {...restProps}\n      >\n        {children}\n      </div>\n    )\n  }\n)\nCollapsibleContent.displayName = 'CollapsibleContent'\n\nexport { Collapsible, CollapsibleContent, CollapsibleTrigger }\n"
        },
        {
          "path": "registry/default/ui/collapsible/use-collapsible-context.ts",
          "target": "components/ui/collapsible/use-collapsible-context.ts",
          "type": "registry:ui",
          "content": "import * as React from 'react'\nimport type { collapsibleConnect } from '@timui/core'\n\nexport type CollapsibleContextValue = ReturnType<typeof collapsibleConnect>\n\nconst CollapsibleContext = React.createContext<CollapsibleContextValue | null>(null)\n\nexport const CollapsibleProvider: React.Provider<CollapsibleContextValue | null> =\n  CollapsibleContext.Provider\n\nexport function useCollapsibleContext(): CollapsibleContextValue {\n  const context = React.useContext(CollapsibleContext)\n  if (!context) {\n    throw new Error('Collapsible components must be used within `<CollapsibleProvider />`')\n  }\n  return context\n}\n"
        },
        {
          "path": "registry/default/ui/collapsible/use-collapsible.ts",
          "target": "components/ui/collapsible/use-collapsible.ts",
          "type": "registry:ui",
          "content": "import * as React from 'react'\nimport { collapsibleConnect, collapsibleMachine } from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/react'\n\nexport interface UseCollapsibleProps {\n  id?: string\n  open?: boolean\n  defaultOpen?: boolean\n  onOpenChange?: (open: boolean) => void\n  disabled?: boolean\n}\n\nexport function useCollapsible(props: UseCollapsibleProps) {\n  const generatedId = React.useId()\n  const service = useMachine(collapsibleMachine, {\n    id: props.id ?? generatedId,\n    open: props.open,\n    defaultOpen: props.defaultOpen,\n    disabled: props.disabled,\n    onOpenChange(details) {\n      props.onOpenChange?.(details.open)\n    },\n  })\n\n  return React.useMemo(() => collapsibleConnect(service, normalizeProps), [service])\n}\n"
        },
        {
          "path": "registry/default/vue/collapsible/collapsible-content.vue",
          "target": "components/ui/collapsible/collapsible-content.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, inject, type HTMLAttributes } from 'vue'\nimport { cn } from '@timui/core'\n\nconst props = defineProps<{ class?: HTMLAttributes['class'] }>()\ntype BindValue = string | number | boolean | null | undefined | ((...args: never[]) => void)\ntype CollapsibleApi = {\n  open?: boolean\n  getContentProps?: () => Record<string, BindValue>\n}\nconst context = inject('collapsible') as { api: CollapsibleApi } | null\nconst isOpen = computed(() => context?.api.open ?? false)\nconst contentProps = computed(() => context?.api.getContentProps?.() ?? {})\n</script>\n\n<template>\n  <div\n    v-bind=\"contentProps\"\n    data-slot=\"collapsible-content\"\n    :data-state=\"isOpen ? 'open' : 'closed'\"\n    :class=\"cn('overflow-hidden', props.class)\"\n  >\n    <slot v-if=\"isOpen\" />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/collapsible/collapsible-trigger.vue",
          "target": "components/ui/collapsible/collapsible-trigger.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, inject, type Component, type HTMLAttributes } from 'vue'\nimport { cn } from '@timui/core'\nimport { Primitive } from '../../primitive'\n\nconst props = withDefaults(\n  defineProps<{\n    as?: string | Component\n    asChild?: boolean\n    class?: HTMLAttributes['class']\n  }>(),\n  {\n    as: 'button',\n  },\n)\n\ntype BindValue = string | number | boolean | null | undefined | ((...args: never[]) => void)\ntype CollapsibleApi = {\n  getTriggerProps?: () => Record<string, BindValue>\n}\nconst context = inject('collapsible') as { api: CollapsibleApi } | null\nconst triggerProps = computed(() => context?.api.getTriggerProps?.() ?? {})\n</script>\n\n<template>\n  <Primitive\n    :as=\"props.as\"\n    :as-child=\"props.asChild\"\n    v-bind=\"triggerProps\"\n    data-slot=\"collapsible-trigger\"\n    type=\"button\"\n    :class=\"cn(props.class)\"\n  >\n    <slot />\n  </Primitive>\n</template>\n"
        },
        {
          "path": "registry/default/vue/collapsible/collapsible.vue",
          "target": "components/ui/collapsible/collapsible.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes } from 'vue'\nimport { useCollapsible } from './use-collapsible'\nimport { provideCollapsibleContext } from './use-collapsible-context'\n\nconst props = defineProps<{\n  open?: boolean\n  defaultOpen?: boolean\n  disabled?: boolean\n  id?: string\n  onOpenChange?: (open: boolean) => void\n  class?: HTMLAttributes['class']\n}>()\n\nconst emit = defineEmits(['update:open', 'change'])\n\nconst api = useCollapsible({\n  id: props.id,\n  open: props.open,\n  defaultOpen: props.open === undefined ? props.defaultOpen : undefined,\n  disabled: props.disabled,\n  onOpenChange(open: boolean) {\n    props.onOpenChange?.(open)\n    emit('update:open', open)\n    emit('change', open)\n  },\n})\n\nprovideCollapsibleContext(api)\n</script>\n\n<template>\n  <div\n    v-bind=\"api.getRootProps()\"\n    :class=\"props.class\"\n  >\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/collapsible/use-collapsible-context.ts",
          "target": "components/ui/collapsible/use-collapsible-context.ts",
          "type": "registry:component",
          "content": "import type { CollapsibleApi } from '@timui/core'\nimport { inject, provide, type ComputedRef } from 'vue'\n\nexport const CollapsibleContextKey = Symbol('CollapsibleContext')\n\nexport function provideCollapsibleContext(api: ComputedRef<CollapsibleApi>) {\n  provide(CollapsibleContextKey, api)\n}\n\nexport function useCollapsibleContext(): ComputedRef<CollapsibleApi> {\n  const context = inject<ComputedRef<CollapsibleApi>>(CollapsibleContextKey)\n  if (!context) {\n    throw new Error('useCollapsibleContext must be used within a CollapsibleProvider')\n  }\n  return context\n}\n"
        },
        {
          "path": "registry/default/vue/collapsible/use-collapsible.ts",
          "target": "components/ui/collapsible/use-collapsible.ts",
          "type": "registry:component",
          "content": "import { collapsibleConnect, collapsibleMachine } from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/vue'\nimport { computed, useId } from 'vue'\n\ntype CollapsibleProps = {\n  id?: string\n  open?: boolean\n  defaultOpen?: boolean\n  disabled?: boolean\n  onOpenChange?: (open: boolean) => void\n}\n\nexport function useCollapsible(props: CollapsibleProps = {}) {\n  const generatedId = useId()\n\n  const service = useMachine(collapsibleMachine, {\n    id: props.id ?? generatedId,\n    open: props.open,\n    defaultOpen: props.defaultOpen,\n    disabled: props.disabled,\n    onOpenChange(details) {\n      props.onOpenChange?.(details.open)\n    },\n  })\n\n  return computed(() => collapsibleConnect(service, normalizeProps))\n}\n"
        },
        {
          "path": "registry/default/html/collapsible.html",
          "target": "components/ui/collapsible.html",
          "type": "registry:component",
          "content": "<div data-timui-root data-timui-init=\"auto\">\n  <details data-slot=\"collapsible\" class=\"p-3\">\n    <summary class=\"font-medium\">Project Details</summary>\n    <p class=\"text-muted-foreground text-sm\">\n      This section can be expanded and collapsed.\n    </p>\n  </details>\n</div>\n<script type=\"module\">\n  import { autoInitHtmlRuntime } from '@timui/html'\n  autoInitHtmlRuntime({ components: ['collapsible'] })\n</script>"
        },
        {
          "path": "registry/default/weapp/collapsible.wxml",
          "target": "components/ui/collapsible.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\" data-state=\"{{api.open ? 'open' : 'closed'}}\">\n  <!-- Trigger -->\n  <view \n    id=\"{{api.triggerProps.id}}\"\n    class=\"collapsible-trigger\"\n    bindtap=\"onTriggerTap\"\n    data-state=\"{{api.open ? 'open' : 'closed'}}\"\n    data-disabled=\"{{disabled}}\"\n  >\n    <slot name=\"trigger\"></slot>\n    <text class=\"collapsible-icon\">{{api.open ? '▼' : '▶'}}</text>\n  </view>\n\n  <!-- Content -->\n  <view \n    id=\"{{api.contentProps.id}}\"\n    class=\"collapsible-content\"\n    data-state=\"{{api.open ? 'open' : 'closed'}}\"\n    hidden=\"{{!api.open}}\"\n  >\n    <slot name=\"content\"></slot>\n  </view>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/collapsible.wxss",
          "target": "components/ui/collapsible.wxss",
          "type": "registry:component",
          "content": "/* weapp component styles */\n"
        },
        {
          "path": "registry/default/weapp/collapsible.ts",
          "target": "components/ui/collapsible.ts",
          "type": "registry:component",
          "content": "import { emitTimEvent } from '../utils'\nimport { setupCollapsibleMachine } from './use-collapsible'\n\ntype MachineEvent =\n  | string\n  | {\n      type: string\n      [key: string]: string | number | boolean | string[] | number[] | null | undefined\n    }\n\ntype WeappCollapsibleApi = {\n  open?: () => void\n  close?: () => void\n  triggerProps?: {\n    onClick?: () => void\n  }\n}\n\ntype WeappService = {\n  setContext: (context: { open?: boolean; disabled?: boolean }) => void\n}\n\ntype WeappCollapsibleInternal =\n  WechatMiniprogram.Component.InstanceMethods<WechatMiniprogram.IAnyObject> & {\n    _service?: WeappService\n    _cleanup?: () => void\n    _send?: (event: MachineEvent) => void\n    data: {\n      api: WeappCollapsibleApi\n    }\n    properties: {\n      open: boolean\n      disabled: boolean\n      id: string\n      extClass: string\n    }\n  }\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    open: { type: Boolean, value: false },\n    disabled: { type: Boolean, value: false },\n    id: { type: String, value: 'collapsible' },\n    extClass: { type: String, value: '' },\n  },\n\n  data: {\n    api: {} as WeappCollapsibleApi,\n    className: '',\n  },\n\n  lifetimes: {\n    attached() {\n      const self = this as WeappCollapsibleInternal\n      const { service, cleanup, send } = setupCollapsibleMachine(this, {\n        id: this.properties.id,\n        open: this.properties.open,\n        disabled: this.properties.disabled,\n        onOpenChange: (details) => {\n          emitTimEvent(this, 'change', 'change', this.properties.id || 'collapsible', {\n            open: details.open,\n          })\n        },\n      })\n\n      self._service = service as WeappService\n      self._cleanup = cleanup\n      self._send = send as (event: MachineEvent) => void\n    },\n    detached() {\n      const self = this as WeappCollapsibleInternal\n      self._cleanup?.()\n    },\n  },\n\n  observers: {\n    state: function (state) {\n      const self = this as WeappCollapsibleInternal\n      if (!state || !self._send) return\n      const { connect } = setupCollapsibleMachine(this, { id: this.properties.id })\n      const api = connect(state, self._send) as WeappCollapsibleApi\n      this.setData({ api, className: this.properties.extClass })\n    },\n\n    open: function (val) {\n      const self = this as WeappCollapsibleInternal\n      if (self._service) {\n        if (val) {\n          self.data.api.open?.()\n        } else {\n          self.data.api.close?.()\n        }\n      }\n    },\n  },\n\n  methods: {\n    onTriggerTap() {\n      const self = this as WeappCollapsibleInternal\n      self.data.api.triggerProps?.onClick?.()\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/collapsible.json",
          "target": "components/ui/collapsible.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        }
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@zag-js/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@zag-js/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "command",
      "type": "registry:ui",
      "dependencies": [
        "@timui/core"
      ],
      "registryDependencies": [
        "dialog"
      ],
      "optionalPeerDependencies": [
        "cmdk",
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/ui/command.tsx",
          "type": "registry:ui",
          "target": "components/ui/command.tsx",
          "content": "'use client'\nimport * as React from 'react'\nimport {\n  cn,\n  commandDialogContentVariants,\n  commandDialogVariants,\n  commandEmptyVariants,\n  commandGroupVariants,\n  commandInputVariants,\n  commandInputWrapperVariants,\n  commandItemVariants,\n  commandListVariants,\n  commandSeparatorVariants,\n  commandShortcutVariants,\n  commandVariants,\n} from '@timui/core'\nimport { Command as CommandPrimitive } from 'cmdk'\nimport { SearchIcon } from 'lucide-react'\n\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from './dialog'\n\nfunction Command({ className, ...props }: React.ComponentProps<typeof CommandPrimitive>) {\n  return (\n    <CommandPrimitive data-slot=\"command\" className={cn(commandVariants(), className)} {...props} />\n  )\n}\n\nfunction CommandDialog({\n  title = 'Command Palette',\n  description = 'Search for a command to run...',\n  children,\n  ...props\n}: React.ComponentProps<typeof Dialog> & {\n  title?: string\n  description?: string\n}) {\n  return (\n    <Dialog {...props}>\n      <DialogHeader className=\"sr-only\">\n        <DialogTitle>{title}</DialogTitle>\n        <DialogDescription>{description}</DialogDescription>\n      </DialogHeader>\n      <DialogContent className={commandDialogContentVariants()}>\n        <Command className={commandDialogVariants()}>{children}</Command>\n      </DialogContent>\n    </Dialog>\n  )\n}\n\nfunction CommandInput({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Input>) {\n  return (\n    <div className={commandInputWrapperVariants()} cmdk-input-wrapper=\"\">\n      <SearchIcon size={20} className=\"text-muted-foreground/80 me-3\" />\n      <CommandPrimitive.Input\n        data-slot=\"command-input-wrapper\"\n        className={cn(commandInputVariants(), className)}\n        {...props}\n      />\n    </div>\n  )\n}\n\nfunction CommandList({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.List>) {\n  return (\n    <CommandPrimitive.List\n      data-slot=\"command-list\"\n      className={cn(commandListVariants(), className)}\n      {...props}\n    />\n  )\n}\n\nfunction CommandEmpty({ ...props }: React.ComponentProps<typeof CommandPrimitive.Empty>) {\n  return (\n    <CommandPrimitive.Empty\n      data-slot=\"command-empty\"\n      className={commandEmptyVariants()}\n      {...props}\n    />\n  )\n}\n\nfunction CommandGroup({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Group>) {\n  return (\n    <CommandPrimitive.Group\n      data-slot=\"command-group\"\n      className={cn(commandGroupVariants(), className)}\n      {...props}\n    />\n  )\n}\n\nfunction CommandSeparator({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Separator>) {\n  return (\n    <CommandPrimitive.Separator\n      data-slot=\"command-separator\"\n      className={cn(commandSeparatorVariants(), className)}\n      {...props}\n    />\n  )\n}\n\nfunction CommandItem({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Item>) {\n  return (\n    <CommandPrimitive.Item\n      data-slot=\"command-item\"\n      className={cn(commandItemVariants(), className)}\n      {...props}\n    />\n  )\n}\n\nfunction CommandShortcut({ className, ...props }: React.ComponentProps<'span'>) {\n  return (\n    <kbd\n      data-slot=\"command-shortcut\"\n      className={cn(commandShortcutVariants(), className)}\n      {...props}\n    />\n  )\n}\n\nexport {\n  Command,\n  CommandDialog,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandItem,\n  CommandList,\n  CommandSeparator,\n  CommandShortcut,\n}\n"
        },
        {
          "path": "registry/default/vue/command/command-dialog.vue",
          "target": "components/ui/command/command-dialog.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport Dialog from \"../dialog/dialog.vue\";\nimport DialogContent from \"../dialog/dialog-content.vue\";\nimport Command from \"./command.vue\";\nimport { cn, commandDialogContentVariants, commandDialogVariants } from \"@timui/core\";\n\nconst props = defineProps<{ open?: boolean; defaultOpen?: boolean }>();\nconst emit = defineEmits([\"update:open\", \"openChange\"]);\n</script>\n\n<template>\n  <Dialog :open=\"props.open\" :defaultOpen=\"props.defaultOpen\" @update:open=\"emit('update:open', $event)\" @openChange=\"emit('openChange', $event)\">\n    <DialogContent :class=\"cn(commandDialogContentVariants(), 'shadow-lg')\">\n      <Command :class=\"commandDialogVariants()\">\n        <slot />\n      </Command>\n    </DialogContent>\n  </Dialog>\n</template>\n"
        },
        {
          "path": "registry/default/vue/command/command-empty.vue",
          "target": "components/ui/command/command-empty.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, commandEmptyVariants } from \"@timui/core\";\nimport type { HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\n</script>\n\n<template>\n  <div :class=\"cn(commandEmptyVariants(), props.class)\">\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/command/command-group.vue",
          "target": "components/ui/command/command-group.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, commandGroupVariants } from \"@timui/core\";\nimport type { HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\n</script>\n\n<template>\n  <div\n    :class=\"\n      cn(\n        commandGroupVariants(),\n        props.class\n      )\n    \"\n  >\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/command/command-input.vue",
          "target": "components/ui/command/command-input.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, ref, type ComputedRef } from \"vue\";\nimport { useCommandContext } from \"./use-command-context\";\nimport { SearchIcon } from \"lucide-vue-next\";\nimport { cn, commandInputVariants, commandInputWrapperVariants } from \"@timui/core\";\nimport type { HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{\n  class?: HTMLAttributes[\"class\"];\n  onValueChange?: (value: string) => void;\n  listId?: string;\n  expanded?: boolean;\n}>();\ntype BindValue = string | number | boolean | null | undefined | ((event: Event) => void);\nconst context = useCommandContext();\nconst inputProps = computed(() => context?.api.value?.getInputProps?.() || {});\nconst inputEl = ref<HTMLInputElement | null>(null);\n\nconst onInput = (event: Event) => {\n  const target = event.target as HTMLInputElement;\n  const onInputHandler = inputProps.value.onInput as ((event: Event) => void) | undefined;\n  const onChangeHandler = inputProps.value.onChange as ((event: Event) => void) | undefined;\n  if (typeof onInputHandler === \"function\") onInputHandler(event);\n  if (typeof onChangeHandler === \"function\") onChangeHandler(event);\n  props.onValueChange?.(target.value);\n};\n\ndefineExpose({\n  inputEl,\n});\n</script>\n\n<template>\n  <div :class=\"commandInputWrapperVariants()\" cmdk-input-wrapper>\n    <SearchIcon class=\"mr-2 h-4 w-4 shrink-0 opacity-50\" />\n    <input\n      v-bind=\"inputProps\"\n      ref=\"inputEl\"\n      :aria-controls=\"props.listId\"\n      :aria-expanded=\"props.expanded\"\n      :class=\"\n        cn(\n          commandInputVariants(),\n          props.class\n        )\n      \"\n      @input=\"onInput\"\n    />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/command/command-item.vue",
          "target": "components/ui/command/command-item.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, onMounted, type ComputedRef } from \"vue\";\nimport { useCommandContext } from \"./use-command-context\";\nimport { cn, commandItemVariants } from \"@timui/core\";\nimport type { HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{\n  value: string;\n  label?: string;\n  class?: HTMLAttributes[\"class\"];\n  onSelect?: (value: string) => void;\n}>();\n\nconst emit = defineEmits<{\n  (e: \"select\", value: string): void;\n}>();\n\nconst context = useCommandContext();\nconst item = computed(() => ({\n  label: props.label ?? props.value,\n  value: props.value,\n}));\n\nonMounted(() => {\n  context?.registerItem?.(item.value);\n});\n\nonBeforeUnmount(() => {\n  context?.unregisterItem?.(props.value);\n});\n\nconst handleSelect = () => {\n  props.onSelect?.(props.value);\n  emit(\"select\", props.value);\n};\n</script>\n\n<template>\n  <div\n    v-bind=\"context?.api.value?.getItemProps?.({ item })\"\n    @click=\"handleSelect\"\n    @keydown.enter=\"handleSelect\"\n    :class=\"\n      cn(\n        commandItemVariants(),\n        props.class\n      )\n    \"\n  >\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/command/command-list.vue",
          "target": "components/ui/command/command-list.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, type ComputedRef } from \"vue\";\nimport { useCommandContext } from \"./use-command-context\";\nimport { cn, commandListVariants } from \"@timui/core\";\nimport type { HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\nconst context = useCommandContext();\nconst contentProps = computed(() => context?.api.value?.getContentProps?.() || {});\n</script>\n\n<template>\n  <div v-bind=\"contentProps\" :class=\"cn(commandListVariants(), props.class)\">\n    <div role=\"presentation\">\n      <slot />\n    </div>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/command/command-separator.vue",
          "target": "components/ui/command/command-separator.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, commandSeparatorVariants } from \"@timui/core\";\nimport type { HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\n</script>\n\n<template>\n  <div :class=\"cn(commandSeparatorVariants(), props.class)\">\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/command/command-shortcut.vue",
          "target": "components/ui/command/command-shortcut.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes } from 'vue'\nimport { cn, commandShortcutVariants } from '@timui/core'\n\nconst props = defineProps<{\n  class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n  <span\n    :class=\"\n      cn(\n        commandShortcutVariants(),\n        props.class\n      )\n    \"\n  >\n    <slot />\n  </span>\n</template>\n"
        },
        {
          "path": "registry/default/vue/command/command.vue",
          "target": "components/ui/command/command.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from \"vue\";\nimport { cn, commandVariants } from \"@timui/core\";\nimport { useCommand, type UseCommandProps } from \"./use-command\";\nimport { provideCommandContext } from \"./use-command-context\";\n\nconst props = defineProps<UseCommandProps>();\nconst emit = defineEmits<{\n  (e: \"update:value\", value?: string): void;\n  (e: \"update:modelValue\", value?: string): void;\n  (e: \"change\", value?: string): void;\n}>();\n\nconst { api, registerItem, unregisterItem } = useCommand(props, emit);\nprovideCommandContext({ api, registerItem, unregisterItem });\n\nconst rootEl = ref<HTMLElement | null>(null);\n\ndefineExpose({\n  rootEl,\n  api,\n});\n</script>\n\n<template>\n  <div\n    :class=\"\n      cn(\n        commandVariants(),\n        props.class\n      )\n    \"\n    v-bind=\"api?.getRootProps?.()\"\n    ref=\"rootEl\"\n  >\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/command/index.ts",
          "target": "components/ui/command/index.ts",
          "type": "registry:component",
          "content": "export { default } from './command.vue'\nexport { default as CommandDialog } from './command-dialog.vue'\nexport { default as CommandEmpty } from './command-empty.vue'\nexport { default as CommandGroup } from './command-group.vue'\nexport { default as CommandInput } from './command-input.vue'\nexport { default as CommandItem } from './command-item.vue'\nexport { default as CommandList } from './command-list.vue'\nexport { default as CommandSeparator } from './command-separator.vue'\nexport { default as CommandShortcut } from './command-shortcut.vue'\nexport { default as Command } from './command.vue'\n"
        },
        {
          "path": "registry/default/vue/command/use-command-context.ts",
          "target": "components/ui/command/use-command-context.ts",
          "type": "registry:component",
          "content": "import type { ComboboxApi } from '@timui/core'\nimport { type PropTypes } from '@zag-js/vue'\nimport { inject, provide, type ComputedRef } from 'vue'\n\nimport type { CommandItem } from './use-command'\n\nexport interface CommandContext {\n  api: ComputedRef<ComboboxApi<PropTypes>>\n  registerItem: (item: CommandItem) => void\n  unregisterItem: (value: string) => void\n}\n\nconst CommandContextKey = Symbol('CommandContext')\n\nexport function provideCommandContext(context: CommandContext) {\n  provide(CommandContextKey, context)\n}\n\nexport function useCommandContext() {\n  const context = inject<CommandContext>(CommandContextKey)\n  if (!context) {\n    throw new Error('useCommandContext must be used within a CommandProvider')\n  }\n  return context\n}\n"
        },
        {
          "path": "registry/default/vue/command/use-command.ts",
          "target": "components/ui/command/use-command.ts",
          "type": "registry:component",
          "content": "import { comboboxCollection, comboboxConnect, comboboxMachine } from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/vue'\nimport { computed, ref, useId, watch } from 'vue'\nimport type { HTMLAttributes } from 'vue'\n\nexport type CommandItem = { value: string; label: string }\n\nexport interface UseCommandProps {\n  class?: HTMLAttributes['class']\n  value?: string\n  modelValue?: string\n  defaultValue?: string\n  id?: string\n  onValueChange?: (value?: string) => void\n}\n\nexport interface UseCommandEmits {\n  (e: 'update:value', value?: string): void\n  (e: 'update:modelValue', value?: string): void\n  (e: 'change', value?: string): void\n}\n\nexport function useCommand(props: UseCommandProps, emit: UseCommandEmits) {\n  const generatedId = useId()\n  const options = ref<CommandItem[]>([])\n  const registerItem = (item: CommandItem) => {\n    if (options.value.find((opt) => opt.value === item.value)) return\n    options.value.push(item)\n  }\n  const unregisterItem = (value: string) => {\n    const index = options.value.findIndex((opt) => opt.value === value)\n    if (index >= 0) options.value.splice(index, 1)\n  }\n\n  const collection = comboboxCollection({\n    items: options.value,\n    itemToString: (item) => item.label,\n    itemToValue: (item) => item.value,\n  })\n\n  const currentValue = computed(() => props.value ?? props.modelValue)\n\n  const service = useMachine(comboboxMachine, {\n    id: props.id ?? generatedId,\n    collection,\n    value: currentValue.value !== undefined ? [currentValue.value] : undefined,\n    defaultValue:\n      props.value === undefined && props.modelValue === undefined && props.defaultValue\n        ? [props.defaultValue]\n        : undefined,\n    onValueChange(details: { value: string[] }) {\n      const nextValue = details.value?.[0]\n      props.onValueChange?.(nextValue)\n      emit('update:value', nextValue)\n      emit('update:modelValue', nextValue)\n      emit('change', nextValue)\n    },\n    inputBehavior: 'autohighlight',\n    open: true,\n  })\n\n  const api = computed(() => comboboxConnect(service, normalizeProps))\n\n  watch(\n    () => props.value ?? props.modelValue,\n    (val) => {\n      if (val !== undefined && val !== api.value?.value?.[0]) {\n        api.value?.setValue([val])\n      }\n    }\n  )\n\n  return {\n    api,\n    registerItem,\n    unregisterItem,\n  }\n}\n"
        },
        {
          "path": "registry/default/html/command.html",
          "target": "components/ui/command.html",
          "type": "registry:component",
          "content": "<div data-slot=\"command\" class=\"rounded-lg border border-input bg-background p-2\">\n  <input\n    type=\"text\"\n    placeholder=\"Type a command...\"\n    class=\"flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none disabled:cursor-not-allowed disabled:opacity-50\"\n  />\n  <div class=\"mt-2 rounded-md bg-muted/40 p-1 text-sm\">\n    <button type=\"button\" class=\"border-input flex items-center border-b px-5\">\n      <span>Open Settings</span>\n      <span class=\"text-xs text-muted-foreground\">⌘S</span>\n    </button>\n    <button type=\"button\" class=\"border-input flex items-center border-b px-5\">\n      <span>Create Project</span>\n      <span class=\"text-xs text-muted-foreground\">⌘P</span>\n    </button>\n  </div>\n</div>"
        },
        {
          "path": "registry/default/weapp/command.wxml",
          "target": "components/ui/command.wxml",
          "type": "registry:component",
          "content": "<view class=\"command {{extClass}}\">\n  <input\n    class=\"command-input\"\n    type=\"text\"\n    placeholder=\"{{placeholder}}\"\n    value=\"{{query}}\"\n    bindinput=\"onInput\"\n  />\n\n  <view wx:if=\"{{filteredItems.length === 0}}\" class=\"command-empty\">\n    No results.\n  </view>\n\n  <view wx:else class=\"command-list\">\n    <view\n      wx:for=\"{{filteredItems}}\"\n      wx:key=\"value\"\n      class=\"command-item {{item.disabled ? 'is-disabled' : ''}}\"\n      data-value=\"{{item.value}}\"\n      bindtap=\"onSelect\"\n    >\n      <text class=\"command-item-label\">{{item.label}}</text>\n      <text class=\"command-item-value\">{{item.value}}</text>\n    </view>\n  </view>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/command.wxss",
          "target": "components/ui/command.wxss",
          "type": "registry:component",
          "content": ".command {\n  display: flex;\n  flex-direction: column;\n  gap: 12rpx;\n  border: 1px solid #e5e7eb;\n  border-radius: 12rpx;\n  padding: 16rpx;\n  background: #ffffff;\n}\n\n.command-input {\n  border: 1px solid #d1d5db;\n  border-radius: 8rpx;\n  padding: 12rpx;\n  font-size: 28rpx;\n}\n\n.command-empty {\n  color: #6b7280;\n  font-size: 26rpx;\n}\n\n.command-list {\n  display: flex;\n  flex-direction: column;\n  gap: 8rpx;\n}\n\n.command-item {\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  padding: 12rpx;\n  border-radius: 8rpx;\n  background: #f9fafb;\n}\n\n.command-item-value {\n  color: #6b7280;\n  font-size: 24rpx;\n}\n\n.is-disabled {\n  opacity: 0.5;\n}\n"
        },
        {
          "path": "registry/default/weapp/command.ts",
          "target": "components/ui/command.ts",
          "type": "registry:component",
          "content": "import { emitTimEvent } from '../utils'\n\ntype CommandItem = {\n  label: string\n  value: string\n  keywords?: string\n  disabled?: boolean\n}\n\nconst normalize = (value: object) => String(value ?? '').toLowerCase()\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    items: {\n      type: Array,\n      value: [],\n    },\n    placeholder: {\n      type: String,\n      value: 'Type a command...',\n    },\n    id: {\n      type: String,\n      value: 'command',\n    },\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n\n  data: {\n    query: '',\n    filteredItems: [] as CommandItem[],\n  },\n\n  lifetimes: {\n    attached() {\n      this.filterItems('')\n    },\n  },\n\n  observers: {\n    items() {\n      this.filterItems(this.data.query || '')\n    },\n  },\n\n  methods: {\n    filterItems(query: string) {\n      const source = (this.properties.items || []) as CommandItem[]\n      const q = normalize(query).trim()\n      if (!q) {\n        this.setData({ filteredItems: source })\n        return\n      }\n      const filtered = source.filter((item) => {\n        const haystack = `${item.label} ${item.value} ${item.keywords || ''}`.toLowerCase()\n        return haystack.includes(q)\n      })\n      this.setData({ filteredItems: filtered })\n    },\n\n    onInput(e: WechatMiniprogram.Input) {\n      const query = String(e.detail.value || '')\n      this.setData({ query })\n      this.filterItems(query)\n    },\n\n    onSelect(e: WechatMiniprogram.BaseEvent) {\n      const value = String(e.currentTarget.dataset.value || '')\n      const item = (this.data.filteredItems || []).find((entry) => entry.value === value)\n      if (!item || item.disabled) return\n      this.triggerEvent('select', item)\n      emitTimEvent(this, 'change', 'change', this.properties.id || 'command', item)\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/command.json",
          "target": "components/ui/command.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        }
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core"
            ],
            "optionalPeerDependencies": [
              "cmdk",
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@zag-js/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "cropper",
      "type": "registry:ui",
      "dependencies": [
        "@timui/core"
      ],
      "optionalPeerDependencies": [
        "@origin-space/image-cropper"
      ],
      "files": [
        {
          "path": "registry/default/ui/cropper.tsx",
          "type": "registry:ui",
          "target": "components/ui/cropper.tsx",
          "content": "'use client'\nimport { Cropper as CropperPrimitive } from '@origin-space/image-cropper'\nimport {\n  cn,\n  cropperCropAreaVariants,\n  cropperDescriptionVariants,\n  cropperImageVariants,\n  cropperRootVariants,\n} from '@timui/core'\n\nfunction Cropper({ className, ...props }: React.ComponentProps<typeof CropperPrimitive.Root>) {\n  return (\n    <CropperPrimitive.Root\n      data-slot=\"cropper\"\n      className={cn(cropperRootVariants(), className)}\n      {...props}\n    />\n  )\n}\n\nfunction CropperDescription({\n  className,\n  ...props\n}: React.ComponentProps<typeof CropperPrimitive.Description>) {\n  return (\n    <CropperPrimitive.Description\n      data-slot=\"cropper-description\"\n      className={cn(cropperDescriptionVariants(), className)}\n      {...props}\n    />\n  )\n}\n\nfunction CropperImage({\n  className,\n  ...props\n}: React.ComponentProps<typeof CropperPrimitive.Image>) {\n  return (\n    <CropperPrimitive.Image\n      data-slot=\"cropper-image\"\n      className={cn(cropperImageVariants(), className)}\n      {...props}\n    />\n  )\n}\n\nfunction CropperCropArea({\n  className,\n  ...props\n}: React.ComponentProps<typeof CropperPrimitive.CropArea>) {\n  return (\n    <CropperPrimitive.CropArea\n      data-slot=\"cropper-crop-area\"\n      className={cn(cropperCropAreaVariants(), className)}\n      {...props}\n    />\n  )\n}\n\nexport { Cropper, CropperDescription, CropperImage, CropperCropArea }\n"
        },
        {
          "path": "registry/default/vue/cropper/cropper.vue",
          "target": "components/ui/cropper/cropper.vue",
          "type": "registry:component",
          "content": "<script lang=\"ts\">\nimport { cn, cropperCropAreaVariants, cropperDescriptionVariants, cropperImageVariants, cropperRootVariants } from \"@timui/core\";\nimport {\n  computed,\n  defineComponent,\n  h,\n  inject,\n  mergeProps,\n  onBeforeUnmount,\n  onMounted,\n  provide,\n  ref,\n  watch,\n  type ComputedRef,\n  type CSSProperties,\n  type PropType,\n} from \"vue\";\n\ntype CropArea = {\n  x: number;\n  y: number;\n  width: number;\n  height: number;\n};\n\ntype CropperContextValue = {\n  image: ComputedRef<string | undefined>;\n  imageStyle: ComputedRef<CSSProperties>;\n  cropAreaStyle: ComputedRef<CSSProperties>;\n  setNaturalSize: (width: number, height: number) => void;\n};\n\nconst cropperContextKey = Symbol(\"timui.cropper\");\n\nconst clamp = (value: number, min: number, max: number) => {\n  if (value < min) return min;\n  if (value > max) return max;\n  return value;\n};\n\nexport const Cropper = defineComponent({\n  name: \"Cropper\",\n  inheritAttrs: false,\n  emits: [\"cropChange\", \"zoomChange\"],\n  props: {\n    class: {\n      type: String,\n      default: undefined,\n    },\n    image: {\n      type: String,\n      default: undefined,\n    },\n    zoom: {\n      type: Number,\n      default: undefined,\n    },\n    minZoom: {\n      type: Number,\n      default: 1,\n    },\n    maxZoom: {\n      type: Number,\n      default: 3,\n    },\n    aspectRatio: {\n      type: Number,\n      default: undefined,\n    },\n    cropPadding: {\n      type: Number,\n      default: 16,\n    },\n    onCropChange: {\n      type: Function as PropType<(area: CropArea | null) => void>,\n      default: undefined,\n    },\n    onZoomChange: {\n      type: Function as PropType<(zoom: number) => void>,\n      default: undefined,\n    },\n  },\n  setup(props, { attrs, slots, emit }) {\n    const rootRef = ref<HTMLElement | null>(null);\n    const containerWidth = ref(0);\n    const containerHeight = ref(0);\n    const naturalWidth = ref(0);\n    const naturalHeight = ref(0);\n    const offsetX = ref(0);\n    const offsetY = ref(0);\n    const internalZoom = ref(props.zoom ?? 1);\n\n    let resizeObserver: ResizeObserver | null = null;\n    let dragging = false;\n    let activePointerId: number | null = null;\n    let dragStartX = 0;\n    let dragStartY = 0;\n    let dragOriginX = 0;\n    let dragOriginY = 0;\n\n    const normalizedMinZoom = computed(() => {\n      const min = Number.isFinite(props.minZoom) ? Math.max(props.minZoom, 0.1) : 1;\n      const max = Number.isFinite(props.maxZoom) ? Math.max(props.maxZoom, 0.1) : 3;\n      return Math.min(min, max);\n    });\n\n    const normalizedMaxZoom = computed(() => {\n      const min = Number.isFinite(props.minZoom) ? Math.max(props.minZoom, 0.1) : 1;\n      const max = Number.isFinite(props.maxZoom) ? Math.max(props.maxZoom, 0.1) : 3;\n      return Math.max(min, max);\n    });\n\n    const currentZoom = computed(() => {\n      const value = typeof props.zoom === \"number\" ? props.zoom : internalZoom.value;\n      return clamp(value, normalizedMinZoom.value, normalizedMaxZoom.value);\n    });\n\n    const cropPadding = computed(() => Math.max(props.cropPadding, 0));\n\n    const cropAreaWidth = computed(() => {\n      const availableWidth = Math.max(containerWidth.value - cropPadding.value * 2, 0);\n      const availableHeight = Math.max(containerHeight.value - cropPadding.value * 2, 0);\n      const ratio = props.aspectRatio;\n\n      if (!ratio || ratio <= 0) return availableWidth;\n      if (availableHeight <= 0) return 0;\n\n      const byWidth = availableWidth;\n      const byHeight = availableHeight * ratio;\n      return Math.min(byWidth, byHeight);\n    });\n\n    const cropAreaHeight = computed(() => {\n      const availableWidth = Math.max(containerWidth.value - cropPadding.value * 2, 0);\n      const availableHeight = Math.max(containerHeight.value - cropPadding.value * 2, 0);\n      const ratio = props.aspectRatio;\n\n      if (!ratio || ratio <= 0) return availableHeight;\n      if (availableWidth <= 0) return 0;\n\n      const byWidth = availableWidth / ratio;\n      const byHeight = availableHeight;\n      return Math.min(byWidth, byHeight);\n    });\n\n    const baseScale = computed(() => {\n      if (\n        naturalWidth.value <= 0 ||\n        naturalHeight.value <= 0 ||\n        cropAreaWidth.value <= 0 ||\n        cropAreaHeight.value <= 0\n      ) {\n        return 1;\n      }\n\n      const widthScale = cropAreaWidth.value / naturalWidth.value;\n      const heightScale = cropAreaHeight.value / naturalHeight.value;\n      return Math.max(widthScale, heightScale);\n    });\n\n    const appliedScale = computed(() => baseScale.value * currentZoom.value);\n    const imageWidth = computed(() => naturalWidth.value * appliedScale.value);\n    const imageHeight = computed(() => naturalHeight.value * appliedScale.value);\n\n    const maxOffsetX = computed(() => Math.max((imageWidth.value - cropAreaWidth.value) / 2, 0));\n    const maxOffsetY = computed(() => Math.max((imageHeight.value - cropAreaHeight.value) / 2, 0));\n\n    const clampOffsets = () => {\n      offsetX.value = clamp(offsetX.value, -maxOffsetX.value, maxOffsetX.value);\n      offsetY.value = clamp(offsetY.value, -maxOffsetY.value, maxOffsetY.value);\n    };\n\n    const setZoom = (nextZoom: number) => {\n      const clampedZoom = clamp(nextZoom, normalizedMinZoom.value, normalizedMaxZoom.value);\n      if (typeof props.zoom !== \"number\") {\n        internalZoom.value = clampedZoom;\n      }\n      props.onZoomChange?.(clampedZoom);\n      emit(\"zoomChange\", clampedZoom);\n      clampOffsets();\n    };\n\n    const getCropArea = (): CropArea | null => {\n      if (\n        naturalWidth.value <= 0 ||\n        naturalHeight.value <= 0 ||\n        cropAreaWidth.value <= 0 ||\n        cropAreaHeight.value <= 0 ||\n        appliedScale.value <= 0\n      ) {\n        return null;\n      }\n\n      const sourceWidth = cropAreaWidth.value / appliedScale.value;\n      const sourceHeight = cropAreaHeight.value / appliedScale.value;\n\n      const unclampedX = ((imageWidth.value - cropAreaWidth.value) / 2 - offsetX.value) / appliedScale.value;\n      const unclampedY = ((imageHeight.value - cropAreaHeight.value) / 2 - offsetY.value) / appliedScale.value;\n\n      const maxX = Math.max(naturalWidth.value - sourceWidth, 0);\n      const maxY = Math.max(naturalHeight.value - sourceHeight, 0);\n\n      const x = clamp(unclampedX, 0, maxX);\n      const y = clamp(unclampedY, 0, maxY);\n\n      return {\n        x: Math.round(x),\n        y: Math.round(y),\n        width: Math.round(sourceWidth),\n        height: Math.round(sourceHeight),\n      };\n    };\n\n    const emitCropArea = () => {\n      const area = getCropArea();\n      props.onCropChange?.(area);\n      emit(\"cropChange\", area);\n    };\n\n    const updateContainerSize = () => {\n      const node = rootRef.value;\n      if (!node) return;\n      containerWidth.value = node.clientWidth;\n      containerHeight.value = node.clientHeight;\n      clampOffsets();\n      emitCropArea();\n    };\n\n    const setNaturalSize = (width: number, height: number) => {\n      naturalWidth.value = Math.max(width, 0);\n      naturalHeight.value = Math.max(height, 0);\n      offsetX.value = 0;\n      offsetY.value = 0;\n      clampOffsets();\n      emitCropArea();\n    };\n\n    const stopDragging = () => {\n      dragging = false;\n      activePointerId = null;\n      window.removeEventListener(\"pointermove\", handlePointerMove);\n      window.removeEventListener(\"pointerup\", handlePointerUp);\n      window.removeEventListener(\"pointercancel\", handlePointerUp);\n    };\n\n    const handlePointerMove = (event: PointerEvent) => {\n      if (!dragging || activePointerId !== event.pointerId) return;\n      event.preventDefault();\n      const deltaX = event.clientX - dragStartX;\n      const deltaY = event.clientY - dragStartY;\n      offsetX.value = clamp(dragOriginX + deltaX, -maxOffsetX.value, maxOffsetX.value);\n      offsetY.value = clamp(dragOriginY + deltaY, -maxOffsetY.value, maxOffsetY.value);\n      emitCropArea();\n    };\n\n    const handlePointerUp = (event: PointerEvent) => {\n      if (activePointerId !== event.pointerId) return;\n      stopDragging();\n    };\n\n    const handlePointerDown = (event: PointerEvent) => {\n      if (event.button !== 0 || naturalWidth.value <= 0 || naturalHeight.value <= 0) return;\n      event.preventDefault();\n      dragging = true;\n      activePointerId = event.pointerId;\n      dragStartX = event.clientX;\n      dragStartY = event.clientY;\n      dragOriginX = offsetX.value;\n      dragOriginY = offsetY.value;\n      window.addEventListener(\"pointermove\", handlePointerMove, { passive: false });\n      window.addEventListener(\"pointerup\", handlePointerUp);\n      window.addEventListener(\"pointercancel\", handlePointerUp);\n    };\n\n    const handleWheel = (event: WheelEvent) => {\n      if (naturalWidth.value <= 0 || naturalHeight.value <= 0) return;\n      event.preventDefault();\n      const zoomRange = normalizedMaxZoom.value - normalizedMinZoom.value;\n      const step = Math.max(zoomRange / 40, 0.05);\n      const direction = Math.sign(event.deltaY);\n      const nextZoom = currentZoom.value - direction * step;\n      setZoom(nextZoom);\n    };\n\n    const handleKeyDown = (event: KeyboardEvent) => {\n      if (naturalWidth.value <= 0 || naturalHeight.value <= 0) return;\n      const panStep = 12;\n      let handled = true;\n\n      switch (event.key) {\n        case \"ArrowLeft\":\n          offsetX.value = clamp(offsetX.value - panStep, -maxOffsetX.value, maxOffsetX.value);\n          break;\n        case \"ArrowRight\":\n          offsetX.value = clamp(offsetX.value + panStep, -maxOffsetX.value, maxOffsetX.value);\n          break;\n        case \"ArrowUp\":\n          offsetY.value = clamp(offsetY.value - panStep, -maxOffsetY.value, maxOffsetY.value);\n          break;\n        case \"ArrowDown\":\n          offsetY.value = clamp(offsetY.value + panStep, -maxOffsetY.value, maxOffsetY.value);\n          break;\n        case \"+\":\n        case \"=\":\n          setZoom(currentZoom.value + 0.1);\n          break;\n        case \"-\":\n        case \"_\":\n          setZoom(currentZoom.value - 0.1);\n          break;\n        default:\n          handled = false;\n      }\n\n      if (handled) {\n        event.preventDefault();\n        emitCropArea();\n      }\n    };\n\n    const imageStyle = computed<CSSProperties>(() => ({\n      position: \"absolute\",\n      left: \"50%\",\n      top: \"50%\",\n      width: `${imageWidth.value}px`,\n      height: `${imageHeight.value}px`,\n      transform: `translate(calc(-50% + ${offsetX.value}px), calc(-50% + ${offsetY.value}px))`,\n      userSelect: \"none\",\n      WebkitUserDrag: \"none\",\n      touchAction: \"none\",\n    }));\n\n    const cropAreaStyle = computed<CSSProperties>(() => ({\n      position: \"absolute\",\n      left: \"50%\",\n      top: \"50%\",\n      width: `${cropAreaWidth.value}px`,\n      height: `${cropAreaHeight.value}px`,\n      transform: \"translate(-50%, -50%)\",\n    }));\n\n    provide<CropperContextValue>(cropperContextKey, {\n      image: computed(() => props.image),\n      imageStyle,\n      cropAreaStyle,\n      setNaturalSize,\n    });\n\n    watch(\n      () => props.zoom,\n      (nextZoom) => {\n        if (typeof nextZoom === \"number\") {\n          internalZoom.value = nextZoom;\n        }\n      }\n    );\n\n    watch(\n      [cropAreaWidth, cropAreaHeight, imageWidth, imageHeight],\n      () => {\n        clampOffsets();\n        emitCropArea();\n      },\n      { immediate: true }\n    );\n\n    watch(\n      [offsetX, offsetY, appliedScale],\n      () => {\n        emitCropArea();\n      },\n      { immediate: true }\n    );\n\n    watch(\n      () => props.image,\n      () => {\n        naturalWidth.value = 0;\n        naturalHeight.value = 0;\n        offsetX.value = 0;\n        offsetY.value = 0;\n      }\n    );\n\n    onMounted(() => {\n      internalZoom.value = props.zoom ?? internalZoom.value;\n      updateContainerSize();\n      if (rootRef.value) {\n        resizeObserver = new ResizeObserver(updateContainerSize);\n        resizeObserver.observe(rootRef.value);\n      }\n    });\n\n    onBeforeUnmount(() => {\n      stopDragging();\n      resizeObserver?.disconnect();\n    });\n\n    return () =>\n      h(\n        \"div\",\n        mergeProps(attrs, {\n          ref: rootRef,\n          \"data-slot\": \"cropper\",\n          class: cn(cropperRootVariants(), props.class),\n          tabindex: attrs.tabindex ?? 0,\n          onPointerdown: handlePointerDown,\n          onWheel: handleWheel,\n          onKeydown: handleKeyDown,\n        }),\n        slots.default?.()\n      );\n  },\n});\n\nexport const CropperDescription = defineComponent({\n  name: \"CropperDescription\",\n  inheritAttrs: false,\n  props: {\n    class: {\n      type: String,\n      default: undefined,\n    },\n  },\n  setup(props, { attrs, slots }) {\n    return () =>\n      h(\n        \"p\",\n        mergeProps(attrs, {\n          \"data-slot\": \"cropper-description\",\n          class: cn(cropperDescriptionVariants(), props.class),\n        }),\n        slots.default?.()\n      );\n  },\n});\n\nexport const CropperImage = defineComponent({\n  name: \"CropperImage\",\n  inheritAttrs: false,\n  props: {\n    class: {\n      type: String,\n      default: undefined,\n    },\n  },\n  setup(props, { attrs }) {\n    const context = inject<CropperContextValue | null>(cropperContextKey, null);\n\n    const resolvedSrc = computed(() => {\n      const attributeSrc = typeof attrs.src === \"string\" ? attrs.src : undefined;\n      return attributeSrc ?? context?.image.value;\n    });\n\n    const handleLoad = (event: Event) => {\n      const target = event.target as HTMLImageElement | null;\n      if (!target) return;\n      context?.setNaturalSize(target.naturalWidth, target.naturalHeight);\n    };\n\n    return () =>\n      h(\n        \"img\",\n        mergeProps(attrs, {\n          \"data-slot\": \"cropper-image\",\n          src: resolvedSrc.value,\n          draggable: false,\n          onLoad: handleLoad,\n          class: cn(cropperImageVariants(), props.class),\n          style: context?.imageStyle.value,\n        })\n      );\n  },\n});\n\nexport const CropperCropArea = defineComponent({\n  name: \"CropperCropArea\",\n  inheritAttrs: false,\n  props: {\n    class: {\n      type: String,\n      default: undefined,\n    },\n  },\n  setup(props, { attrs }) {\n    const context = inject<CropperContextValue | null>(cropperContextKey, null);\n\n    return () =>\n      h(\n        \"div\",\n        mergeProps(attrs, {\n          \"data-slot\": \"cropper-crop-area\",\n          class: cn(cropperCropAreaVariants(), props.class),\n          style: context?.cropAreaStyle.value,\n        })\n      );\n  },\n});\n\nexport default Cropper;\n</script>\n"
        }
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core"
            ],
            "optionalPeerDependencies": [
              "@origin-space/image-cropper"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core"
            ]
          }
        },
        "placeholder": false,
        "clientOnly": true
      }
    },
    {
      "name": "datefield-rac",
      "type": "registry:ui",
      "files": [
        {
          "path": "registry/default/ui/datefield-rac.tsx",
          "type": "registry:ui",
          "target": "components/ui/datefield-rac.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport { cn, dateFieldInputVariants, dateFieldSegmentVariants } from '@timui/core'\n\ntype DateInputType = 'date' | 'time' | 'datetime-local'\ntype DateGranularity = 'day' | 'minute' | 'second'\ntype DateFieldValue = string | number | Date | null\n\ntype DateFieldContextValue = {\n  inputType: DateInputType\n  granularity?: DateGranularity\n  value?: string\n  onValueChange?: (value: string) => void\n}\n\nconst DateFieldContext = React.createContext<DateFieldContextValue | null>(null)\n\nconst dateInputStyle = dateFieldInputVariants()\n\ntype DateFieldProps<T = DateFieldValue> = React.HTMLAttributes<HTMLDivElement> & {\n  type?: DateInputType\n  granularity?: DateGranularity\n  hourCycle?: 12 | 24\n  value?: T\n  defaultValue?: T\n  onChange?: (value: T) => void\n}\n\ntype TimeFieldProps<T = DateFieldValue> = React.HTMLAttributes<HTMLDivElement> & {\n  type?: DateInputType\n  granularity?: DateGranularity\n  hourCycle?: 12 | 24\n  value?: T\n  defaultValue?: T\n  onChange?: (value: T) => void\n}\n\ntype DateSegmentProps = React.HTMLAttributes<HTMLSpanElement>\n\ninterface DateInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {\n  unstyled?: boolean\n  invalid?: boolean\n}\n\nconst toInputString = (value?: DateFieldValue) => {\n  if (value === undefined || value === null) return undefined\n  if (value instanceof Date) {\n    return `${value.getFullYear()}-${String(value.getMonth() + 1).padStart(2, '0')}-${String(\n      value.getDate()\n    ).padStart(2, '0')}`\n  }\n  return String(value)\n}\n\nfunction DateField<T = DateFieldValue>({\n  type,\n  granularity,\n  value,\n  defaultValue,\n  onChange,\n  hourCycle: _hourCycle,\n  className,\n  children,\n  ...restProps\n}: DateFieldProps<T>) {\n  const [uncontrolledValue, setUncontrolledValue] = React.useState<string | undefined>(() =>\n    toInputString(defaultValue as DateFieldValue)\n  )\n  const controlledValue = value !== undefined ? toInputString(value as DateFieldValue) : undefined\n  const fieldValue = controlledValue ?? uncontrolledValue\n\n  const handleValueChange = React.useCallback(\n    (nextValue: string) => {\n      if (value === undefined) {\n        setUncontrolledValue(nextValue)\n      }\n      onChange?.(nextValue as T)\n    },\n    [onChange, value]\n  )\n\n  const inputType: DateInputType =\n    type ?? (granularity && granularity !== 'day' ? 'datetime-local' : 'date')\n\n  return (\n    <DateFieldContext.Provider\n      value={{ inputType, granularity, value: fieldValue, onValueChange: handleValueChange }}\n    >\n      <div className={cn(className)} {...restProps}>\n        {children}\n      </div>\n    </DateFieldContext.Provider>\n  )\n}\n\nfunction TimeField<T = DateFieldValue>({\n  type,\n  granularity,\n  value,\n  defaultValue,\n  onChange,\n  hourCycle: _hourCycle,\n  className,\n  children,\n  ...restProps\n}: TimeFieldProps<T>) {\n  const [uncontrolledValue, setUncontrolledValue] = React.useState<string | undefined>(() =>\n    toInputString(defaultValue as DateFieldValue)\n  )\n  const controlledValue = value !== undefined ? toInputString(value as DateFieldValue) : undefined\n  const fieldValue = controlledValue ?? uncontrolledValue\n\n  const handleValueChange = React.useCallback(\n    (nextValue: string) => {\n      if (value === undefined) {\n        setUncontrolledValue(nextValue)\n      }\n      onChange?.(nextValue as T)\n    },\n    [onChange, value]\n  )\n\n  const inputType: DateInputType = type ?? 'time'\n\n  return (\n    <DateFieldContext.Provider\n      value={{ inputType, granularity, value: fieldValue, onValueChange: handleValueChange }}\n    >\n      <div className={cn(className)} {...restProps}>\n        {children}\n      </div>\n    </DateFieldContext.Provider>\n  )\n}\n\nfunction DateSegment({ className, ...props }: DateSegmentProps) {\n  return <span className={cn(dateFieldSegmentVariants(), className)} {...props} />\n}\n\nfunction DateInput({ className, unstyled = false, invalid, type, step, ...props }: DateInputProps) {\n  const context = React.useContext(DateFieldContext)\n  const { onChange, value, defaultValue, ...restProps } = props\n  const resolvedType = type ?? context?.inputType ?? 'date'\n  const resolvedValue = value ?? context?.value\n\n  const resolvedStep =\n    step ??\n    (context?.granularity === 'second' ? 1 : context?.granularity === 'minute' ? 60 : undefined)\n\n  const handleChange = React.useCallback(\n    (event: React.ChangeEvent<HTMLInputElement>) => {\n      context?.onValueChange?.(event.currentTarget.value)\n      onChange?.(event)\n    },\n    [context, onChange]\n  )\n\n  return (\n    <input\n      type={resolvedType}\n      step={resolvedStep}\n      value={resolvedValue}\n      defaultValue={resolvedValue === undefined ? defaultValue : undefined}\n      className={cn(!unstyled && dateFieldInputVariants(), className)}\n      aria-invalid={invalid || undefined}\n      onChange={handleChange}\n      {...restProps}\n    />\n  )\n}\n\nexport { DateField, DateInput, DateSegment, TimeField, dateInputStyle }\nexport type { DateFieldProps, DateInputProps, DateSegmentProps, TimeFieldProps }\n"
        },
        {
          "path": "registry/default/vue/datefield-rac.vue",
          "type": "registry:ui",
          "target": "components/ui/datefield-rac.vue",
          "content": "<script setup lang=\"ts\">\nimport DateFieldRac from './datefield/datefield-rac.vue'\n</script>\n\n<template>\n  <DateFieldRac v-bind=\"$attrs\">\n    <slot />\n  </DateFieldRac>\n</template>\n"
        }
      ],
      "dependencies": [
        "@timui/core"
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core"
            ]
          },
          "vue": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "dialog",
      "type": "registry:ui",
      "dependencies": [
        "@timui/core",
        "@zag-js/react"
      ],
      "registryDependencies": [
        "use-machine"
      ],
      "files": [
        {
          "path": "registry/default/ui/dialog.tsx",
          "type": "registry:ui",
          "target": "components/ui/dialog.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport type { AssertNoExtraKeys, DialogProps as CoreDialogProps } from '@timui/core'\nimport {\n  cn,\n  createTimEvent,\n  dialogCloseIconVariants,\n  dialogCloseVariants,\n  dialogContentVariants,\n  dialogDescriptionVariants,\n  dialogFooterVariants,\n  dialogHeaderVariants,\n  dialogOverlayVariants,\n  dialogTitleVariants,\n} from '@timui/core'\nimport { createPortal } from 'react-dom'\n\nimport { useDialog, type UseDialogProps } from './dialog/use-dialog'\nimport { DialogProvider, useDialogContext } from './dialog/use-dialog-context'\nimport { Slot } from './slot'\n\nexport interface DialogProps extends UseDialogProps {\n  children?: React.ReactNode\n}\n\nconst Dialog: React.FC<DialogProps> = (props) => {\n  const { children, ...restProps } = props\n  const api = useDialog(restProps)\n\n  return <DialogProvider value={api}>{children}</DialogProvider>\n}\nDialog.displayName = 'Dialog'\n\nconst DialogTrigger = React.forwardRef<\n  HTMLButtonElement,\n  React.ButtonHTMLAttributes<HTMLButtonElement> & { asChild?: boolean }\n>(({ asChild = false, ...props }, ref) => {\n  const api = useDialogContext()\n  const Comp = asChild ? Slot : 'button'\n  return <Comp data-slot=\"dialog-trigger\" {...api.getTriggerProps()} {...props} ref={ref} />\n})\nDialogTrigger.displayName = 'DialogTrigger'\n\nconst DialogPortal = ({ children }: { children: React.ReactNode }) => {\n  const api = useDialogContext()\n\n  // Only render when open for simplicity\n  if (!api.open) return null\n  if (typeof window === 'undefined') return null\n\n  return createPortal(<div data-slot=\"dialog-portal\">{children}</div>, document.body)\n}\nDialogPortal.displayName = 'DialogPortal'\n\nconst DialogOverlay = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  (props, ref) => {\n    const api = useDialogContext()\n    return (\n      <div\n        data-slot=\"dialog-overlay\"\n        {...api.getBackdropProps()}\n        {...props}\n        className={cn(dialogOverlayVariants(), props.className)}\n        ref={ref}\n      />\n    )\n  }\n)\nDialogOverlay.displayName = 'DialogOverlay'\n\nconst DialogContent = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  (props, ref) => {\n    const api = useDialogContext()\n\n    return (\n      <DialogPortal>\n        <DialogOverlay />\n        <div {...api.getPositionerProps()}>\n          <div\n            data-slot=\"dialog-content\"\n            {...api.getContentProps()}\n            {...props}\n            className={cn(dialogContentVariants(), props.className)}\n            ref={ref}\n          >\n            {props.children}\n            <button\n              data-slot=\"dialog-close\"\n              className={cn(dialogCloseVariants())}\n              {...api.getCloseTriggerProps()}\n            >\n              <svg\n                aria-hidden=\"true\"\n                viewBox=\"0 0 24 24\"\n                fill=\"none\"\n                stroke=\"currentColor\"\n                strokeWidth=\"2\"\n                strokeLinecap=\"round\"\n                strokeLinejoin=\"round\"\n                className={dialogCloseIconVariants()}\n              >\n                <path d=\"M18 6 6 18\" />\n                <path d=\"m6 6 12 12\" />\n              </svg>\n              <span className=\"sr-only\">Close</span>\n            </button>\n          </div>\n        </div>\n      </DialogPortal>\n    )\n  }\n)\nDialogContent.displayName = 'DialogContent'\n\nconst DialogHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (\n  <div className={cn(dialogHeaderVariants(), className)} {...props} />\n)\nDialogHeader.displayName = 'DialogHeader'\n\nconst DialogFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (\n  <div className={cn(dialogFooterVariants(), className)} {...props} />\n)\nDialogFooter.displayName = 'DialogFooter'\n\nconst DialogTitle = React.forwardRef<HTMLHeadingElement, React.HTMLAttributes<HTMLHeadingElement>>(\n  ({ className, ...props }, ref) => {\n    const api = useDialogContext()\n    return (\n      <h2\n        ref={ref}\n        data-slot=\"dialog-title\"\n        {...api.getTitleProps()}\n        {...props}\n        className={cn(dialogTitleVariants(), className)}\n      />\n    )\n  }\n)\nDialogTitle.displayName = 'DialogTitle'\n\ntype DialogDescriptionProps = React.HTMLAttributes<HTMLParagraphElement> & {\n  asChild?: boolean\n}\n\nconst DialogDescription = React.forwardRef<HTMLParagraphElement, DialogDescriptionProps>(\n  ({ className, asChild, children, ...props }, ref) => {\n    const api = useDialogContext()\n    if (asChild) {\n      return (\n        <Slot\n          data-slot=\"dialog-description\"\n          {...api.getDescriptionProps()}\n          {...props}\n          className={cn(dialogDescriptionVariants(), className)}\n        >\n          {children}\n        </Slot>\n      )\n    }\n\n    return (\n      <p\n        ref={ref}\n        data-slot=\"dialog-description\"\n        {...api.getDescriptionProps()}\n        {...props}\n        className={cn(dialogDescriptionVariants(), className)}\n      >\n        {children}\n      </p>\n    )\n  }\n)\nDialogDescription.displayName = 'DialogDescription'\n\ntype DialogCloseProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {\n  asChild?: boolean\n}\n\nconst DialogClose = React.forwardRef<HTMLButtonElement, DialogCloseProps>(\n  ({ className, asChild, children, ...props }, ref) => {\n    const api = useDialogContext()\n    const sharedProps = {\n      ...api.getCloseTriggerProps(),\n      className: cn(className),\n      ...props,\n    }\n\n    if (asChild) {\n      return (\n        <Slot data-slot=\"dialog-close\" {...sharedProps}>\n          {children}\n        </Slot>\n      )\n    }\n\n    return (\n      <button ref={ref} data-slot=\"dialog-close\" {...sharedProps}>\n        {children}\n      </button>\n    )\n  }\n)\nDialogClose.displayName = 'DialogClose'\n\nexport {\n  Dialog,\n  DialogPortal,\n  DialogOverlay,\n  DialogClose,\n  DialogTrigger,\n  DialogContent,\n  DialogHeader,\n  DialogFooter,\n  DialogTitle,\n  DialogDescription,\n}\n"
        },
        {
          "path": "registry/default/ui/dialog/use-dialog-context.ts",
          "target": "components/ui/dialog/use-dialog-context.ts",
          "type": "registry:ui",
          "content": "import * as React from 'react'\nimport type { dialogConnect } from '@timui/core'\n\nexport type DialogContextValue = ReturnType<typeof dialogConnect>\n\nconst DialogContext = React.createContext<DialogContextValue | null>(null)\n\nexport const DialogProvider: React.Provider<DialogContextValue | null> = DialogContext.Provider\n\nexport function useDialogContext(): DialogContextValue {\n  const context = React.useContext(DialogContext)\n  if (!context) {\n    throw new Error('Dialog components must be used within `<DialogProvider />`')\n  }\n  return context\n}\n"
        },
        {
          "path": "registry/default/ui/dialog/use-dialog.ts",
          "target": "components/ui/dialog/use-dialog.ts",
          "type": "registry:ui",
          "content": "import * as React from 'react'\nimport { createTimEvent, dialogConnect, dialogMachine } from '@timui/core'\nimport type { DialogProps as CoreDialogProps } from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/react'\n\nexport interface UseDialogProps extends Omit<CoreDialogProps, 'id'> {\n  id?: string\n  defaultOpen?: boolean\n  role?: 'dialog' | 'alertdialog'\n}\n\nexport function useDialog(props: UseDialogProps = {}) {\n  const generatedId = React.useId()\n  const dialogId = props.id ?? `dialog-${generatedId}`\n\n  const service = useMachine(dialogMachine, {\n    id: dialogId,\n    open: props.open,\n    defaultOpen: props.defaultOpen,\n    modal: props.modal !== false,\n    role: props.role,\n    onOpenChange: (details) => {\n      props.onOpenChange?.(createTimEvent('dialog.openChange', dialogId, { open: details.open }))\n    },\n  })\n\n  const api = React.useMemo(() => dialogConnect(service, normalizeProps), [service])\n\n  React.useEffect(() => {\n    if (props.open !== undefined && props.open !== api.open) {\n      api.setOpen(props.open)\n    }\n  }, [props.open, api])\n\n  return api\n}\n"
        },
        {
          "path": "registry/default/vue/dialog/dialog-close.vue",
          "target": "components/ui/dialog/dialog-close.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, type Component, type HTMLAttributes } from 'vue'\nimport { cn } from '@timui/core'\nimport { Primitive } from '../../primitive'\nimport { useDialogContext } from './use-dialog-context'\n\nconst props = withDefaults(\n  defineProps<{\n    as?: string | Component\n    asChild?: boolean\n    class?: HTMLAttributes['class']\n  }>(),\n  {\n    as: 'button',\n  }\n)\n\nconst api = useDialogContext()\nconst closeProps = computed(() => ({\n  ...(api.value.getCloseTriggerProps?.() ?? {}),\n  type: props.asChild ? undefined : 'button',\n  'data-slot': 'dialog-close',\n}))\n</script>\n\n<template>\n  <Primitive\n    :as=\"props.as\"\n    :as-child=\"props.asChild\"\n    :class=\"cn(props.class)\"\n    v-bind=\"closeProps\"\n  >\n    <slot />\n  </Primitive>\n</template>\n"
        },
        {
          "path": "registry/default/vue/dialog/dialog-content.vue",
          "target": "components/ui/dialog/dialog-content.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes } from \"vue\";\nimport {\n  dialogOverlayVariants,\n  dialogContentVariants,\n  dialogCloseVariants,\n  dialogCloseIconVariants,\n  dialogPositionerVariants,\n  cn,\n} from \"@timui/core\";\nimport { useDialogContext } from \"./use-dialog-context\";\nimport Presence from \"../presence/presence.vue\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\n\nconst api = useDialogContext();\n</script>\n\n<template>\n  <Teleport to=\"body\">\n    <Presence\n      :present=\"api?.open ?? false\"\n      :unmountOnExit=\"true\"\n      v-bind=\"api?.getBackdropProps?.()\"\n      data-slot=\"dialog-overlay\"\n      data-state=\"open\"\n      :class=\"cn(dialogOverlayVariants())\"\n    />\n    <Presence\n      :present=\"api?.open ?? false\"\n      :unmountOnExit=\"true\"\n      v-bind=\"api?.getPositionerProps?.()\"\n      :class=\"cn(dialogPositionerVariants())\"\n    >\n      <div\n        v-bind=\"api?.getContentProps?.()\"\n        data-slot=\"dialog-content\"\n        data-state=\"open\"\n        :class=\"cn(dialogContentVariants(), props.class)\"\n      >\n        <slot />\n\n        <button\n          v-bind=\"api?.getCloseTriggerProps?.()\"\n          data-slot=\"dialog-close\"\n          :class=\"cn(dialogCloseVariants())\"\n        >\n          <svg\n            aria-hidden=\"true\"\n            viewBox=\"0 0 24 24\"\n            fill=\"none\"\n            stroke=\"currentColor\"\n            stroke-width=\"2\"\n            stroke-linecap=\"round\"\n            stroke-linejoin=\"round\"\n            :class=\"dialogCloseIconVariants()\"\n          >\n            <path d=\"M18 6 6 18\" />\n            <path d=\"m6 6 12 12\" />\n          </svg>\n          <span class=\"sr-only\">Close</span>\n        </button>\n      </div>\n    </Presence>\n  </Teleport>\n</template>\n"
        },
        {
          "path": "registry/default/vue/dialog/dialog-description.vue",
          "target": "components/ui/dialog/dialog-description.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes } from \"vue\";\nimport { cn, dialogDescriptionVariants } from \"@timui/core\";\nimport { useDialogContext } from \"./use-dialog-context\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\nconst api = useDialogContext();\n</script>\n\n<template>\n  <p\n    v-bind=\"api.getDescriptionProps()\"\n    data-slot=\"dialog-description\"\n    :class=\"cn(dialogDescriptionVariants(), props.class)\"\n  >\n    <slot />\n  </p>\n</template>\n"
        },
        {
          "path": "registry/default/vue/dialog/dialog-footer.vue",
          "target": "components/ui/dialog/dialog-footer.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed } from \"vue\";\nimport { cn, dialogFooterVariants } from \"@timui/core\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\n</script>\n\n<template>\n  <div data-slot=\"dialog-footer\" :class=\"cn(dialogFooterVariants(), props.class)\">\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/dialog/dialog-header.vue",
          "target": "components/ui/dialog/dialog-header.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed } from \"vue\";\nimport { cn, dialogHeaderVariants } from \"@timui/core\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\n</script>\n\n<template>\n  <div data-slot=\"dialog-header\" :class=\"cn(dialogHeaderVariants(), props.class)\">\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/dialog/dialog-title.vue",
          "target": "components/ui/dialog/dialog-title.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes } from \"vue\";\nimport { cn } from \"@timui/core\";\nimport { useDialogContext } from \"./use-dialog-context\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\nconst api = useDialogContext();\n</script>\n\n<template>\n  <h2\n    v-bind=\"api.getTitleProps()\"\n    data-slot=\"dialog-title\"\n    :class=\"cn('text-lg font-semibold leading-none tracking-tight', props.class)\"\n  >\n    <slot />\n  </h2>\n</template>\n"
        },
        {
          "path": "registry/default/vue/dialog/dialog-trigger.vue",
          "target": "components/ui/dialog/dialog-trigger.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { useDialogContext } from \"./use-dialog-context\";\n\nconst api = useDialogContext();\n</script>\n\n<template>\n  <button v-bind=\"api.getTriggerProps()\" data-slot=\"dialog-trigger\">\n    <slot />\n  </button>\n</template>\n"
        },
        {
          "path": "registry/default/vue/dialog/dialog.vue",
          "target": "components/ui/dialog/dialog.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { useDialog, type UseDialogProps, type UseDialogEmits } from \"./use-dialog\";\nimport { DialogProvider } from \"./use-dialog-context\";\n\nconst props = defineProps<UseDialogProps>();\nconst emit = defineEmits<UseDialogEmits>();\n\nconst api = useDialog(props, emit);\nDialogProvider(api);\n</script>\n\n<template>\n  <slot />\n</template>\n"
        },
        {
          "path": "registry/default/vue/dialog/use-dialog-context.ts",
          "target": "components/ui/dialog/use-dialog-context.ts",
          "type": "registry:component",
          "content": "import type { dialogConnect } from '@timui/core'\nimport type { ComputedRef } from 'vue'\n\nimport { createContext } from '../../hooks/create-context'\n\nexport type DialogContext = ComputedRef<ReturnType<typeof dialogConnect>>\n\nexport const [DialogProvider, useDialogContext] = createContext<DialogContext>({\n  id: 'DialogContext',\n  providerName: '<Dialog />',\n})\n"
        },
        {
          "path": "registry/default/vue/dialog/use-dialog.ts",
          "target": "components/ui/dialog/use-dialog.ts",
          "type": "registry:component",
          "content": "import type { DialogVueProps as CoreDialogProps } from '@timui/core'\nimport { dialogConnect, dialogMachine } from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/vue'\nimport { computed, useId, watch } from 'vue'\n\nexport interface UseDialogProps extends Omit<CoreDialogProps, 'id'> {\n  id?: string\n  defaultOpen?: boolean\n}\n\nexport interface UseDialogEmits {\n  (e: 'update:open', value: boolean): void\n  (e: 'openChange', value: boolean): void\n}\n\nexport function useDialog(props: UseDialogProps, emit: UseDialogEmits) {\n  const generatedId = useId()\n\n  const machineProps = computed(() => ({\n    id: props.id ?? generatedId,\n    open: props.open,\n    defaultOpen: props.defaultOpen,\n    modal: props.modal !== false,\n    onOpenChange(details: { open: boolean }) {\n      props.onOpenChange?.(details.open)\n      emit('update:open', details.open)\n      emit('openChange', details.open)\n    },\n  }))\n\n  const service = useMachine(dialogMachine, machineProps)\n  const api = computed(() => dialogConnect(service, normalizeProps))\n\n  // Controlled component sync logic\n  watch(\n    () => props.open,\n    (val?: boolean) => {\n      if (val !== undefined && val !== api.value.open) {\n        api.value.setOpen(val)\n      }\n    }\n  )\n\n  return api\n}\n"
        },
        {
          "path": "registry/default/html/dialog.html",
          "target": "components/ui/dialog.html",
          "type": "registry:component",
          "content": "<div data-slot=\"dialog-portal\">\n    <div data-slot=\"dialog-overlay\" class=\"data-[state&#x3D;open]:animate-in data-[state&#x3D;closed]:animate-out data-[state&#x3D;closed]:fade-out-0 data-[state&#x3D;open]:fade-in-0 fixed inset-0 z-50 bg-black/80\"></div>\n    <div class=\"fixed inset-0 z-50 flex items-center justify-center pointer-events-none\">\n        <div data-slot=\"dialog-content\" class=\"data-[state&#x3D;open]:animate-in data-[state&#x3D;closed]:animate-out data-[state&#x3D;closed]:fade-out-0 data-[state&#x3D;open]:fade-in-0 data-[state&#x3D;closed]:zoom-out-95 data-[state&#x3D;open]:zoom-in-95 data-[state&#x3D;closed]:slide-out-to-top-[48%] data-[state&#x3D;closed]:slide-out-to-left-[50%] data-[state&#x3D;open]:slide-in-from-top-[48%] data-[state&#x3D;open]:slide-in-from-left-[50%] fixed top-[50%] left-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 sm:rounded-lg pointer-events-auto\">\n            <div class=\"flex flex-col space-y-1.5 text-center sm:text-left\">\n                <h2 data-slot=\"dialog-title\" class=\"text-lg font-semibold leading-none tracking-tight\">Dialog Title</h2>\n                <p data-slot=\"dialog-description\" class=\"text-sm text-muted-foreground\">Dialog Description</p>\n            </div>\n            <div class=\"py-4\">Main content area</div>\n            <div class=\"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2\">\n                <button\n                    class=\"bg-primary text-primary-foreground hover:bg-primary/90 inline-flex items-center justify-center rounded-md text-sm font-medium h-10 px-4 py-2\">Save</button>\n            </div>\n            <button data-slot=\"dialog-close\" class=\"ring-offset-background focus:ring-ring absolute right-4 top-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:pointer-events-none data-[state&#x3D;open]:bg-accent data-[state&#x3D;open]:text-muted-foreground\">\n                <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n                    stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"h-4 w-4\">\n                    <path d=\"M18 6 6 18\" />\n                    <path d=\"m6 6 12 12\" />\n                </svg>\n                <span class=\"sr-only\">Close</span>\n            </button>\n        </div>\n    </div>\n</div>"
        },
        {
          "path": "registry/default/weapp/dialog.wxml",
          "target": "components/ui/dialog.wxml",
          "type": "registry:component",
          "content": "<root-portal wx:if=\"{{api.open}}\">\n  <view \n    class=\"{{overlayClass}}\" \n    data-slot=\"dialog-overlay\" \n    data-state=\"{{api.open ? 'open' : 'closed'}}\" \n    bindtap=\"onBackdropTap\" \n    catchtouchmove=\"noop\"\n  ></view>\n  <view \n    class=\"{{contentClass}}\" \n    data-slot=\"dialog-content\" \n    data-state=\"{{api.open ? 'open' : 'closed'}}\"\n    id=\"{{api.contentProps.id}}\"\n    role=\"{{api.contentProps.role}}\"\n    aria-modal=\"{{api.contentProps['aria-modal']}}\"\n    aria-label=\"{{api.contentProps['aria-label']}}\"\n  >\n    <slot></slot>\n    <view \n      class=\"{{closeClass}}\" \n      data-slot=\"dialog-close\" \n      bindtap=\"onCloseTap\"\n    >\n      <text>✕</text>\n    </view>\n  </view>\n</root-portal>\n"
        },
        {
          "path": "registry/default/weapp/dialog.wxss",
          "target": "components/ui/dialog.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/dialog.ts",
          "target": "components/ui/dialog.ts",
          "type": "registry:component",
          "content": "import { dialogCloseVariants, dialogContentVariants, dialogOverlayVariants } from '@timui/core'\n\nimport { resolveClasses } from '../utils'\nimport { setupDialogMachine } from './use-dialog'\n\ntype MachineEvent =\n  | string\n  | {\n      type: string\n      [key: string]: string | number | boolean | string[] | number[] | null | undefined\n    }\n\ntype WeappDialogApi = {\n  open?: boolean\n  backdropProps?: {\n    onClick?: () => void\n  }\n  closeTriggerProps?: {\n    onClick?: () => void\n  }\n}\n\ntype WeappService = {\n  setContext: (context: { open?: boolean }) => void\n}\n\ntype MachineSend = (event: MachineEvent) => void\n\ntype WeappDialogInternal = WechatMiniprogram.Component.InstanceMethods<WeappDialogApi> & {\n  _service?: WeappService\n  _cleanup?: () => void\n  _send?: MachineSend\n  _connect?: (state: object, send: MachineSend) => WeappDialogApi\n  data: {\n    api: WeappDialogApi\n  }\n  properties: {\n    open: boolean\n    id: string\n    extClass: string\n  }\n}\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    open: {\n      type: Boolean,\n      value: false,\n    },\n    id: {\n      type: String,\n      value: 'dialog',\n    },\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n\n  data: {\n    api: {} as WeappDialogApi,\n    // Store variants class strings\n    contentClass: '',\n    overlayClass: '',\n    closeClass: '',\n  },\n\n  lifetimes: {\n    attached() {\n      const self = this as WeappDialogInternal\n      const { controller, connect } = setupDialogMachine(this)\n\n      self._service = controller.service as WeappService\n      self._cleanup = controller.start()\n      self._send = controller.send as MachineSend\n      self._connect = connect\n    },\n    detached() {\n      const self = this as WeappDialogInternal\n      self._cleanup?.()\n    },\n  },\n\n  observers: {\n    state: function (state) {\n      const self = this as WeappDialogInternal\n      if (!state || !self._send || !self._connect) return\n\n      const api = self._connect(state, self._send) as WeappDialogApi\n\n      const contentClass = resolveClasses(dialogContentVariants(), this.properties.extClass)\n      const overlayClass = resolveClasses(dialogOverlayVariants())\n      const closeClass = resolveClasses(dialogCloseVariants())\n\n      this.setData({\n        api,\n        contentClass,\n        overlayClass,\n        closeClass,\n      })\n    },\n\n    open: function (val) {\n      const self = this as WeappDialogInternal\n      if (self._service) {\n        if (val !== self.data.api.open) {\n          self._send?.(val ? 'OPEN' : 'CLOSE')\n        }\n      }\n    },\n  },\n\n  methods: {\n    onBackdropTap() {\n      const self = this as WeappDialogInternal\n      self.data.api.backdropProps?.onClick?.()\n    },\n    onCloseTap() {\n      const self = this as WeappDialogInternal\n      self.data.api.closeTriggerProps?.onClick?.()\n    },\n    noop() {},\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/dialog.json",
          "target": "components/ui/dialog.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        },
        {
          "path": "registry/default/weapp/dialog-description/dialog-description.wxml",
          "target": "components/ui/dialog-description/dialog-description.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{baseClass}}\" data-slot=\"dialog-description\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/dialog-description/dialog-description.wxss",
          "target": "components/ui/dialog-description/dialog-description.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/dialog-description/dialog-description.json",
          "target": "components/ui/dialog-description/dialog-description.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/dialog-description/dialog-description.ts",
          "target": "components/ui/dialog-description/dialog-description.ts",
          "type": "registry:component",
          "content": "import { dialogDescriptionVariants } from '@timui/core'\n\nimport { resolveClasses } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: { type: String, value: '' },\n  },\n  data: { baseClass: '' },\n  observers: {\n    extClass: function (extClass) {\n      const { baseClass } = resolveClasses(dialogDescriptionVariants(), extClass)\n      this.setData({ baseClass })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/dialog-footer/dialog-footer.wxml",
          "target": "components/ui/dialog-footer/dialog-footer.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{baseClass}}\" data-slot=\"dialog-footer\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/dialog-footer/dialog-footer.wxss",
          "target": "components/ui/dialog-footer/dialog-footer.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/dialog-footer/dialog-footer.json",
          "target": "components/ui/dialog-footer/dialog-footer.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/dialog-footer/dialog-footer.ts",
          "target": "components/ui/dialog-footer/dialog-footer.ts",
          "type": "registry:component",
          "content": "import { dialogFooterVariants } from '@timui/core'\n\nimport { resolveClasses } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: { type: String, value: '' },\n  },\n  data: { baseClass: '' },\n  observers: {\n    extClass: function (extClass) {\n      const { baseClass } = resolveClasses(dialogFooterVariants(), extClass)\n      this.setData({ baseClass })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/dialog-header/dialog-header.wxml",
          "target": "components/ui/dialog-header/dialog-header.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{baseClass}}\" data-slot=\"dialog-header\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/dialog-header/dialog-header.wxss",
          "target": "components/ui/dialog-header/dialog-header.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/dialog-header/dialog-header.json",
          "target": "components/ui/dialog-header/dialog-header.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/dialog-header/dialog-header.ts",
          "target": "components/ui/dialog-header/dialog-header.ts",
          "type": "registry:component",
          "content": "import { dialogHeaderVariants } from '@timui/core'\n\nimport { resolveClasses } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: { type: String, value: '' },\n  },\n  data: { baseClass: '' },\n  observers: {\n    extClass: function (extClass) {\n      const { baseClass } = resolveClasses(dialogHeaderVariants(), extClass)\n      this.setData({ baseClass })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/dialog-title/dialog-title.wxml",
          "target": "components/ui/dialog-title/dialog-title.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{baseClass}}\" data-slot=\"dialog-title\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/dialog-title/dialog-title.wxss",
          "target": "components/ui/dialog-title/dialog-title.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/dialog-title/dialog-title.json",
          "target": "components/ui/dialog-title/dialog-title.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/dialog-title/dialog-title.ts",
          "target": "components/ui/dialog-title/dialog-title.ts",
          "type": "registry:component",
          "content": "import { dialogTitleVariants } from '@timui/core'\n\nimport { resolveClasses } from '../utils'\nimport {\n  createWeappBaseProps,\n  createWeappOptions,\n  WEAPP_EXTERNAL_CLASSES,\n} from '../utils/component'\n\nComponent({\n  options: createWeappOptions({ pureData: true }),\n  externalClasses: WEAPP_EXTERNAL_CLASSES,\n  properties: {\n    ...createWeappBaseProps(),\n  },\n  data: { baseClass: '' },\n  observers: {\n    extClass: function (extClass) {\n      const { baseClass } = resolveClasses(dialogTitleVariants(), extClass)\n      this.setData({ baseClass })\n    },\n  },\n})\n"
        }
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@zag-js/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@zag-js/vue"
            ]
          },
          "weapp": {
            "dependencies": [
              "@timui/core"
            ]
          },
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "dropdown-menu",
      "type": "registry:ui",
      "dependencies": [
        "@timui/core",
        "@zag-js/popper",
        "@zag-js/react"
      ],
      "files": [
        {
          "path": "registry/default/ui/dropdown-menu.tsx",
          "type": "registry:ui",
          "target": "components/ui/dropdown-menu.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport {\n  cn,\n  dropdownMenuCheckboxItemVariants,\n  dropdownMenuContentVariants,\n  dropdownMenuItemVariants,\n  dropdownMenuLabelVariants,\n  dropdownMenuRadioItemVariants,\n  dropdownMenuSeparatorVariants,\n  dropdownMenuShortcutVariants,\n  dropdownMenuSubContentVariants,\n  dropdownMenuSubTriggerVariants,\n} from '@timui/core'\nimport type { PositioningOptions } from '@zag-js/popper'\nimport { mergeProps, Portal } from '@zag-js/react'\n\nimport { useDropdownMenu, type DropdownMenuProps } from './dropdown-menu/use-dropdown-menu'\nimport {\n  DropdownMenuProvider,\n  DropdownMenuRadioGroupProvider,\n  useDropdownMenuContext,\n  useDropdownMenuRadioGroupContext,\n} from './dropdown-menu/use-dropdown-menu-context'\nimport { Slot } from './slot'\n\nconst composeEventHandlers = <E,>(\n  original?: ((event: E) => void) | undefined,\n  next?: ((event: E) => void) | undefined\n) => {\n  return (event: E) => {\n    original?.(event)\n    next?.(event)\n  }\n}\n\nconst setRef = <T,>(ref: React.Ref<T> | undefined, value: T | null) => {\n  if (!ref) return\n  if (typeof ref === 'function') {\n    ref(value)\n    return\n  }\n  ;(ref as React.MutableRefObject<T | null>).current = value\n}\n\nconst composeRefs = <T,>(...refs: Array<React.Ref<T> | undefined>) => {\n  return (value: T | null) => {\n    refs.forEach((ref) => setRef(ref, value))\n  }\n}\n\ntype DropdownMenuSubRootContextValue = {\n  openSubId: string | null\n  setOpenSubId: React.Dispatch<React.SetStateAction<string | null>>\n}\n\ntype DropdownMenuSubContextValue = {\n  id: string\n  open: boolean\n  setOpen: (open: boolean) => void\n  triggerElement: HTMLElement | null\n  setTriggerElement: React.Dispatch<React.SetStateAction<HTMLElement | null>>\n}\n\nconst DropdownMenuSubRootContext = React.createContext<DropdownMenuSubRootContextValue | null>(null)\nconst DropdownMenuSubContext = React.createContext<DropdownMenuSubContextValue | null>(null)\n\nconst useDropdownMenuSubRootContext = () => React.useContext(DropdownMenuSubRootContext)\n\nconst useDropdownMenuSubContext = () => {\n  const context = React.useContext(DropdownMenuSubContext)\n  if (!context) {\n    throw new Error('DropdownMenuSub components must be used within DropdownMenuSub.')\n  }\n  return context\n}\n\nconst DropdownMenu = (props: DropdownMenuProps) => {\n  const { children } = props\n  const api = useDropdownMenu(props)\n  const [openSubId, setOpenSubId] = React.useState<string | null>(null)\n\n  React.useEffect(() => {\n    if (!api.open) {\n      setOpenSubId(null)\n    }\n  }, [api.open])\n\n  return (\n    <DropdownMenuSubRootContext.Provider value={{ openSubId, setOpenSubId }}>\n      <DropdownMenuProvider value={api}>{children}</DropdownMenuProvider>\n    </DropdownMenuSubRootContext.Provider>\n  )\n}\n\ntype BaseDivProps = React.ComponentPropsWithoutRef<'div'>\ntype BaseButtonProps = React.ComponentPropsWithoutRef<'button'>\n\ntype DropdownMenuTriggerProps = BaseButtonProps & {\n  asChild?: boolean\n}\n\nconst DropdownMenuTrigger = React.forwardRef<HTMLButtonElement, DropdownMenuTriggerProps>(\n  (props, ref) => {\n    const api = useDropdownMenuContext()\n    const { asChild, className, ...otherProps } = props\n    const Comp = asChild ? Slot : 'button'\n    const triggerProps = api?.getTriggerProps?.() ?? {}\n    const mergedProps = mergeProps(triggerProps, otherProps)\n\n    return (\n      <Comp ref={ref} data-slot=\"dropdown-menu-trigger\" className={cn(className)} {...mergedProps}>\n        {props.children}\n      </Comp>\n    )\n  }\n)\nDropdownMenuTrigger.displayName = 'DropdownMenuTrigger'\n\ntype DropdownMenuContentProps = BaseDivProps & {\n  side?: 'top' | 'bottom' | 'left' | 'right'\n  align?: 'start' | 'center' | 'end'\n  sideOffset?: number\n}\n\nconst DropdownMenuContent = React.forwardRef<HTMLDivElement, DropdownMenuContentProps>(\n  ({ className, side = 'bottom', align = 'center', sideOffset = 4, ...props }, ref) => {\n    const api = useDropdownMenuContext()\n    const placement = (align === 'center' ? side : `${side}-${align}`) as NonNullable<\n      PositioningOptions['placement']\n    >\n    const reposition = api?.reposition\n\n    React.useEffect(() => {\n      if (!reposition) return\n      reposition({ placement, gutter: sideOffset })\n    }, [placement, reposition, sideOffset])\n\n    if (!api?.open) return null\n\n    const positionerProps = api.getPositionerProps()\n    const contentProps = api.getContentProps()\n\n    return (\n      <Portal>\n        <div {...positionerProps} style={{ ...positionerProps.style, zIndex: 50 }}>\n          <div\n            {...contentProps}\n            ref={ref}\n            data-slot=\"dropdown-menu-content\"\n            className={cn(dropdownMenuContentVariants(), className)}\n            {...props}\n          />\n        </div>\n      </Portal>\n    )\n  }\n)\nDropdownMenuContent.displayName = 'DropdownMenuContent'\n\ntype DropdownMenuItemProps = Omit<BaseDivProps, 'onSelect'> & {\n  inset?: boolean\n  value?: string\n  disabled?: boolean\n  closeOnSelect?: boolean\n  asChild?: boolean\n  onSelect?: () => void\n}\n\nconst DropdownMenuItem = React.forwardRef<HTMLElement, DropdownMenuItemProps>(\n  ({ className, inset, value, disabled, closeOnSelect, asChild = false, onSelect, ...props }, ref) => {\n    const api = useDropdownMenuContext()\n    const Comp = asChild ? Slot : 'div'\n    const generatedId = React.useId()\n    const itemValue = value ?? generatedId\n    const itemProps = api.getItemProps({ value: itemValue, disabled, closeOnSelect })\n    const mergedProps = mergeProps(itemProps, props)\n    const onClick = composeEventHandlers(\n      (mergedProps as React.HTMLAttributes<HTMLElement>).onClick,\n      () => onSelect?.()\n    )\n    const { className: mergedClassName, ...restProps } = mergedProps as React.HTMLAttributes<HTMLElement>\n\n    return (\n      <Comp\n        {...restProps}\n        ref={ref as React.Ref<HTMLDivElement>}\n        onClick={onClick}\n        data-slot=\"dropdown-menu-item\"\n        className={cn(dropdownMenuItemVariants(), inset && 'pl-8', mergedClassName, className)}\n      />\n    )\n  }\n)\nDropdownMenuItem.displayName = 'DropdownMenuItem'\n\ntype DropdownMenuSeparatorProps = BaseDivProps\n\nconst DropdownMenuSeparator = React.forwardRef<HTMLDivElement, DropdownMenuSeparatorProps>(\n  ({ className, ...props }, ref) => {\n    const api = useDropdownMenuContext()\n    const separatorProps = api?.getSeparatorProps?.() ?? {}\n    return (\n      <div\n        {...mergeProps(separatorProps, props)}\n        ref={ref}\n        data-slot=\"dropdown-menu-separator\"\n        className={cn(dropdownMenuSeparatorVariants(), className)}\n      />\n    )\n  }\n)\nDropdownMenuSeparator.displayName = 'DropdownMenuSeparator'\n\ntype DropdownMenuLabelProps = BaseDivProps & {\n  inset?: boolean\n}\n\nconst DropdownMenuLabel = React.forwardRef<HTMLDivElement, DropdownMenuLabelProps>(\n  ({ className, inset, ...props }, ref) => {\n    return (\n      <div\n        ref={ref}\n        data-slot=\"dropdown-menu-label\"\n        className={cn(dropdownMenuLabelVariants(), inset && 'pl-8', className)}\n        {...props}\n      />\n    )\n  }\n)\nDropdownMenuLabel.displayName = 'DropdownMenuLabel'\n\ntype DropdownMenuCheckboxItemProps = BaseDivProps & {\n  checked?: boolean\n  value?: string\n  disabled?: boolean\n  onCheckedChange?: (next: boolean) => void\n}\n\nconst DropdownMenuCheckboxItem = React.forwardRef<HTMLDivElement, DropdownMenuCheckboxItemProps>(\n  ({ className, children, checked, ...props }, ref) => {\n    const api = useDropdownMenuContext()\n    const generatedId = React.useId()\n    const { value: providedValue, disabled, onCheckedChange, ...domProps } = props\n    const value = providedValue ?? generatedId\n    const optionProps = api.getOptionItemProps({\n      type: 'checkbox',\n      checked: !!checked,\n      value,\n      disabled,\n      onCheckedChange: (next: boolean) => onCheckedChange?.(next),\n    })\n\n    return (\n      <div\n        {...mergeProps(optionProps, domProps)}\n        ref={ref}\n        data-slot=\"dropdown-menu-checkbox-item\"\n        className={cn(dropdownMenuCheckboxItemVariants(), className)}\n      >\n        <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n          {checked && (\n            <svg\n              aria-hidden=\"true\"\n              viewBox=\"0 0 16 16\"\n              fill=\"none\"\n              stroke=\"currentColor\"\n              strokeWidth=\"2.5\"\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              className=\"h-4 w-4\"\n            >\n              <path d=\"M3.5 8.5l3 3 6-7\" />\n            </svg>\n          )}\n        </span>\n        {children}\n      </div>\n    )\n  }\n)\nDropdownMenuCheckboxItem.displayName = 'DropdownMenuCheckboxItem'\n\ntype DropdownMenuGroupProps = BaseDivProps\ntype DropdownMenuSubProps = BaseDivProps\ntype DropdownMenuPortalProps = {\n  children: React.ReactNode\n}\ntype DropdownMenuSubTriggerProps = BaseDivProps & { inset?: boolean }\ntype DropdownMenuSubContentProps = BaseDivProps\n\nconst DropdownMenuGroup = (props: DropdownMenuGroupProps) => (\n  <div data-slot=\"dropdown-menu-group\" {...props} />\n)\nconst DropdownMenuPortal = (props: DropdownMenuPortalProps) => <Portal>{props.children}</Portal>\n\nconst DropdownMenuSub = ({ ...props }: DropdownMenuSubProps) => {\n  const root = useDropdownMenuSubRootContext()\n  const id = React.useId()\n  const [triggerElement, setTriggerElement] = React.useState<HTMLElement | null>(null)\n  const open = root?.openSubId === id\n  const setOpen = React.useCallback(\n    (nextOpen: boolean) => root?.setOpenSubId(nextOpen ? id : null),\n    [id, root]\n  )\n\n  return (\n    <DropdownMenuSubContext.Provider value={{ id, open, setOpen, triggerElement, setTriggerElement }}>\n      <div data-slot=\"dropdown-menu-sub\" data-state={open ? 'open' : 'closed'} {...props} />\n    </DropdownMenuSubContext.Provider>\n  )\n}\n\nconst DropdownMenuSubTrigger = React.forwardRef<HTMLDivElement, DropdownMenuSubTriggerProps>(\n  ({ className, inset, onClick, onPointerEnter, onKeyDown, ...props }, ref) => {\n    const sub = useDropdownMenuSubContext()\n\n    const handleClick = composeEventHandlers(onClick, () => {\n      sub.setOpen(!sub.open)\n    })\n\n    const handlePointerEnter = composeEventHandlers(onPointerEnter, () => {\n      sub.setOpen(true)\n    })\n\n    const handleKeyDown = composeEventHandlers(onKeyDown, (event: React.KeyboardEvent<HTMLDivElement>) => {\n      if (event.key === 'ArrowRight' || event.key === 'Enter' || event.key === ' ') {\n        event.preventDefault()\n        sub.setOpen(true)\n      }\n      if (event.key === 'ArrowLeft' || event.key === 'Escape') {\n        sub.setOpen(false)\n      }\n    })\n\n    return (\n      <div\n        ref={composeRefs(ref, sub.setTriggerElement)}\n        role=\"menuitem\"\n        tabIndex={-1}\n        aria-haspopup=\"menu\"\n        aria-expanded={sub.open}\n        data-slot=\"dropdown-menu-sub-trigger\"\n        data-state={sub.open ? 'open' : 'closed'}\n        onClick={handleClick}\n        onPointerEnter={handlePointerEnter}\n        onKeyDown={handleKeyDown}\n        {...props}\n        className={cn(dropdownMenuSubTriggerVariants(), inset && 'pl-8', className)}\n      />\n    )\n  }\n)\nDropdownMenuSubTrigger.displayName = 'DropdownMenuSubTrigger'\n\nconst DropdownMenuSubContent = React.forwardRef<HTMLDivElement, DropdownMenuSubContentProps>(\n  ({ className, style, onPointerEnter, onPointerLeave, onKeyDown, ...props }, ref) => {\n    const sub = useDropdownMenuSubContext()\n    const contentRef = React.useRef<HTMLDivElement | null>(null)\n    const [position, setPosition] = React.useState<{ left: number; top: number }>({ left: 0, top: 0 })\n\n    const updatePosition = React.useCallback(() => {\n      const trigger = sub.triggerElement\n      const content = contentRef.current\n      if (!trigger || !content) return\n\n      const rect = trigger.getBoundingClientRect()\n      const contentRect = content.getBoundingClientRect()\n      const gap = 6\n      const viewportPadding = 8\n\n      let left = rect.right + gap\n      if (left + contentRect.width > window.innerWidth - viewportPadding) {\n        left = rect.left - contentRect.width - gap\n      }\n\n      let top = rect.top\n      if (top + contentRect.height > window.innerHeight - viewportPadding) {\n        top = Math.max(viewportPadding, window.innerHeight - contentRect.height - viewportPadding)\n      }\n\n      setPosition({ left, top })\n    }, [sub.triggerElement])\n\n    React.useLayoutEffect(() => {\n      if (!sub.open) return\n      updatePosition()\n\n      const scheduleUpdate = () => {\n        requestAnimationFrame(updatePosition)\n      }\n\n      window.addEventListener('resize', scheduleUpdate)\n      window.addEventListener('scroll', scheduleUpdate, true)\n\n      return () => {\n        window.removeEventListener('resize', scheduleUpdate)\n        window.removeEventListener('scroll', scheduleUpdate, true)\n      }\n    }, [sub.open, updatePosition])\n\n    if (!sub.open) return null\n\n    const handlePointerEnter = composeEventHandlers(onPointerEnter, () => {\n      sub.setOpen(true)\n    })\n\n    const handlePointerLeave = composeEventHandlers(onPointerLeave, () => {\n      sub.setOpen(false)\n    })\n\n    const handleKeyDown = composeEventHandlers(onKeyDown, (event: React.KeyboardEvent<HTMLDivElement>) => {\n      if (event.key === 'Escape' || event.key === 'ArrowLeft') {\n        sub.setOpen(false)\n      }\n    })\n\n    return (\n      <Portal>\n        <div\n          ref={composeRefs(ref, contentRef)}\n          data-slot=\"dropdown-menu-sub-content\"\n          data-state=\"open\"\n          onPointerEnter={handlePointerEnter}\n          onPointerLeave={handlePointerLeave}\n          onKeyDown={handleKeyDown}\n          style={{ position: 'fixed', top: position.top, left: position.left, zIndex: 60, ...style }}\n          {...props}\n          className={cn(dropdownMenuSubContentVariants(), className)}\n        />\n      </Portal>\n    )\n  }\n)\nDropdownMenuSubContent.displayName = 'DropdownMenuSubContent'\n\ntype DropdownMenuRadioGroupProps = BaseDivProps & {\n  value?: string\n  onValueChange?: (value: string) => void\n}\n\nconst DropdownMenuRadioGroup = ({\n  value,\n  onValueChange,\n  ...props\n}: DropdownMenuRadioGroupProps) => {\n  const groupContextValue = React.useMemo(() => ({ value, onValueChange }), [onValueChange, value])\n  return (\n    <DropdownMenuRadioGroupProvider value={groupContextValue}>\n      <div data-slot=\"dropdown-menu-radio-group\" {...props} />\n    </DropdownMenuRadioGroupProvider>\n  )\n}\n\ntype DropdownMenuRadioItemProps = BaseDivProps & {\n  value: string\n  disabled?: boolean\n  onCheckedChange?: (next: boolean) => void\n}\n\nconst DropdownMenuRadioItem = React.forwardRef<HTMLDivElement, DropdownMenuRadioItemProps>(\n  ({ className, children, value, ...props }, ref) => {\n    const api = useDropdownMenuContext()\n    const group = useDropdownMenuRadioGroupContext()\n    const checked = group?.value === value\n    const { disabled, onCheckedChange, ...domProps } = props\n    const optionProps = api.getOptionItemProps({\n      type: 'radio',\n      checked,\n      value,\n      disabled,\n      onCheckedChange: (next: boolean) => {\n        if (next) group?.onValueChange?.(value)\n        onCheckedChange?.(next)\n      },\n    })\n\n    return (\n      <div\n        {...mergeProps(optionProps, domProps)}\n        ref={ref}\n        data-slot=\"dropdown-menu-radio-item\"\n        className={cn(dropdownMenuRadioItemVariants(), className)}\n      >\n        <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n          {checked && (\n            <svg aria-hidden=\"true\" viewBox=\"0 0 8 8\" fill=\"currentColor\" className=\"h-2 w-2\">\n              <circle cx=\"4\" cy=\"4\" r=\"3\" />\n            </svg>\n          )}\n        </span>\n        {children}\n      </div>\n    )\n  }\n)\nDropdownMenuRadioItem.displayName = 'DropdownMenuRadioItem'\n\ntype DropdownMenuShortcutProps = React.ComponentPropsWithoutRef<'span'>\n\nconst DropdownMenuShortcut = (props: DropdownMenuShortcutProps) => {\n  const { className, ...restProps } = props\n  return (\n    <span\n      data-slot=\"dropdown-menu-shortcut\"\n      {...restProps}\n      className={cn(dropdownMenuShortcutVariants(), className)}\n    />\n  )\n}\n\nexport {\n  DropdownMenu,\n  DropdownMenuTrigger,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuCheckboxItem,\n  DropdownMenuRadioItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n  DropdownMenuShortcut,\n  DropdownMenuGroup,\n  DropdownMenuPortal,\n  DropdownMenuSub,\n  DropdownMenuSubContent,\n  DropdownMenuSubTrigger,\n  DropdownMenuRadioGroup,\n}\n"
        },
        {
          "path": "registry/default/ui/dropdown-menu/use-dropdown-menu-context.tsx",
          "target": "components/ui/dropdown-menu/use-dropdown-menu-context.tsx",
          "type": "registry:ui",
          "content": "import * as React from 'react'\nimport type { menuConnect } from '@timui/core'\n\nexport type DropdownMenuApi = ReturnType<typeof menuConnect>\n\nexport const DropdownMenuContext: React.Context<DropdownMenuApi | null> =\n  React.createContext<DropdownMenuApi | null>(null)\nexport const DropdownMenuRadioGroupContext: React.Context<{\n  value?: string\n  onValueChange?: (value: string) => void\n} | null> = React.createContext<{\n  value?: string\n  onValueChange?: (value: string) => void\n} | null>(null)\n\nexport const DropdownMenuProvider: React.Provider<DropdownMenuApi | null> =\n  DropdownMenuContext.Provider\nexport const DropdownMenuRadioGroupProvider: React.Provider<{\n  value?: string\n  onValueChange?: (value: string) => void\n} | null> = DropdownMenuRadioGroupContext.Provider\n\nexport function useDropdownMenuContext(): DropdownMenuApi {\n  const context = React.useContext(DropdownMenuContext)\n  if (!context) {\n    throw new Error('useDropdownMenuContext must be used within a DropdownMenu component')\n  }\n  return context\n}\n\nexport function useDropdownMenuRadioGroupContext() {\n  const context = React.useContext(DropdownMenuRadioGroupContext)\n  if (!context) {\n    throw new Error(\n      'useDropdownMenuRadioGroupContext must be used within a DropdownMenuRadioGroup component'\n    )\n  }\n  return context\n}\n"
        },
        {
          "path": "registry/default/ui/dropdown-menu/use-dropdown-menu.ts",
          "target": "components/ui/dropdown-menu/use-dropdown-menu.ts",
          "type": "registry:ui",
          "content": "import * as React from 'react'\nimport { menuConnect, menuMachine } from '@timui/core'\nimport type { PositioningOptions } from '@zag-js/popper'\nimport { normalizeProps, useMachine } from '@zag-js/react'\n\nexport type DropdownMenuProps = {\n  id?: string\n  open?: boolean\n  defaultOpen?: boolean\n  closeOnSelect?: boolean\n  loopFocus?: boolean\n  positioning?: PositioningOptions\n  onOpenChange?: (open: boolean) => void\n  onSelect?: (value: string) => void\n  children?: React.ReactNode\n}\n\nexport function useDropdownMenu(props: DropdownMenuProps) {\n  const { onOpenChange, onSelect, ...menuProps } = props\n  const generatedId = React.useId()\n  const service = useMachine(menuMachine, {\n    id: menuProps.id ?? generatedId,\n    open: menuProps.open,\n    defaultOpen: menuProps.defaultOpen,\n    closeOnSelect: menuProps.closeOnSelect,\n    loopFocus: menuProps.loopFocus,\n    positioning: menuProps.positioning,\n    onOpenChange: (details: { open: boolean }) => onOpenChange?.(details.open),\n    onSelect: (details: { value: string }) => onSelect?.(details.value),\n  })\n  return menuConnect(service, normalizeProps)\n}\n"
        },
        {
          "path": "registry/default/vue/dropdown-menu/dropdown-menu-checkbox-item.vue",
          "target": "components/ui/dropdown-menu/dropdown-menu-checkbox-item.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { useDropdownMenuContext } from \"./use-dropdown-menu-context\";\nimport { computed, useId, type HTMLAttributes, type Ref } from \"vue\";\nimport { cn, dropdownMenuCheckboxItemVariants } from \"@timui/core\";\n\nconst props = defineProps<{\n  class?: HTMLAttributes[\"class\"];\n  checked?: boolean;\n  value?: string;\n  onCheckedChange?: (checked: boolean) => void;\n}>();\n\nconst emit = defineEmits([\"update:checked\", \"checkedChange\"]);\n\ntype DropdownCheckedDetails = { checked: boolean };\ntype BindValue = string | number | boolean | null | undefined | ((value: DropdownCheckedDetails) => void);\ntype DropdownMenuApi = {\n  getOptionItemProps: (options: {\n    type: \"radio\" | \"checkbox\";\n    checked?: boolean;\n    value: string;\n    onCheckedChange?: (details: DropdownCheckedDetails) => void;\n  }) => Record<string, BindValue>;\n};\n\nconst api = useDropdownMenuContext() as Ref<DropdownMenuApi | undefined> | undefined;\nconst generatedId = useId();\nconst optionValue = computed(() => props.value ?? generatedId);\n\nconst optionProps = computed(() => {\n  if (!api?.value) return {};\n  return api.value.getOptionItemProps({\n    type: \"checkbox\",\n    checked: props.checked,\n    value: optionValue.value,\n    onCheckedChange: (details: DropdownCheckedDetails) => {\n      props.onCheckedChange?.(details.checked);\n      emit(\"update:checked\", details.checked);\n      emit(\"checkedChange\", details.checked);\n    },\n  });\n});\n</script>\n\n<template>\n  <div\n    v-bind=\"optionProps\"\n    data-slot=\"dropdown-menu-checkbox-item\"\n    :class=\"\n      cn(\n        dropdownMenuCheckboxItemVariants(),\n        props.class\n      )\n    \"\n  >\n    <span class=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n      <svg\n        v-if=\"props.checked\"\n        aria-hidden=\"true\"\n        viewBox=\"0 0 16 16\"\n        fill=\"none\"\n        stroke=\"currentColor\"\n        stroke-width=\"2.5\"\n        stroke-linecap=\"round\"\n        stroke-linejoin=\"round\"\n        class=\"h-4 w-4\"\n      >\n        <path d=\"M3.5 8.5l3 3 6-7\" />\n      </svg>\n    </span>\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/dropdown-menu/dropdown-menu-content.vue",
          "target": "components/ui/dropdown-menu/dropdown-menu-content.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { useDropdownMenuContext } from \"./use-dropdown-menu-context\";\nimport { computed, watch, type HTMLAttributes, type ComputedRef } from \"vue\";\nimport { cn, dropdownMenuContentVariants } from \"@timui/core\";\nimport Presence from \"../presence/presence.vue\";\n\nconst props = withDefaults(\n  defineProps<{\n    class?: HTMLAttributes[\"class\"];\n    side?: \"top\" | \"bottom\" | \"left\" | \"right\";\n    align?: \"start\" | \"center\" | \"end\";\n    sideOffset?: number;\n  }>(),\n  {\n    side: \"bottom\",\n    align: \"center\",\n    sideOffset: 4,\n  }\n);\ntype BindValue = string | number | boolean | null | undefined | ((...args: never[]) => void);\ntype DropdownMenuApi = {\n  open?: boolean;\n  getPositionerProps?: () => Record<string, BindValue>;\n  getContentProps?: () => Record<string, BindValue>;\n  reposition?: (options: { placement: string; gutter?: number }) => void;\n};\n\nconst api = useDropdownMenuContext() as ComputedRef<DropdownMenuApi> | undefined;\nconst placement = computed(() =>\n  props.align === \"center\" ? props.side : `${props.side}-${props.align}`\n);\nconst positionerProps = computed(() => api?.value?.getPositionerProps?.() ?? {});\nconst contentProps = computed(() => api?.value?.getContentProps?.() ?? {});\n\nwatch(\n  () => [placement.value, props.sideOffset],\n  () => {\n    api?.value?.reposition?.({ placement: placement.value, gutter: props.sideOffset });\n  },\n  { immediate: true }\n);\n</script>\n\n<template>\n  <Teleport to=\"body\">\n    <Presence :present=\"api?.open ?? false\" :unmountOnExit=\"true\" v-bind=\"positionerProps\" style=\"z-index: 50\">\n      <div\n        v-bind=\"contentProps\"\n        data-slot=\"dropdown-menu-content\"\n        :class=\"\n          cn(\n            dropdownMenuContentVariants(),\n            props.class\n          )\n        \"\n      >\n        <slot />\n      </div>\n    </Presence>\n  </Teleport>\n</template>\n"
        },
        {
          "path": "registry/default/vue/dropdown-menu/dropdown-menu-group.vue",
          "target": "components/ui/dropdown-menu/dropdown-menu-group.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { useAttrs } from 'vue'\n\nconst attrs = useAttrs()\n</script>\n\n<template>\n  <div v-bind=\"attrs\" data-slot=\"dropdown-menu-group\">\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/dropdown-menu/dropdown-menu-item.vue",
          "target": "components/ui/dropdown-menu/dropdown-menu-item.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { useDropdownMenuContext } from \"./use-dropdown-menu-context\";\nimport { computed, useId, type Component, type HTMLAttributes, type ComputedRef } from \"vue\";\nimport { cn, dropdownMenuItemVariants } from \"@timui/core\";\nimport { Primitive } from '../../primitive';\n\nconst props = withDefaults(\n  defineProps<{\n    as?: string | Component;\n    asChild?: boolean;\n    class?: HTMLAttributes[\"class\"];\n    inset?: boolean;\n    value?: string;\n    disabled?: boolean;\n    closeOnSelect?: boolean;\n  }>(),\n  {\n    as: \"div\",\n  }\n);\n\ntype BindValue = string | number | boolean | null | undefined | ((...args: never[]) => void);\ntype DropdownMenuApi = {\n  getItemProps?: (options: {\n    value: string;\n    disabled?: boolean;\n    closeOnSelect?: boolean;\n  }) => Record<string, BindValue>;\n};\n\nconst api = useDropdownMenuContext() as ComputedRef<DropdownMenuApi> | undefined;\nconst generatedId = useId();\nconst itemValue = computed(() => props.value ?? generatedId);\nconst itemProps = computed(() => {\n  if (!api?.value) return {};\n  return api.value.getItemProps?.({\n    value: itemValue.value,\n    disabled: props.disabled,\n    closeOnSelect: props.closeOnSelect,\n  }) ?? {};\n});\n</script>\n\n<template>\n  <Primitive\n    :as=\"props.as\"\n    :as-child=\"props.asChild\"\n    v-bind=\"itemProps\"\n    data-slot=\"dropdown-menu-item\"\n    :class=\"\n      cn(\n        dropdownMenuItemVariants(),\n        props.inset && 'pl-8',\n        props.class\n      )\n    \"\n  >\n    <slot />\n  </Primitive>\n</template>\n"
        },
        {
          "path": "registry/default/vue/dropdown-menu/dropdown-menu-label.vue",
          "target": "components/ui/dropdown-menu/dropdown-menu-label.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, dropdownMenuLabelVariants } from \"@timui/core\";\nimport type { HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"]; inset?: boolean }>();\n</script>\n\n<template>\n  <div\n    data-slot=\"dropdown-menu-label\"\n    :class=\"cn(dropdownMenuLabelVariants(), props.inset && 'pl-8', props.class)\"\n  >\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/dropdown-menu/dropdown-menu-portal.vue",
          "target": "components/ui/dropdown-menu/dropdown-menu-portal.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nconst props = defineProps<{ to?: string }>()\n</script>\n\n<template>\n  <Teleport :to=\"props.to || 'body'\">\n    <slot />\n  </Teleport>\n</template>\n"
        },
        {
          "path": "registry/default/vue/dropdown-menu/dropdown-menu-radio-group.vue",
          "target": "components/ui/dropdown-menu/dropdown-menu-radio-group.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\nimport { provideDropdownMenuRadioGroupContext } from './use-dropdown-menu-context'\n\nconst props = defineProps<{\n  value?: string\n  modelValue?: string\n  onValueChange?: (value: string) => void\n}>()\nconst emit = defineEmits(['update:value', 'update:modelValue', 'change'])\nconst attrs = useAttrs()\n\nprovideDropdownMenuRadioGroupContext(\n  computed(() => ({\n    value: props.value ?? props.modelValue,\n    onValueChange(nextValue: string) {\n      props.onValueChange?.(nextValue)\n      emit('update:value', nextValue)\n      emit('update:modelValue', nextValue)\n      emit('change', nextValue)\n    },\n  }))\n)\n</script>\n\n<template>\n  <div v-bind=\"attrs\" data-slot=\"dropdown-menu-radio-group\">\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/dropdown-menu/dropdown-menu-radio-item.vue",
          "target": "components/ui/dropdown-menu/dropdown-menu-radio-item.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { useDropdownMenuContext, useDropdownMenuRadioGroupContext } from \"./use-dropdown-menu-context\";\nimport { computed, useId, type HTMLAttributes, type Ref } from \"vue\";\nimport { cn, dropdownMenuRadioItemVariants } from \"@timui/core\";\n\nconst props = defineProps<{\n  class?: HTMLAttributes[\"class\"];\n  checked?: boolean;\n  value?: string;\n  onCheckedChange?: (checked: boolean) => void;\n}>();\n\nconst emit = defineEmits([\"update:checked\", \"checkedChange\"]);\n\ntype DropdownCheckedDetails = { checked: boolean };\ntype BindValue = string | number | boolean | null | undefined | ((value: DropdownCheckedDetails) => void);\ntype DropdownMenuApi = {\n  getOptionItemProps: (options: {\n    type: \"radio\" | \"checkbox\";\n    checked?: boolean;\n    value: string;\n    onCheckedChange?: (details: DropdownCheckedDetails) => void;\n  }) => Record<string, BindValue>;\n};\n\nconst api = useDropdownMenuContext() as Ref<DropdownMenuApi | undefined> | undefined;\nconst group = useDropdownMenuRadioGroupContext();\nconst generatedId = useId();\nconst optionValue = computed(() => props.value ?? generatedId);\nconst isChecked = computed(() =>\n  group ? group.value.value === optionValue.value : !!props.checked\n);\n\nconst optionProps = computed(() => {\n  if (!api?.value) return {};\n  return api.value.getOptionItemProps({\n    type: \"radio\",\n    checked: isChecked.value,\n    value: optionValue.value,\n    onCheckedChange: (details: DropdownCheckedDetails) => {\n      if (details.checked) {\n        group?.value.onValueChange?.(optionValue.value);\n      }\n      props.onCheckedChange?.(details.checked);\n      emit(\"update:checked\", details.checked);\n      emit(\"checkedChange\", details.checked);\n    },\n  });\n});\n</script>\n\n<template>\n  <div\n    v-bind=\"optionProps\"\n    data-slot=\"dropdown-menu-radio-item\"\n    :class=\"\n      cn(\n        dropdownMenuRadioItemVariants(),\n        props.class\n      )\n    \"\n  >\n    <span class=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n      <svg\n        v-if=\"isChecked\"\n        aria-hidden=\"true\"\n        viewBox=\"0 0 8 8\"\n        fill=\"currentColor\"\n        class=\"h-2 w-2\"\n      >\n        <circle cx=\"4\" cy=\"4\" r=\"3\" />\n      </svg>\n    </span>\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/dropdown-menu/dropdown-menu-separator.vue",
          "target": "components/ui/dropdown-menu/dropdown-menu-separator.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { useDropdownMenuContext } from \"./use-dropdown-menu-context\";\nimport { computed, inject, type HTMLAttributes, type ComputedRef } from \"vue\";\nimport { cn, dropdownMenuSeparatorVariants } from \"@timui/core\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\ntype BindValue = string | number | boolean | null | undefined | ((...args: never[]) => void);\ntype DropdownMenuApi = {\n  getSeparatorProps?: () => Record<string, BindValue>;\n};\nconst api = useDropdownMenuContext() as ComputedRef<DropdownMenuApi> | undefined;\nconst separatorProps = computed(() => api?.value?.getSeparatorProps?.() ?? {});\n</script>\n\n<template>\n  <div\n    v-bind=\"separatorProps\"\n    data-slot=\"dropdown-menu-separator\"\n    :class=\"cn(dropdownMenuSeparatorVariants(), props.class)\"\n  >\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/dropdown-menu/dropdown-menu-shortcut.vue",
          "target": "components/ui/dropdown-menu/dropdown-menu-shortcut.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes } from 'vue'\nimport { cn, dropdownMenuShortcutVariants } from '@timui/core'\n\nconst props = defineProps<{\n  class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n  <span\n    data-slot=\"dropdown-menu-shortcut\"\n    :class=\"cn(dropdownMenuShortcutVariants(), props.class)\"\n  >\n    <slot />\n  </span>\n</template>\n"
        },
        {
          "path": "registry/default/vue/dropdown-menu/dropdown-menu-sub-content.vue",
          "target": "components/ui/dropdown-menu/dropdown-menu-sub-content.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, dropdownMenuSubContentVariants } from '@timui/core'\nimport { nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'\nimport type { HTMLAttributes, CSSProperties } from 'vue'\n\nimport { useDropdownMenuSubContext } from './use-dropdown-menu-sub-context'\n\nconst props = defineProps<{ class?: HTMLAttributes['class'] }>()\nconst subContext = useDropdownMenuSubContext()\nconst contentRef = ref<HTMLElement | null>(null)\nconst contentStyle = ref<CSSProperties>({\n  position: 'fixed',\n  top: '0px',\n  left: '0px',\n  zIndex: 60,\n})\n\nconst updatePosition = () => {\n  if (!subContext?.triggerElement.value || !contentRef.value) return\n\n  const triggerRect = subContext.triggerElement.value.getBoundingClientRect()\n  const contentRect = contentRef.value.getBoundingClientRect()\n  const gap = 6\n  const viewportPadding = 8\n\n  let left = triggerRect.right + gap\n  if (left + contentRect.width > window.innerWidth - viewportPadding) {\n    left = triggerRect.left - contentRect.width - gap\n  }\n\n  let top = triggerRect.top\n  if (top + contentRect.height > window.innerHeight - viewportPadding) {\n    top = Math.max(viewportPadding, window.innerHeight - contentRect.height - viewportPadding)\n  }\n\n  contentStyle.value = {\n    position: 'fixed',\n    top: `${top}px`,\n    left: `${left}px`,\n    zIndex: 60,\n  }\n}\n\nconst scheduleUpdate = () => {\n  requestAnimationFrame(() => updatePosition())\n}\n\nwatch(\n  () => subContext?.open.value ?? false,\n  async (isOpen) => {\n    if (!isOpen) return\n    await nextTick()\n    updatePosition()\n  },\n  { immediate: true }\n)\n\nonMounted(() => {\n  window.addEventListener('resize', scheduleUpdate)\n  window.addEventListener('scroll', scheduleUpdate, true)\n})\n\nonBeforeUnmount(() => {\n  window.removeEventListener('resize', scheduleUpdate)\n  window.removeEventListener('scroll', scheduleUpdate, true)\n})\n\nconst onPointerEnter = () => {\n  subContext?.setOpen(true)\n}\n\nconst onPointerLeave = () => {\n  subContext?.setOpen(false)\n}\n\nconst onKeyDown = (event: KeyboardEvent) => {\n  if (!subContext) return\n  if (event.key === 'Escape' || event.key === 'ArrowLeft') {\n    subContext.setOpen(false)\n  }\n}\n</script>\n\n<template>\n  <Teleport to=\"body\">\n    <div\n      v-if=\"subContext?.open.value\"\n      ref=\"contentRef\"\n      data-slot=\"dropdown-menu-sub-content\"\n      data-state=\"open\"\n      :style=\"contentStyle\"\n      @pointerenter=\"onPointerEnter\"\n      @pointerleave=\"onPointerLeave\"\n      @keydown=\"onKeyDown\"\n      :class=\"\n        cn(\n          dropdownMenuSubContentVariants(),\n          props.class\n        )\n      \"\n    >\n      <slot />\n    </div>\n  </Teleport>\n</template>\n"
        },
        {
          "path": "registry/default/vue/dropdown-menu/dropdown-menu-sub-trigger.vue",
          "target": "components/ui/dropdown-menu/dropdown-menu-sub-trigger.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, dropdownMenuSubTriggerVariants } from '@timui/core'\nimport { ChevronRightIcon } from 'lucide-vue-next'\nimport { ref, watchEffect } from 'vue'\nimport type { HTMLAttributes } from 'vue'\n\nimport { useDropdownMenuSubContext } from './use-dropdown-menu-sub-context'\n\nconst props = defineProps<{ class?: HTMLAttributes['class']; inset?: boolean }>()\nconst subContext = useDropdownMenuSubContext()\nconst triggerRef = ref<HTMLElement | null>(null)\n\nwatchEffect(() => {\n  if (!subContext) return\n  subContext.triggerElement.value = triggerRef.value\n})\n\nconst onPointerEnter = () => {\n  subContext?.setOpen(true)\n}\n\nconst onClick = () => {\n  if (!subContext) return\n  subContext.setOpen(!subContext.open.value)\n}\n\nconst onKeyDown = (event: KeyboardEvent) => {\n  if (!subContext) return\n  if (event.key === 'ArrowRight' || event.key === 'Enter' || event.key === ' ') {\n    event.preventDefault()\n    subContext.setOpen(true)\n  }\n  if (event.key === 'ArrowLeft' || event.key === 'Escape') {\n    subContext.setOpen(false)\n  }\n}\n</script>\n\n<template>\n  <div\n    ref=\"triggerRef\"\n    data-slot=\"dropdown-menu-sub-trigger\"\n    role=\"menuitem\"\n    tabindex=\"-1\"\n    aria-haspopup=\"menu\"\n    :aria-expanded=\"subContext?.open.value ?? false\"\n    :data-state=\"subContext?.open.value ? 'open' : 'closed'\"\n    @pointerenter=\"onPointerEnter\"\n    @click=\"onClick\"\n    @keydown=\"onKeyDown\"\n    :class=\"\n      cn(\n        dropdownMenuSubTriggerVariants(),\n        props.inset && 'pl-8',\n        props.class\n      )\n    \"\n  >\n    <slot />\n    <ChevronRightIcon aria-hidden=\"true\" class=\"ml-auto h-4 w-4\" />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/dropdown-menu/dropdown-menu-sub.vue",
          "target": "components/ui/dropdown-menu/dropdown-menu-sub.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { watch } from 'vue'\nimport { useDropdownMenuContext } from './use-dropdown-menu-context'\nimport {\n  createDropdownMenuSubContext,\n  provideDropdownMenuSubContext,\n} from './use-dropdown-menu-sub-context'\nimport { useAttrs } from 'vue'\n\nconst attrs = useAttrs()\nconst api = useDropdownMenuContext()\nconst subContext = createDropdownMenuSubContext()\n\nprovideDropdownMenuSubContext(subContext)\n\nwatch(\n  () => api.value.open,\n  (isOpen) => {\n    if (!isOpen) {\n      subContext.setOpen(false)\n    }\n  }\n)\n</script>\n\n<template>\n  <div v-bind=\"attrs\" data-slot=\"dropdown-menu-sub\" :data-state=\"subContext.open.value ? 'open' : 'closed'\">\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/dropdown-menu/dropdown-menu-trigger.vue",
          "target": "components/ui/dropdown-menu/dropdown-menu-trigger.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { useDropdownMenuContext } from \"./use-dropdown-menu-context\";\nimport { computed, inject, type Component, type HTMLAttributes, type ComputedRef } from \"vue\";\nimport { cn } from \"@timui/core\";\nimport { Primitive } from '../../primitive';\n\nconst props = withDefaults(\n  defineProps<{\n    as?: string | Component;\n    asChild?: boolean;\n    class?: HTMLAttributes[\"class\"];\n  }>(),\n  {\n    as: \"button\",\n  }\n);\n\ntype BindValue = string | number | boolean | null | undefined | ((...args: never[]) => void);\ntype DropdownMenuApi = {\n  getTriggerProps?: () => Record<string, BindValue>;\n};\n\nconst api = useDropdownMenuContext() as ComputedRef<DropdownMenuApi> | undefined;\nconst triggerProps = computed(() => ({\n  type: props.asChild ? undefined : \"button\",\n  \"data-slot\": \"dropdown-menu-trigger\",\n  ...(api?.value?.getTriggerProps?.() ?? {}),\n}));\n</script>\n\n<template>\n  <Primitive\n    :as=\"props.as\"\n    :as-child=\"props.asChild\"\n    v-bind=\"triggerProps\"\n    :class=\"cn(props.class)\"\n  >\n    <slot />\n  </Primitive>\n</template>\n"
        },
        {
          "path": "registry/default/vue/dropdown-menu/dropdown-menu.vue",
          "target": "components/ui/dropdown-menu/dropdown-menu.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, type HTMLAttributes } from \"vue\";\nimport type { PositioningOptions } from \"@zag-js/popper\";\nimport { useDropdownMenu } from \"./use-dropdown-menu\";\nimport { DropdownMenuProvider } from \"./use-dropdown-menu-context\";\n\nconst props = defineProps<{\n  id?: string;\n  open?: boolean;\n  defaultOpen?: boolean;\n  closeOnSelect?: boolean;\n  loopFocus?: boolean;\n  positioning?: PositioningOptions;\n  onOpenChange?: (open: boolean) => void;\n  class?: HTMLAttributes[\"class\"];\n}>();\n\nconst emit = defineEmits([\"update:open\", \"change\"]);\n\nconst api = useDropdownMenu(props, emit);\nDropdownMenuProvider(api);\n</script>\n\n<template>\n  <slot />\n</template>\n"
        },
        {
          "path": "registry/default/vue/dropdown-menu/use-dropdown-menu-context.ts",
          "target": "components/ui/dropdown-menu/use-dropdown-menu-context.ts",
          "type": "registry:component",
          "content": "import type { MenuApi } from '@timui/core'\nimport { inject, provide, type ComputedRef } from 'vue'\n\nimport { createContext } from '../../hooks/create-context'\n\nconst context = createContext<ComputedRef<MenuApi>>({\n  id: 'dropdownMenuContext',\n  providerName: '<DropdownMenu />',\n})\n\nexport const DropdownMenuProvider: (value: ComputedRef<MenuApi>) => void = context[0]\nexport const useDropdownMenuContext: (fallback?: ComputedRef<MenuApi>) => ComputedRef<MenuApi> =\n  context[1]\n\nexport type DropdownMenuRadioGroupContextValue = {\n  value?: string\n  onValueChange?: (value: string) => void\n}\n\nexport const DropdownMenuRadioGroupContextKey = Symbol('DropdownMenuRadioGroupContext')\n\nexport function provideDropdownMenuRadioGroupContext(\n  value: ComputedRef<DropdownMenuRadioGroupContextValue>\n) {\n  provide(DropdownMenuRadioGroupContextKey, value)\n}\n\nexport function useDropdownMenuRadioGroupContext() {\n  return inject<ComputedRef<DropdownMenuRadioGroupContextValue> | undefined>(\n    DropdownMenuRadioGroupContextKey,\n    undefined\n  )\n}\n"
        },
        {
          "path": "registry/default/vue/dropdown-menu/use-dropdown-menu-sub-context.ts",
          "target": "components/ui/dropdown-menu/use-dropdown-menu-sub-context.ts",
          "type": "registry:component",
          "content": "import { inject, provide, ref, type InjectionKey, type Ref } from 'vue'\n\nexport type DropdownMenuSubContextValue = {\n  open: Ref<boolean>\n  setOpen: (open: boolean) => void\n  triggerElement: Ref<HTMLElement | null>\n}\n\nconst dropdownMenuSubContextKey: InjectionKey<DropdownMenuSubContextValue> = Symbol(\n  'DropdownMenuSubContext'\n)\n\nexport function createDropdownMenuSubContext(): DropdownMenuSubContextValue {\n  const open = ref(false)\n  const triggerElement = ref<HTMLElement | null>(null)\n\n  return {\n    open,\n    triggerElement,\n    setOpen(nextOpen: boolean) {\n      open.value = nextOpen\n    },\n  }\n}\n\nexport function provideDropdownMenuSubContext(value: DropdownMenuSubContextValue) {\n  provide(dropdownMenuSubContextKey, value)\n}\n\nexport function useDropdownMenuSubContext() {\n  return inject(dropdownMenuSubContextKey, null)\n}\n"
        },
        {
          "path": "registry/default/vue/dropdown-menu/use-dropdown-menu.ts",
          "target": "components/ui/dropdown-menu/use-dropdown-menu.ts",
          "type": "registry:component",
          "content": "import { menuConnect, menuMachine } from '@timui/core'\nimport type { PositioningOptions } from '@zag-js/popper'\nimport { normalizeProps, useMachine } from '@zag-js/vue'\nimport { computed, useId } from 'vue'\n\ntype UseDropdownMenuProps = {\n  id?: string\n  open?: boolean\n  defaultOpen?: boolean\n  closeOnSelect?: boolean\n  loopFocus?: boolean\n  positioning?: PositioningOptions\n  onOpenChange?: (open: boolean) => void\n}\n\nexport function useDropdownMenu(\n  props: UseDropdownMenuProps,\n  emit: (event: 'update:open' | 'change', value: boolean) => void\n) {\n  const generatedId = useId()\n\n  const machineProps = computed(() => ({\n    id: props.id ?? generatedId,\n    open: props.open,\n    defaultOpen: props.open === undefined ? props.defaultOpen : undefined,\n    closeOnSelect: props.closeOnSelect,\n    loopFocus: props.loopFocus,\n    positioning: props.positioning,\n    onOpenChange(details: { open: boolean }) {\n      props.onOpenChange?.(details.open)\n      emit('update:open', details.open)\n      emit('change', details.open)\n    },\n  }))\n\n  const service = useMachine(menuMachine, machineProps)\n  const api = computed(() => menuConnect(service, normalizeProps))\n\n  return api\n}\n"
        },
        {
          "path": "registry/default/html/dropdown-menu.html",
          "target": "components/ui/dropdown-menu.html",
          "type": "registry:component",
          "content": "<div data-timui-root data-timui-init=\"auto\">\n  <div class=\"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50\">\n      <!-- Trigger -->\n      <button type=\"button\" data-slot=\"dropdown-menu-trigger\"\n          class=\"mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n          aria-expanded=\"false\" aria-haspopup=\"true\">\n          Options\n      </button>\n\n      <!-- Content (Open) -->\n      <div data-slot=\"dropdown-menu-content\" data-state=\"closed\" hidden class=\"absolute right-0 z-50 mt-2 w-56 origin-top-right rounded-md border bg-popover p-1 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95\"\n          role=\"menu\" tabindex=\"-1\">\n          <div data-slot=\"dropdown-menu-item\" class=\"relative flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50\"\n              role=\"menuitem\">\n              Profile\n          </div>\n          <div data-slot=\"dropdown-menu-item\" class=\"relative flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50\"\n              role=\"menuitem\">\n              Billing\n          </div>\n          <div data-slot=\"dropdown-menu-item\" class=\"relative flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50\"\n              role=\"menuitem\">\n              Team\n          </div>\n          <div data-slot=\"dropdown-menu-item\" class=\"relative flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50\"\n              role=\"menuitem\">\n              Subscription\n          </div>\n      </div>\n  </div>\n</div>\n<script type=\"module\">\n  import { autoInitHtmlRuntime } from '@timui/html'\n  autoInitHtmlRuntime({ components: ['dropdown-menu'] })\n</script>"
        },
        {
          "path": "registry/default/weapp/dropdown-menu.wxml",
          "target": "components/ui/dropdown-menu.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\">\n  <!-- Trigger -->\n  <view \n    class=\"dropdown-trigger\"\n    bindtap=\"onTriggerTap\"\n  >\n    <slot name=\"trigger\"></slot>\n  </view>\n\n  <!-- Backdrop -->\n  <view \n    wx:if=\"{{api.open}}\"\n    class=\"dropdown-backdrop\"\n    bindtap=\"onBackdropTap\"\n  ></view>\n\n  <!-- Menu Content -->\n  <view \n    wx:if=\"{{api.open}}\"\n    class=\"dropdown-content\"\n    data-state=\"{{api.open ? 'open' : 'closed'}}\"\n  >\n    <slot name=\"content\"></slot>\n  </view>\n</view>\n\n<!-- 使用示例：\n<dropdown-menu bind:select=\"handleSelect\">\n  <view slot=\"trigger\">菜单</view>\n  <view slot=\"content\">\n    <view class=\"dropdown-item\" data-value=\"item1\" bindtap=\"onItemTap\">选项 1</view>\n    <view class=\"dropdown-item\" data-value=\"item2\" bindtap=\"onItemTap\">选项 2</view>\n  </view>\n</dropdown-menu>\n-->\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu.wxss",
          "target": "components/ui/dropdown-menu.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/dropdown-menu.ts",
          "target": "components/ui/dropdown-menu.ts",
          "type": "registry:component",
          "content": "// @ts-nocheck\nimport { emitTimEvent } from '../utils'\nimport {\n  createWeappBaseProps,\n  createWeappOptions,\n  WEAPP_EXTERNAL_CLASSES,\n} from '../utils/component'\nimport {\n  connectDropdownMenuMachine,\n  setupDropdownMenuMachine,\n  type WeappDropdownMenuApi,\n  type WeappDropdownMenuService,\n} from './use-dropdown-menu'\n\ntype MenuItemTapEvent = WechatMiniprogram.BaseEvent & {\n  currentTarget: {\n    dataset: {\n      value?: string\n    }\n  }\n}\n\ntype WeappDropdownMenuInternal = WechatMiniprogram.Component.InstanceMethods<{}> & {\n  _service?: WeappDropdownMenuService\n  _cleanup?: () => void\n  _send?: (event: object) => void\n  data: {\n    api: WeappDropdownMenuApi\n  }\n  properties: {\n    open: boolean\n    closeOnSelect: boolean\n    id: string\n    extClass: string\n  }\n}\n\nComponent({\n  options: createWeappOptions({ pureData: true }),\n\n  externalClasses: WEAPP_EXTERNAL_CLASSES,\n\n  properties: {\n    open: { type: Boolean, value: false },\n    closeOnSelect: { type: Boolean, value: true },\n    ...createWeappBaseProps('dropdown-menu'),\n  },\n\n  data: {\n    api: {} as WeappDropdownMenuApi,\n    className: '',\n  },\n\n  lifetimes: {\n    attached() {\n      const self = this as WeappDropdownMenuInternal\n      const { service, cleanup, send } = setupDropdownMenuMachine(this, {\n        id: this.properties.id,\n        open: this.properties.open,\n        closeOnSelect: this.properties.closeOnSelect,\n        onOpenChange: (details) => {\n          this.triggerEvent('change', details)\n          emitTimEvent(\n            this,\n            'openchange',\n            'dropdownMenu.openChange',\n            this.properties.id || 'dropdown-menu',\n            {\n              open: details.open,\n            }\n          )\n        },\n        onSelect: (details) => {\n          this.triggerEvent('select', details)\n        },\n      })\n\n      self._service = service\n      self._cleanup = cleanup\n      self._send = send\n    },\n    detached() {\n      const self = this as WeappDropdownMenuInternal\n      self._cleanup?.()\n    },\n  },\n\n  observers: {\n    state: function (state) {\n      const self = this as WeappDropdownMenuInternal\n      if (!state || !self._send) return\n      const api = connectDropdownMenuMachine(state, self._send)\n      this.setData({ api, className: this.properties.extClass })\n    },\n  },\n\n  methods: {\n    onTriggerTap() {\n      const self = this as WeappDropdownMenuInternal\n      self.data.api.triggerProps?.onClick?.()\n    },\n    onItemTap(e: MenuItemTapEvent) {\n      const self = this as WeappDropdownMenuInternal\n      const value = e.currentTarget.dataset.value\n      if (value && self.data.api.selectItem) {\n        self.data.api.selectItem({ value })\n      }\n    },\n    onBackdropTap() {\n      const self = this as WeappDropdownMenuInternal\n      self.data.api.setOpen?.(false)\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu.json",
          "target": "components/ui/dropdown-menu.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-checkbox-item/dropdown-menu-checkbox-item.wxml",
          "target": "components/ui/dropdown-menu-checkbox-item/dropdown-menu-checkbox-item.wxml",
          "type": "registry:component",
          "content": "<view\n  data-slot=\"dropdown-menu-checkbox-item\"\n  class=\"{{className}}\"\n  data-state=\"{{checked ? 'checked' : 'unchecked'}}\"\n  data-disabled=\"{{disabled}}\"\n  bindtap=\"onToggle\"\n>\n  <view class=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n    <image\n      wx:if=\"{{checked}}\"\n      class=\"h-4 w-4\"\n      src=\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMy41IDguNWwzIDMgNi03IiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPjwvc3ZnPg==\"\n    />\n  </view>\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-checkbox-item/dropdown-menu-checkbox-item.wxss",
          "target": "components/ui/dropdown-menu-checkbox-item/dropdown-menu-checkbox-item.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/dropdown-menu-checkbox-item/dropdown-menu-checkbox-item.json",
          "target": "components/ui/dropdown-menu-checkbox-item/dropdown-menu-checkbox-item.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-checkbox-item/dropdown-menu-checkbox-item.ts",
          "target": "components/ui/dropdown-menu-checkbox-item/dropdown-menu-checkbox-item.ts",
          "type": "registry:component",
          "content": "import { emitTimEvent, resolveClasses } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  relations: {\n    '../dropdown-menu/dropdown-menu': {\n      type: 'parent',\n    },\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    checked: { type: Boolean, value: false },\n    disabled: { type: Boolean, value: false },\n    closeOnSelect: { type: Boolean, value: false },\n    id: { type: String, value: 'dropdown-menu-checkbox-item' },\n    extClass: { type: String, value: '' },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass: string) {\n      const base =\n        'relative flex cursor-default select-none items-center rounded-sm py-3 pl-8 pr-2 text-sm'\n      this.setData({\n        className: resolveClasses(base, extClass),\n      })\n    },\n  },\n  methods: {\n    onToggle() {\n      if (this.properties.disabled) return\n      const nextChecked = !this.properties.checked\n      emitTimEvent(this, 'change', 'change', this.properties.id || 'dropdown-menu-checkbox-item', {\n        checked: nextChecked,\n      })\n      if (this.properties.closeOnSelect) {\n        const parents = this.getRelationNodes('../dropdown-menu/dropdown-menu')\n        if (parents.length) {\n          parents[0].close()\n        }\n      }\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-content/dropdown-menu-content.wxml",
          "target": "components/ui/dropdown-menu-content/dropdown-menu-content.wxml",
          "type": "registry:component",
          "content": "<view\n  wx:if=\"{{visible}}\"\n  id=\"dropdown-menu-content\"\n  data-slot=\"dropdown-menu-content\"\n  data-state=\"{{visible ? 'open' : 'closed'}}\"\n  class=\"{{className}}\"\n  style=\"{{style}}\"\n  catchtouchmove=\"noop\"\n>\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-content/dropdown-menu-content.wxss",
          "target": "components/ui/dropdown-menu-content/dropdown-menu-content.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/dropdown-menu-content/dropdown-menu-content.json",
          "target": "components/ui/dropdown-menu-content/dropdown-menu-content.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-content/dropdown-menu-content.ts",
          "target": "components/ui/dropdown-menu-content/dropdown-menu-content.ts",
          "type": "registry:component",
          "content": "import { resolveClasses } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  relations: {\n    '../dropdown-menu/dropdown-menu': {\n      type: 'parent',\n    },\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: { type: String, value: '' },\n  },\n  data: {\n    visible: false,\n    style: 'opacity: 0;',\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass: string) {\n      this.setData({\n        className: resolveClasses(\n          'z-50 min-w-40 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md',\n          extClass\n        ),\n      })\n    },\n  },\n  methods: {\n    showForMeasure() {\n      this.setData({\n        visible: true,\n        style: 'position: fixed; top: 0; left: 0; opacity: 0; pointer-events: none;',\n      })\n    },\n    updatePosition(top: number, left: number) {\n      this.setData({\n        style: `position: fixed; top: ${top}px; left: ${left}px; opacity: 1; transition: opacity 0.2s;`,\n      })\n    },\n    hide() {\n      this.setData({ visible: false, style: 'opacity: 0;' })\n    },\n    getRect() {\n      return new Promise((resolve) => {\n        this.createSelectorQuery()\n          .select('#dropdown-menu-content')\n          .boundingClientRect((rect) => {\n            resolve(rect)\n          })\n          .exec()\n      })\n    },\n    noop() {},\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-group/dropdown-menu-group.wxml",
          "target": "components/ui/dropdown-menu-group/dropdown-menu-group.wxml",
          "type": "registry:component",
          "content": "<view data-slot=\"dropdown-menu-group\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-group/dropdown-menu-group.wxss",
          "target": "components/ui/dropdown-menu-group/dropdown-menu-group.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/dropdown-menu-group/dropdown-menu-group.json",
          "target": "components/ui/dropdown-menu-group/dropdown-menu-group.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-group/dropdown-menu-group.ts",
          "target": "components/ui/dropdown-menu-group/dropdown-menu-group.ts",
          "type": "registry:component",
          "content": "Component({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    extClass: { type: String, value: '' },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-item/dropdown-menu-item.wxml",
          "target": "components/ui/dropdown-menu-item/dropdown-menu-item.wxml",
          "type": "registry:component",
          "content": "<view\n  data-slot=\"dropdown-menu-item\"\n  class=\"{{className}}\"\n  data-disabled=\"{{disabled}}\"\n  bindtap=\"onSelect\"\n>\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-item/dropdown-menu-item.wxss",
          "target": "components/ui/dropdown-menu-item/dropdown-menu-item.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/dropdown-menu-item/dropdown-menu-item.json",
          "target": "components/ui/dropdown-menu-item/dropdown-menu-item.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-item/dropdown-menu-item.ts",
          "target": "components/ui/dropdown-menu-item/dropdown-menu-item.ts",
          "type": "registry:component",
          "content": "import { resolveClasses } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  relations: {\n    '../dropdown-menu/dropdown-menu': {\n      type: 'parent',\n    },\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    disabled: { type: Boolean, value: false },\n    inset: { type: Boolean, value: false },\n    closeOnSelect: { type: Boolean, value: true },\n    extClass: { type: String, value: '' },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    'extClass, inset': function (extClass: string, inset: boolean) {\n      const base =\n        'relative flex cursor-default select-none items-center rounded-sm px-2 py-3 text-sm'\n      const insetClass = inset ? 'pl-8' : ''\n      this.setData({\n        className: resolveClasses(base, insetClass, extClass),\n      })\n    },\n  },\n  methods: {\n    onSelect() {\n      if (this.properties.disabled) return\n      this.triggerEvent('select')\n      if (this.properties.closeOnSelect) {\n        const parents = this.getRelationNodes('../dropdown-menu/dropdown-menu')\n        if (parents.length) {\n          parents[0].close()\n        }\n      }\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-label/dropdown-menu-label.wxml",
          "target": "components/ui/dropdown-menu-label/dropdown-menu-label.wxml",
          "type": "registry:component",
          "content": "<view data-slot=\"dropdown-menu-label\" class=\"{{className}}\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-label/dropdown-menu-label.wxss",
          "target": "components/ui/dropdown-menu-label/dropdown-menu-label.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/dropdown-menu-label/dropdown-menu-label.json",
          "target": "components/ui/dropdown-menu-label/dropdown-menu-label.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-label/dropdown-menu-label.ts",
          "target": "components/ui/dropdown-menu-label/dropdown-menu-label.ts",
          "type": "registry:component",
          "content": "import { resolveClasses } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    inset: { type: Boolean, value: false },\n    extClass: { type: String, value: '' },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    'extClass, inset': function (extClass: string, inset: boolean) {\n      const base = 'px-2 py-1.5 text-sm font-semibold'\n      const insetClass = inset ? 'pl-8' : ''\n      this.setData({\n        className: resolveClasses(base, insetClass, extClass),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-radio-item/dropdown-menu-radio-item.wxml",
          "target": "components/ui/dropdown-menu-radio-item/dropdown-menu-radio-item.wxml",
          "type": "registry:component",
          "content": "<view\n  data-slot=\"dropdown-menu-radio-item\"\n  class=\"{{className}}\"\n  data-state=\"{{checked ? 'checked' : 'unchecked'}}\"\n  data-disabled=\"{{disabled}}\"\n  bindtap=\"onSelect\"\n>\n  <view class=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n    <view wx:if=\"{{checked}}\" class=\"h-2 w-2 rounded-full bg-current\"></view>\n  </view>\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-radio-item/dropdown-menu-radio-item.wxss",
          "target": "components/ui/dropdown-menu-radio-item/dropdown-menu-radio-item.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/dropdown-menu-radio-item/dropdown-menu-radio-item.json",
          "target": "components/ui/dropdown-menu-radio-item/dropdown-menu-radio-item.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-radio-item/dropdown-menu-radio-item.ts",
          "target": "components/ui/dropdown-menu-radio-item/dropdown-menu-radio-item.ts",
          "type": "registry:component",
          "content": "import { emitTimEvent, resolveClasses } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  relations: {\n    '../dropdown-menu/dropdown-menu': {\n      type: 'parent',\n    },\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    value: { type: String, value: '' },\n    checked: { type: Boolean, value: false },\n    disabled: { type: Boolean, value: false },\n    closeOnSelect: { type: Boolean, value: true },\n    id: { type: String, value: 'dropdown-menu-radio-item' },\n    extClass: { type: String, value: '' },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass: string) {\n      const base =\n        'relative flex cursor-default select-none items-center rounded-sm py-3 pl-8 pr-2 text-sm'\n      this.setData({\n        className: resolveClasses(base, extClass),\n      })\n    },\n  },\n  methods: {\n    onSelect() {\n      if (this.properties.disabled) return\n      emitTimEvent(this, 'change', 'change', this.properties.id || 'dropdown-menu-radio-item', {\n        value: this.properties.value,\n      })\n      if (this.properties.closeOnSelect) {\n        const parents = this.getRelationNodes('../dropdown-menu/dropdown-menu')\n        if (parents.length) {\n          parents[0].close()\n        }\n      }\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-separator/dropdown-menu-separator.wxml",
          "target": "components/ui/dropdown-menu-separator/dropdown-menu-separator.wxml",
          "type": "registry:component",
          "content": "<view data-slot=\"dropdown-menu-separator\" class=\"{{className}}\"></view>\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-separator/dropdown-menu-separator.wxss",
          "target": "components/ui/dropdown-menu-separator/dropdown-menu-separator.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/dropdown-menu-separator/dropdown-menu-separator.json",
          "target": "components/ui/dropdown-menu-separator/dropdown-menu-separator.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-separator/dropdown-menu-separator.ts",
          "target": "components/ui/dropdown-menu-separator/dropdown-menu-separator.ts",
          "type": "registry:component",
          "content": "import { resolveClasses } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: { type: String, value: '' },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass: string) {\n      this.setData({\n        className: resolveClasses('-mx-1 my-1 h-px bg-muted', extClass),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-shortcut/dropdown-menu-shortcut.wxml",
          "target": "components/ui/dropdown-menu-shortcut/dropdown-menu-shortcut.wxml",
          "type": "registry:component",
          "content": "<text data-slot=\"dropdown-menu-shortcut\" class=\"{{className}}\">\n  <slot></slot>\n</text>\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-shortcut/dropdown-menu-shortcut.wxss",
          "target": "components/ui/dropdown-menu-shortcut/dropdown-menu-shortcut.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/dropdown-menu-shortcut/dropdown-menu-shortcut.json",
          "target": "components/ui/dropdown-menu-shortcut/dropdown-menu-shortcut.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-shortcut/dropdown-menu-shortcut.ts",
          "target": "components/ui/dropdown-menu-shortcut/dropdown-menu-shortcut.ts",
          "type": "registry:component",
          "content": "import { resolveClasses } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: { type: String, value: '' },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass: string) {\n      this.setData({\n        className: resolveClasses('ml-auto text-xs tracking-widest opacity-60', extClass),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-sub/dropdown-menu-sub.wxml",
          "target": "components/ui/dropdown-menu-sub/dropdown-menu-sub.wxml",
          "type": "registry:component",
          "content": "<view data-slot=\"dropdown-menu-sub\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-sub/dropdown-menu-sub.wxss",
          "target": "components/ui/dropdown-menu-sub/dropdown-menu-sub.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/dropdown-menu-sub/dropdown-menu-sub.json",
          "target": "components/ui/dropdown-menu-sub/dropdown-menu-sub.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-sub/dropdown-menu-sub.ts",
          "target": "components/ui/dropdown-menu-sub/dropdown-menu-sub.ts",
          "type": "registry:component",
          "content": "Component({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    extClass: { type: String, value: '' },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-sub-content/dropdown-menu-sub-content.wxml",
          "target": "components/ui/dropdown-menu-sub-content/dropdown-menu-sub-content.wxml",
          "type": "registry:component",
          "content": "<view data-slot=\"dropdown-menu-sub-content\" class=\"{{className}}\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-sub-content/dropdown-menu-sub-content.wxss",
          "target": "components/ui/dropdown-menu-sub-content/dropdown-menu-sub-content.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/dropdown-menu-sub-content/dropdown-menu-sub-content.json",
          "target": "components/ui/dropdown-menu-sub-content/dropdown-menu-sub-content.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-sub-content/dropdown-menu-sub-content.ts",
          "target": "components/ui/dropdown-menu-sub-content/dropdown-menu-sub-content.ts",
          "type": "registry:component",
          "content": "import { resolveClasses } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: { type: String, value: '' },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass: string) {\n      const base =\n        'z-50 min-w-40 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg'\n      this.setData({\n        className: resolveClasses(base, extClass),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-sub-trigger/dropdown-menu-sub-trigger.wxml",
          "target": "components/ui/dropdown-menu-sub-trigger/dropdown-menu-sub-trigger.wxml",
          "type": "registry:component",
          "content": "<view data-slot=\"dropdown-menu-sub-trigger\" class=\"{{className}}\">\n  <slot></slot>\n  <text class=\"ml-auto\">›</text>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-sub-trigger/dropdown-menu-sub-trigger.wxss",
          "target": "components/ui/dropdown-menu-sub-trigger/dropdown-menu-sub-trigger.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/dropdown-menu-sub-trigger/dropdown-menu-sub-trigger.json",
          "target": "components/ui/dropdown-menu-sub-trigger/dropdown-menu-sub-trigger.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-sub-trigger/dropdown-menu-sub-trigger.ts",
          "target": "components/ui/dropdown-menu-sub-trigger/dropdown-menu-sub-trigger.ts",
          "type": "registry:component",
          "content": "import { resolveClasses } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    inset: { type: Boolean, value: false },\n    extClass: { type: String, value: '' },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    'extClass, inset': function (extClass: string, inset: boolean) {\n      const base = 'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm'\n      const insetClass = inset ? 'pl-8' : ''\n      this.setData({\n        className: resolveClasses(base, insetClass, extClass),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-trigger/dropdown-menu-trigger.wxml",
          "target": "components/ui/dropdown-menu-trigger/dropdown-menu-trigger.wxml",
          "type": "registry:component",
          "content": "<view\n  id=\"dropdown-menu-trigger\"\n  data-slot=\"dropdown-menu-trigger\"\n  class=\"{{className}}\"\n  data-disabled=\"{{disabled}}\"\n  bindtap=\"onTap\"\n>\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-trigger/dropdown-menu-trigger.wxss",
          "target": "components/ui/dropdown-menu-trigger/dropdown-menu-trigger.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/dropdown-menu-trigger/dropdown-menu-trigger.json",
          "target": "components/ui/dropdown-menu-trigger/dropdown-menu-trigger.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        },
        {
          "path": "registry/default/weapp/dropdown-menu-trigger/dropdown-menu-trigger.ts",
          "target": "components/ui/dropdown-menu-trigger/dropdown-menu-trigger.ts",
          "type": "registry:component",
          "content": "import { resolveClasses } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  relations: {\n    '../dropdown-menu/dropdown-menu': {\n      type: 'parent',\n    },\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    disabled: { type: Boolean, value: false },\n    extClass: { type: String, value: '' },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass: string) {\n      this.setData({\n        className: resolveClasses('inline-flex items-center', extClass),\n      })\n    },\n  },\n  methods: {\n    onTap() {\n      if (this.properties.disabled) return\n      const parents = this.getRelationNodes('../dropdown-menu/dropdown-menu')\n      if (parents.length) {\n        parents[0].toggle()\n      }\n    },\n    getRect() {\n      return new Promise((resolve) => {\n        this.createSelectorQuery()\n          .select('#dropdown-menu-trigger')\n          .boundingClientRect((rect) => {\n            resolve(rect)\n          })\n          .exec()\n      })\n    },\n  },\n})\n"
        }
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@zag-js/popper",
              "@zag-js/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@zag-js/popper",
              "@zag-js/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "hover-card",
      "type": "registry:ui",
      "dependencies": [
        "@timui/core",
        "@zag-js/popper",
        "@zag-js/react"
      ],
      "registryDependencies": [
        "use-machine"
      ],
      "files": [
        {
          "path": "registry/default/ui/hover-card.tsx",
          "type": "registry:ui",
          "target": "components/ui/hover-card.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport { cn, hoverCardContentVariants } from '@timui/core'\nimport type { Placement } from '@zag-js/popper'\nimport { mergeProps } from '@zag-js/react'\nimport { createPortal } from 'react-dom'\n\nimport { useHoverCard, type UseHoverCardProps } from './hover-card/use-hover-card'\nimport { HoverCardProvider, useHoverCardContext } from './hover-card/use-hover-card-context'\nimport { Slot } from './slot'\n\nconst HoverCard = ({ children, ...props }: UseHoverCardProps & { children: React.ReactNode }) => {\n  const api = useHoverCard(props)\n  return <HoverCardProvider value={api}>{children}</HoverCardProvider>\n}\nHoverCard.displayName = 'HoverCard'\n\nconst HoverCardTrigger = React.forwardRef<\n  HTMLAnchorElement,\n  React.AnchorHTMLAttributes<HTMLAnchorElement> & { asChild?: boolean }\n>(({ className, asChild = false, ...props }, ref) => {\n  const api = useHoverCardContext()\n\n  const Comp = asChild ? Slot : 'a'\n  const triggerProps = api.getTriggerProps()\n  const mergedProps = mergeProps(triggerProps, props)\n\n  return (\n    <Comp\n      ref={ref}\n      data-slot=\"hover-card-trigger\"\n      className={cn('cursor-pointer', className)}\n      {...mergedProps}\n    />\n  )\n})\nHoverCardTrigger.displayName = 'HoverCardTrigger'\n\nconst HoverCardContent = React.forwardRef<\n  HTMLDivElement,\n  React.HTMLAttributes<HTMLDivElement> & {\n    align?: 'center' | 'start' | 'end'\n    side?: 'top' | 'bottom' | 'left' | 'right'\n    sideOffset?: number\n    showArrow?: boolean\n  }\n>(\n  (\n    {\n      className,\n      align = 'center',\n      side = 'bottom',\n      sideOffset = 4,\n      showArrow = false,\n      style,\n      children,\n      ...props\n    },\n    ref\n  ) => {\n    const api = useHoverCardContext()\n    const placement = (align === 'center' ? side : `${side}-${align}`) as Placement\n    React.useEffect(() => {\n      if (!api.open) return\n      api.reposition({ placement, gutter: sideOffset })\n    }, [api, placement, sideOffset])\n    if (!api.open) return null\n    if (typeof window === 'undefined') return null\n\n    const positionerProps = api.getPositionerProps()\n    const contentProps = api.getContentProps()\n    const mergedProps = mergeProps(contentProps, props) as React.HTMLAttributes<HTMLDivElement>\n\n    return createPortal(\n      <div {...positionerProps} style={{ ...positionerProps.style, zIndex: 50 }}>\n        <div\n          ref={ref}\n          data-slot=\"hover-card-content\"\n          data-state=\"open\"\n          style={{ ...mergedProps.style, ...style }}\n          className={cn(hoverCardContentVariants(), showArrow ? 'relative' : undefined, className)}\n          {...mergedProps}\n        >\n          {children}\n          {showArrow ? (\n            <span\n              data-slot=\"hover-card-arrow\"\n              className=\"absolute -top-1 left-6 h-2 w-2 rotate-45 border border-border bg-popover\"\n            />\n          ) : null}\n        </div>\n      </div>,\n      document.body\n    )\n  }\n)\nHoverCardContent.displayName = 'HoverCardContent'\n\nexport { HoverCard, HoverCardContent, HoverCardTrigger }\n"
        },
        {
          "path": "registry/default/ui/hover-card/use-hover-card-context.tsx",
          "target": "components/ui/hover-card/use-hover-card-context.tsx",
          "type": "registry:ui",
          "content": "import * as React from 'react'\n\nimport type { useHoverCard } from './use-hover-card'\n\nexport type UseHoverCardReturn = ReturnType<typeof useHoverCard>\n\nconst HoverCardContext = React.createContext<UseHoverCardReturn | null>(null)\n\nexport function HoverCardProvider({\n  children,\n  value,\n}: {\n  children: React.ReactNode\n  value: UseHoverCardReturn\n}) {\n  return <HoverCardContext.Provider value={value}>{children}</HoverCardContext.Provider>\n}\n\nexport function useHoverCardContext() {\n  const context = React.useContext(HoverCardContext)\n  if (!context) {\n    throw new Error('useHoverCardContext must be used within a HoverCardProvider')\n  }\n  return context\n}\n"
        },
        {
          "path": "registry/default/ui/hover-card/use-hover-card.ts",
          "target": "components/ui/hover-card/use-hover-card.ts",
          "type": "registry:ui",
          "content": "import * as React from 'react'\nimport { hoverCardConnect, hoverCardMachine } from '@timui/core'\nimport type { PositioningOptions } from '@zag-js/popper'\nimport { normalizeProps, useMachine } from '@zag-js/react'\n\nexport interface UseHoverCardProps {\n  id?: string\n  open?: boolean\n  defaultOpen?: boolean\n  openDelay?: number\n  closeDelay?: number\n  disabled?: boolean\n  positioning?: PositioningOptions\n  onOpenChange?: (open: boolean) => void\n}\n\nexport function useHoverCard(props: UseHoverCardProps) {\n  const generatedId = React.useId()\n  const service = useMachine(hoverCardMachine, {\n    id: props.id ?? generatedId,\n    open: props.open,\n    defaultOpen: props.defaultOpen,\n    openDelay: props.openDelay,\n    closeDelay: props.closeDelay,\n    positioning: props.positioning,\n    disabled: props.disabled,\n    onOpenChange: (details) => props.onOpenChange?.(details.open),\n  })\n\n  const api = React.useMemo(() => hoverCardConnect(service, normalizeProps), [service])\n\n  return api\n}\n"
        },
        {
          "path": "registry/default/vue/hover-card/hover-card-content.vue",
          "target": "components/ui/hover-card/hover-card-content.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, watch } from 'vue'\nimport { cn, hoverCardContentVariants } from '@timui/core'\nimport type { HTMLAttributes } from 'vue'\nimport type { Placement } from '@zag-js/popper'\nimport { useHoverCardContext } from './use-hover-card-context'\nimport Presence from '../presence/presence.vue'\n\nconst props = withDefaults(\n  defineProps<{\n    class?: HTMLAttributes['class']\n    align?: 'center' | 'start' | 'end'\n    side?: 'top' | 'bottom' | 'left' | 'right'\n    sideOffset?: number\n    showArrow?: boolean\n  }>(),\n  {\n    align: 'center',\n    side: 'bottom',\n    sideOffset: 4,\n    showArrow: false,\n  }\n)\n\nconst context = useHoverCardContext()\nconst isOpen = computed(() => context.value.open ?? false)\nconst positionerProps = computed(() => context.value.getPositionerProps?.() ?? {})\nconst contentProps = computed(() => context.value.getContentProps?.() ?? {})\nconst placement = computed(() =>\n  props.align === 'center' ? props.side : `${props.side}-${props.align}`\n)\n\nwatch(\n  () => [placement.value, props.sideOffset],\n  () => {\n    context.value.reposition?.({ placement: placement.value as Placement, gutter: props.sideOffset })\n  },\n  { immediate: true }\n)\n</script>\n\n<template>\n  <Teleport to=\"body\">\n    <Presence :present=\"isOpen\" :unmountOnExit=\"true\" v-bind=\"positionerProps\" style=\"z-index: 50\">\n      <div\n        v-bind=\"contentProps\"\n        data-slot=\"hover-card-content\"\n        data-state=\"open\"\n        :class=\"\n          cn(hoverCardContentVariants(), props.showArrow && 'relative', props.class)\n        \"\n      >\n        <slot />\n        <span\n          v-if=\"props.showArrow\"\n          data-slot=\"hover-card-arrow\"\n          class=\"absolute -top-1 left-6 h-2 w-2 rotate-45 border border-border bg-popover\"\n        />\n      </div>\n    </Presence>\n  </Teleport>\n</template>\n"
        },
        {
          "path": "registry/default/vue/hover-card/hover-card-trigger.vue",
          "target": "components/ui/hover-card/hover-card-trigger.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, type Component, type HTMLAttributes } from 'vue'\nimport { cn } from '@timui/core'\nimport { Primitive } from '../../primitive'\nimport { useHoverCardContext } from './use-hover-card-context'\n\nconst props = withDefaults(\n  defineProps<{\n    as?: string | Component\n    asChild?: boolean\n    class?: HTMLAttributes['class']\n  }>(),\n  {\n    as: 'a',\n  }\n)\n\nconst context = useHoverCardContext()\nconst triggerProps = computed(() => ({\n  ...(context.value.getTriggerProps?.() ?? {}),\n  'data-slot': 'hover-card-trigger',\n}))\n</script>\n\n<template>\n  <Primitive :as=\"props.as\" :as-child=\"props.asChild\" v-bind=\"triggerProps\" :class=\"cn(props.class)\">\n    <slot />\n  </Primitive>\n</template>\n"
        },
        {
          "path": "registry/default/vue/hover-card/hover-card.vue",
          "target": "components/ui/hover-card/hover-card.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes } from 'vue'\nimport type { PositioningOptions } from '@zag-js/popper'\nimport { useHoverCard } from './use-hover-card'\nimport { HoverCardProvider } from './use-hover-card-context'\n\nconst props = defineProps<{\n  open?: boolean\n  defaultOpen?: boolean\n  openDelay?: number\n  closeDelay?: number\n  disabled?: boolean\n  positioning?: PositioningOptions\n  onOpenChange?: (open: boolean) => void\n  id?: string\n  class?: HTMLAttributes['class']\n}>()\n\nconst emit = defineEmits(['update:open', 'change'])\n\nconst api = useHoverCard(props, emit)\nHoverCardProvider(api)\n</script>\n\n<template>\n  <slot />\n</template>\n"
        },
        {
          "path": "registry/default/vue/hover-card/use-hover-card-context.ts",
          "target": "components/ui/hover-card/use-hover-card-context.ts",
          "type": "registry:component",
          "content": "import { createContext } from '../../hooks/create-context'\nimport type { useHoverCard } from './use-hover-card'\n\nexport type UseHoverCardReturn = ReturnType<typeof useHoverCard>\n\nexport const [HoverCardProvider, useHoverCardContext] = createContext<UseHoverCardReturn>({\n  id: 'hoverCardContext',\n  providerName: '<HoverCard />',\n})\n"
        },
        {
          "path": "registry/default/vue/hover-card/use-hover-card.ts",
          "target": "components/ui/hover-card/use-hover-card.ts",
          "type": "registry:component",
          "content": "import { hoverCardConnect, hoverCardMachine } from '@timui/core'\nimport type { PositioningOptions } from '@zag-js/popper'\nimport { normalizeProps, useMachine } from '@zag-js/vue'\nimport { computed, useId, watch } from 'vue'\n\nexport interface UseHoverCardProps {\n  id?: string\n  open?: boolean\n  defaultOpen?: boolean\n  openDelay?: number\n  closeDelay?: number\n  disabled?: boolean\n  positioning?: PositioningOptions\n  onOpenChange?: (open: boolean) => void\n}\n\nexport interface UseHoverCardEmits {\n  (e: 'update:open', value: boolean): void\n  (e: 'change', value: boolean): void\n}\n\nexport function useHoverCard(props: UseHoverCardProps, emit: UseHoverCardEmits) {\n  const generatedId = useId()\n\n  const machineProps = computed(() => ({\n    id: props.id ?? generatedId,\n    open: props.open,\n    defaultOpen: props.open === undefined ? props.defaultOpen : undefined,\n    openDelay: props.openDelay,\n    closeDelay: props.closeDelay,\n    disabled: props.disabled,\n    positioning: props.positioning,\n    onOpenChange(details: { open: boolean }) {\n      props.onOpenChange?.(details.open)\n      emit('update:open', details.open)\n      emit('change', details.open)\n    },\n  }))\n\n  const service = useMachine(hoverCardMachine, machineProps)\n  const api = computed(() => hoverCardConnect(service, normalizeProps))\n\n  watch(\n    () => props.open,\n    (val?: boolean) => {\n      if (val !== undefined && val !== api.value.open) {\n        api.value.setOpen(val)\n      }\n    }\n  )\n\n  return api\n}\n"
        },
        {
          "path": "registry/default/html/hover-card.html",
          "target": "components/ui/hover-card.html",
          "type": "registry:component",
          "content": "<div data-timui-root data-timui-init=\"auto\">\n  <div data-slot=\"hover-card\" class=\"inline-block\">\n    <button data-slot=\"hover-card-trigger\" class=\"rounded-md border border-input px-3 py-2 text-sm\">\n      Hover Card Trigger\n    </button>\n    <div data-slot=\"hover-card-content\" data-state=\"closed\" hidden class=\"p-3\">\n      Hover card content preview.\n    </div>\n  </div>\n</div>\n<script type=\"module\">\n  import { autoInitHtmlRuntime } from '@timui/html'\n  autoInitHtmlRuntime({ components: ['hover-card'] })\n</script>"
        },
        {
          "path": "registry/default/weapp/hover-card.wxml",
          "target": "components/ui/hover-card.wxml",
          "type": "registry:component",
          "content": "<view class=\"hover-card {{extClass}}\">\n  <view class=\"hover-card-trigger\" bindtouchstart=\"onTriggerEnter\" bindtouchend=\"onTriggerLeave\">\n    <slot name=\"trigger\" />\n  </view>\n\n  <view\n    wx:if=\"{{open}}\"\n    class=\"hover-card-content\"\n    bindtouchstart=\"onContentEnter\"\n    bindtouchend=\"onContentLeave\"\n  >\n    <slot />\n  </view>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/hover-card.wxss",
          "target": "components/ui/hover-card.wxss",
          "type": "registry:component",
          "content": ".hover-card {\n  position: relative;\n  display: inline-flex;\n  flex-direction: column;\n}\n\n.hover-card-content {\n  margin-top: 10rpx;\n  min-width: 260rpx;\n  border: 1px solid #e5e7eb;\n  border-radius: 12rpx;\n  background: #ffffff;\n  padding: 16rpx;\n  box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.12);\n}\n"
        },
        {
          "path": "registry/default/weapp/hover-card.ts",
          "target": "components/ui/hover-card.ts",
          "type": "registry:component",
          "content": "Component({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    openDelay: {\n      type: Number,\n      value: 120,\n    },\n    closeDelay: {\n      type: Number,\n      value: 100,\n    },\n    disabled: {\n      type: Boolean,\n      value: false,\n    },\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n\n  data: {\n    open: false,\n    _openTimer: 0,\n    _closeTimer: 0,\n  },\n\n  methods: {\n    clearTimers() {\n      if (this.data._openTimer) clearTimeout(this.data._openTimer)\n      if (this.data._closeTimer) clearTimeout(this.data._closeTimer)\n      this.setData({ _openTimer: 0, _closeTimer: 0 })\n    },\n\n    onTriggerEnter() {\n      if (this.properties.disabled) return\n      this.clearTimers()\n      const timer = setTimeout(() => {\n        this.setData({ open: true })\n        this.triggerEvent('openChange', { open: true })\n      }, this.properties.openDelay)\n      this.setData({ _openTimer: Number(timer) })\n    },\n\n    onTriggerLeave() {\n      this.scheduleClose()\n    },\n\n    onContentEnter() {\n      this.clearTimers()\n    },\n\n    onContentLeave() {\n      this.scheduleClose()\n    },\n\n    scheduleClose() {\n      this.clearTimers()\n      const timer = setTimeout(() => {\n        this.setData({ open: false })\n        this.triggerEvent('openChange', { open: false })\n      }, this.properties.closeDelay)\n      this.setData({ _closeTimer: Number(timer) })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/hover-card.json",
          "target": "components/ui/hover-card.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        }
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@zag-js/popper",
              "@zag-js/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@zag-js/popper",
              "@zag-js/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "input",
      "type": "registry:ui",
      "files": [
        {
          "path": "registry/default/ui/input.tsx",
          "type": "registry:ui",
          "target": "components/ui/input.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport type { AssertNoExtraKeys, InputProps as CoreInputProps } from '@timui/core'\nimport { cn, createTimEvent, inputVariants } from '@timui/core'\n\ntype InputProps = CoreInputProps & Omit<React.ComponentProps<'input'>, keyof CoreInputProps>\n\nfunction Input({ className, type, id, onValueChange, onChange, ...props }: InputProps) {\n  const generatedId = React.useId()\n  const inputId = id ?? generatedId\n  const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n    onChange?.(event)\n    onValueChange?.(createTimEvent('change', inputId, { value: event.target.value }))\n  }\n\n  const inputType = type === 'search' ? 'search' : type === 'file' ? 'file' : 'default'\n\n  return (\n    <input\n      type={type}\n      data-slot=\"input\"\n      className={cn(inputVariants({ type: inputType }), className)}\n      onChange={handleChange}\n      {...props}\n    />\n  )\n}\n\nexport { Input }\n"
        },
        {
          "path": "registry/default/vue/input.vue",
          "type": "registry:ui",
          "target": "components/ui/input.vue",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed, useAttrs, useId } from 'vue'\nimport type { AssertNoExtraKeys, InputVueProps, TextInputValueChangeEvent } from '@timui/core'\nimport { cn, inputVariants, createTimEvent } from '@timui/core'\n\ndefineOptions({\n  inheritAttrs: false,\n})\n\ntype InputProps = InputVueProps & { class?: HTMLAttributes['class'] }\ntype _InputPropsGuard = AssertNoExtraKeys<\n  InputProps,\n  InputVueProps & { class?: HTMLAttributes['class'] }\n>\n\nconst props = defineProps<InputProps>()\nconst attrs = useAttrs()\n\nconst emit = defineEmits<{\n  (e: 'update:modelValue', value: string | number): void\n  (e: 'valueChange', event: TextInputValueChangeEvent): void\n}>()\n\nconst modelValue = defineModel<string | number>({ required: false })\nconst inputType = computed(() => {\n  const type = attrs.type\n  if (type === 'search') return 'search'\n  if (type === 'file') return 'file'\n  return 'default'\n})\n\nconst generatedId = useId()\nconst inputId = computed(() => props.id ?? generatedId)\n\nconst handleChange = (event: Event) => {\n  const target = event.target as HTMLInputElement\n  // React fires onValueChange on every stroke to match its behavior, which maps to Vue's @input\n  if (props.onValueChange) {\n    props.onValueChange(createTimEvent('change', inputId.value, { value: target.value }))\n  }\n  emit('valueChange', createTimEvent('change', inputId.value, { value: target.value }))\n}\n</script>\n\n<template>\n  <input\n    v-model=\"modelValue\"\n    data-slot=\"input\"\n    :id=\"inputId\"\n    :class=\"\n      cn(\n        inputVariants({ type: inputType }),\n        props.class,\n      )\n    \"\n    v-bind=\"$attrs\"\n    @input=\"handleChange\"\n  />\n</template>\n"
        },
        {
          "path": "registry/default/vue/input/input.vue",
          "target": "components/ui/input/input.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed, useAttrs, useId } from 'vue'\nimport type { AssertNoExtraKeys, InputVueProps, TextInputValueChangeEvent } from '@timui/core'\nimport { cn, inputVariants, createTimEvent } from '@timui/core'\n\ndefineOptions({\n  inheritAttrs: false,\n})\n\ntype InputProps = InputVueProps & { class?: HTMLAttributes['class'] }\ntype _InputPropsGuard = AssertNoExtraKeys<\n  InputProps,\n  InputVueProps & { class?: HTMLAttributes['class'] }\n>\n\nconst props = defineProps<InputProps>()\nconst attrs = useAttrs()\n\nconst emit = defineEmits<{\n  (e: 'update:modelValue', value: string | number): void\n  (e: 'valueChange', event: TextInputValueChangeEvent): void\n}>()\n\nconst modelValue = defineModel<string | number>({ required: false })\nconst inputType = computed(() => {\n  const type = attrs.type\n  if (type === 'search') return 'search'\n  if (type === 'file') return 'file'\n  return 'default'\n})\n\nconst generatedId = useId()\nconst inputId = computed(() => props.id ?? generatedId)\n\nconst handleChange = (event: Event) => {\n  const target = event.target as HTMLInputElement\n  // React fires onValueChange on every stroke to match its behavior, which maps to Vue's @input\n  if (props.onValueChange) {\n    props.onValueChange(createTimEvent('change', inputId.value, { value: target.value }))\n  }\n  emit('valueChange', createTimEvent('change', inputId.value, { value: target.value }))\n}\n</script>\n\n<template>\n  <input\n    v-model=\"modelValue\"\n    data-slot=\"input\"\n    :id=\"inputId\"\n    :class=\"\n      cn(\n        inputVariants({ type: inputType }),\n        props.class,\n      )\n    \"\n    v-bind=\"$attrs\"\n    @input=\"handleChange\"\n  />\n</template>\n"
        },
        {
          "path": "registry/default/html/input.html",
          "target": "components/ui/input.html",
          "type": "registry:component",
          "content": "<input data-slot=\"input\" class=\"border-input file:text-foreground placeholder:text-muted-foreground/70 flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-sm shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\" type=\"text\"\n    placeholder=\"Email\" />"
        },
        {
          "path": "registry/default/weapp/input.wxml",
          "target": "components/ui/input.wxml",
          "type": "registry:component",
          "content": "<input \n  class=\"{{className}}\"\n  type=\"{{type}}\"\n  value=\"{{value}}\"\n  placeholder=\"{{placeholder}}\"\n  disabled=\"{{disabled}}\"\n  maxlength=\"{{maxlength}}\"\n  focus=\"{{focus}}\"\n  confirm-type=\"{{confirmType}}\"\n  adjust-position=\"{{true}}\"\n  cursor-spacing=\"{{16}}\"\n  bindinput=\"onInput\"\n  bindfocus=\"onFocus\"\n  bindblur=\"onBlur\"\n  bindconfirm=\"onConfirm\"\n/>\n"
        },
        {
          "path": "registry/default/weapp/input.wxss",
          "target": "components/ui/input.wxss",
          "type": "registry:component",
          "content": "/* Styles handled by Tailwind CSS */\n"
        },
        {
          "path": "registry/default/weapp/input.ts",
          "target": "components/ui/input.ts",
          "type": "registry:component",
          "content": "import { emitTimEvent, inputVariants } from '../utils'\nimport {\n  createWeappBaseProps,\n  createWeappOptions,\n  WEAPP_EXTERNAL_CLASSES,\n} from '../utils/component'\n\ntype WeappInputDetail = {\n  value: string\n}\n\ntype WeappInputEvent = WechatMiniprogram.CustomEvent<WeappInputDetail>\n\nComponent({\n  options: createWeappOptions({ pureData: true }),\n\n  externalClasses: WEAPP_EXTERNAL_CLASSES,\n\n  properties: {\n    value: { type: String, value: '' },\n    type: { type: String, value: 'text' },\n    placeholder: { type: String, value: '' },\n    disabled: { type: Boolean, value: false },\n    maxlength: { type: Number, value: 140 },\n    focus: { type: Boolean, value: false },\n    confirmType: { type: String, value: 'done' },\n    ...createWeappBaseProps('input'),\n  },\n\n  data: {\n    className: '',\n  },\n\n  lifetimes: {\n    attached() {\n      this.updateClassName()\n    },\n  },\n\n  observers: {\n    'type, extClass': function () {\n      this.updateClassName()\n    },\n  },\n\n  methods: {\n    updateClassName() {\n      // Use core package's inputVariants for consistent styling\n      const { baseClass } = inputVariants({\n        type: this.properties.type === 'search' ? 'search' : 'default',\n        className: this.properties.extClass,\n      })\n\n      this.setData({ className: baseClass })\n    },\n\n    onInput(e: WeappInputEvent) {\n      this.setData({ value: e.detail.value })\n      this.triggerEvent('input', e.detail)\n      emitTimEvent(this, 'change', 'change', this.properties.id || 'input', {\n        value: e.detail.value,\n      })\n    },\n    onFocus(e: WeappInputEvent) {\n      this.triggerEvent('focus', e.detail)\n    },\n    onBlur(e: WeappInputEvent) {\n      this.triggerEvent('blur', e.detail)\n    },\n    onConfirm(e: WeappInputEvent) {\n      this.triggerEvent('confirm', e.detail)\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/input.json",
          "target": "components/ui/input.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        }
      ],
      "dependencies": [
        "@timui/core"
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "label",
      "type": "registry:ui",
      "dependencies": [
        "@timui/core"
      ],
      "files": [
        {
          "path": "registry/default/ui/label.tsx",
          "type": "registry:ui",
          "target": "components/ui/label.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport { cn, labelVariants } from '@timui/core'\n\nconst Label = React.forwardRef<HTMLLabelElement, React.LabelHTMLAttributes<HTMLLabelElement>>(\n  ({ className, ...props }, ref) => (\n    <label ref={ref} className={cn(labelVariants(), className)} {...props} />\n  )\n)\nLabel.displayName = 'Label'\n\nexport { Label }\n"
        },
        {
          "path": "registry/default/vue/label/label.vue",
          "target": "components/ui/label/label.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed } from 'vue'\nimport { Label, type LabelProps } from 'radix-vue'\nimport { cn, labelVariants } from '@timui/core'\n\nconst props = defineProps<\n  LabelProps & {\n    class?: HTMLAttributes['class']\n    htmlFor?: string\n  }\n>()\n\nconst delegatedProps = computed(() => {\n  const { class: _, htmlFor, ...delegated } = props\n  if (htmlFor !== undefined) {\n    return {\n      ...delegated,\n      for: htmlFor,\n    }\n  }\n  return delegated\n})\n</script>\n\n<template>\n    <Label\n      v-bind=\"delegatedProps\"\n      :class=\"\n        cn(\n        labelVariants(),\n        props.class,\n      )\n    \"\n  >\n    <slot />\n  </Label>\n</template>\n"
        },
        {
          "path": "registry/default/html/label.html",
          "target": "components/ui/label.html",
          "type": "registry:component",
          "content": "<label class=\"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\">\n    Label\n</label>"
        },
        {
          "path": "registry/default/weapp/label.wxml",
          "target": "components/ui/label.wxml",
          "type": "registry:component",
          "content": "<label \n  class=\"{{className}}\"\n  for=\"{{for}}\"\n  bindtap=\"onTap\"\n>\n  <slot></slot>\n</label>\n"
        },
        {
          "path": "registry/default/weapp/label.wxss",
          "target": "components/ui/label.wxss",
          "type": "registry:component",
          "content": "/* Styles handled by Tailwind CSS */\n"
        },
        {
          "path": "registry/default/weapp/label.ts",
          "target": "components/ui/label.ts",
          "type": "registry:component",
          "content": "import { labelVariants } from '../utils'\n\ntype TapEvent = WechatMiniprogram.BaseEvent<{\n  value?: string\n}>\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    for: { type: String, value: '' },\n    extClass: { type: String, value: '' },\n  },\n\n  data: {\n    className: '',\n  },\n\n  lifetimes: {\n    attached() {\n      this.updateClassName()\n    },\n  },\n\n  observers: {\n    extClass: function () {\n      this.updateClassName()\n    },\n  },\n\n  methods: {\n    updateClassName() {\n      // Use core package's labelVariants for consistent styling\n      const { baseClass } = labelVariants({\n        className: this.properties.extClass,\n      })\n\n      this.setData({ className: baseClass })\n    },\n\n    onTap(e: TapEvent) {\n      this.triggerEvent('tap', e.detail)\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/label.json",
          "target": "components/ui/label.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        }
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core"
            ],
            "optionalPeerDependencies": [
              "radix-vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "multiselect",
      "type": "registry:ui",
      "registryDependencies": [
        "https://ui.timkit.cn/r/command.json"
      ],
      "optionalPeerDependencies": [
        "cmdk",
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/ui/multiselect.tsx",
          "type": "registry:ui",
          "target": "components/ui/multiselect.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport { useEffect } from 'react'\nimport type {\n  AssertNoExtraKeys,\n  MultiselectProps as CoreMultiselectProps,\n  MultiselectOption,\n} from '@timui/core'\nimport {\n  cn,\n  multiselectClearButtonVariants,\n  multiselectCommandVariants,\n  multiselectContainerVariants,\n  multiselectDropdownVariants,\n  multiselectEmptyVariants,\n  multiselectGroupVariants,\n  multiselectInputVariants,\n  multiselectListVariants,\n  multiselectTagRemoveVariants,\n  multiselectTagVariants,\n} from '@timui/core'\nimport { Command as CommandPrimitive, useCommandState } from 'cmdk'\nimport { XIcon } from 'lucide-react'\n\nimport { Command, CommandGroup, CommandItem, CommandList } from './command'\n\nexport type Option = MultiselectOption\ninterface GroupOption {\n  [key: string]: Option[]\n}\n\ntype MultipleSelectorProps = CoreMultiselectProps & {\n  onChange?: (options: Option[]) => void\n  loadingIndicator?: React.ReactNode\n  emptyIndicator?: React.ReactNode\n  className?: string\n  badgeClassName?: string\n  commandProps?: React.ComponentPropsWithoutRef<typeof Command>\n  inputProps?: Omit<\n    React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>,\n    'value' | 'placeholder' | 'disabled'\n  >\n}\ntype _MultipleSelectorPropsGuard = AssertNoExtraKeys<\n  MultipleSelectorProps,\n  CoreMultiselectProps & {\n    onChange?: (options: Option[]) => void\n    loadingIndicator?: React.ReactNode\n    emptyIndicator?: React.ReactNode\n    className?: string\n    badgeClassName?: string\n    commandProps?: React.ComponentPropsWithoutRef<typeof Command>\n    inputProps?: Omit<\n      React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>,\n      'value' | 'placeholder' | 'disabled'\n    >\n  }\n>\n\nexport interface MultipleSelectorRef {\n  selectedValue: Option[]\n  input: HTMLInputElement\n  focus: () => void\n  reset: () => void\n}\n\nexport function useDebounce<T>(value: T, delay?: number): T {\n  const [debouncedValue, setDebouncedValue] = React.useState<T>(value)\n\n  useEffect(() => {\n    const timer = setTimeout(() => setDebouncedValue(value), delay || 500)\n\n    return () => {\n      clearTimeout(timer)\n    }\n  }, [value, delay])\n\n  return debouncedValue\n}\n\nfunction transToGroupOption(options: Option[], groupBy?: string) {\n  if (options.length === 0) {\n    return {}\n  }\n  if (!groupBy) {\n    return {\n      '': options,\n    }\n  }\n\n  const groupOption: GroupOption = {}\n  options.forEach((option) => {\n    const key = (option[groupBy] as string) || ''\n    if (!groupOption[key]) {\n      groupOption[key] = []\n    }\n    groupOption[key].push(option)\n  })\n  return groupOption\n}\n\nfunction removePickedOption(groupOption: GroupOption, picked: Option[]) {\n  if (picked.length === 0) {\n    return groupOption\n  }\n\n  const pickedValues = new Set(picked.map((item) => item.value))\n  const next: GroupOption = {}\n  for (const [key, value] of Object.entries(groupOption)) {\n    next[key] = value.filter((val) => !pickedValues.has(val.value))\n  }\n  return next\n}\n\nfunction isOptionsExist(groupOption: GroupOption, targetOption: Option[]) {\n  if (targetOption.length === 0) {\n    return false\n  }\n  const targetValues = new Set(targetOption.map((item) => item.value))\n  for (const [, value] of Object.entries(groupOption)) {\n    if (value.some((option) => targetValues.has(option.value))) {\n      return true\n    }\n  }\n  return false\n}\n\nconst CommandEmpty = ({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Empty>) => {\n  const render = useCommandState((state) => state.filtered.count === 0)\n\n  if (!render) return null\n\n  return (\n    <div\n      className={cn(multiselectEmptyVariants(), className)}\n      cmdk-empty=\"\"\n      role=\"presentation\"\n      {...props}\n    />\n  )\n}\n\nCommandEmpty.displayName = 'CommandEmpty'\n\nexport const MultipleSelector = ({\n  value,\n  onChange,\n  onValueChange,\n  placeholder,\n  defaultOptions: arrayDefaultOptions = [],\n  options: arrayOptions,\n  delay,\n  onSearch,\n  onSearchSync,\n  loadingIndicator,\n  emptyIndicator,\n  maxSelected = Number.MAX_SAFE_INTEGER,\n  onMaxSelected,\n  hidePlaceholderWhenSelected,\n  disabled,\n  groupBy,\n  className,\n  badgeClassName,\n  selectFirstItem = true,\n  creatable = false,\n  triggerSearchOnFocus = false,\n  commandProps,\n  inputProps,\n  hideClearAllButton = false,\n}: MultipleSelectorProps) => {\n  const emitValueChange = React.useCallback(\n    (next: Option[]) => {\n      onValueChange?.(next)\n      onChange?.(next)\n    },\n    [onChange, onValueChange]\n  )\n\n  const inputRef = React.useRef<HTMLInputElement>(null)\n  const [open, setOpen] = React.useState(false)\n  const [onScrollbar, setOnScrollbar] = React.useState(false)\n  const [isLoading, setIsLoading] = React.useState(false)\n  const dropdownRef = React.useRef<HTMLDivElement>(null) // Added this\n\n  const [selected, setSelected] = React.useState<Option[]>(value || [])\n  const [options, setOptions] = React.useState<GroupOption>(\n    transToGroupOption(arrayDefaultOptions, groupBy)\n  )\n  const [inputValue, setInputValue] = React.useState('')\n  const debouncedSearchTerm = useDebounce(inputValue, delay || 500)\n  const selectedValueSet = React.useMemo(\n    () => new Set(selected.map((item) => item.value)),\n    [selected]\n  )\n\n  const handleClickOutside = React.useCallback((event: MouseEvent | TouchEvent) => {\n    if (\n      dropdownRef.current &&\n      !dropdownRef.current.contains(event.target as Node) &&\n      inputRef.current &&\n      !inputRef.current.contains(event.target as Node)\n    ) {\n      setOpen(false)\n      inputRef.current.blur()\n    }\n  }, [])\n\n  const handleUnselect = React.useCallback(\n    (option: Option) => {\n      const newOptions = selected.filter((s) => s.value !== option.value)\n      setSelected(newOptions)\n      emitValueChange(newOptions)\n    },\n    [emitValueChange, selected]\n  )\n\n  const handleKeyDown = React.useCallback(\n    (e: React.KeyboardEvent<HTMLDivElement>) => {\n      const input = inputRef.current\n      if (input) {\n        if (e.key === 'Delete' || e.key === 'Backspace') {\n          if (input.value === '' && selected.length > 0) {\n            const lastSelectOption = selected[selected.length - 1]\n            // If last item is fixed, we should not remove it.\n            if (!lastSelectOption.fixed) {\n              handleUnselect(selected[selected.length - 1])\n            }\n          }\n        }\n        // This is not a default behavior of the <input /> field\n        if (e.key === 'Escape') {\n          input.blur()\n        }\n      }\n    },\n    [handleUnselect, selected]\n  )\n\n  useEffect(() => {\n    if (open) {\n      document.addEventListener('mousedown', handleClickOutside)\n      document.addEventListener('touchend', handleClickOutside)\n    } else {\n      document.removeEventListener('mousedown', handleClickOutside)\n      document.removeEventListener('touchend', handleClickOutside)\n    }\n\n    return () => {\n      document.removeEventListener('mousedown', handleClickOutside)\n      document.removeEventListener('touchend', handleClickOutside)\n    }\n  }, [handleClickOutside, open])\n\n  useEffect(() => {\n    if (value) {\n      setSelected(value)\n    }\n  }, [value])\n\n  useEffect(() => {\n    /** If `onSearch` is provided, do not trigger options updated. */\n    if (!arrayOptions || onSearch) {\n      return\n    }\n    setOptions(transToGroupOption(arrayOptions, groupBy))\n  }, [arrayOptions, groupBy, onSearch])\n\n  useEffect(() => {\n    /** sync search */\n\n    const doSearchSync = () => {\n      const res = onSearchSync?.(debouncedSearchTerm)\n      setOptions(transToGroupOption(res || [], groupBy))\n    }\n\n    const exec = async () => {\n      if (!onSearchSync || !open) return\n      if (triggerSearchOnFocus || debouncedSearchTerm) {\n        doSearchSync()\n      }\n    }\n\n    void exec()\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [debouncedSearchTerm, groupBy, open, triggerSearchOnFocus])\n\n  useEffect(() => {\n    /** async search */\n    let active = true\n\n    const doSearch = async () => {\n      setIsLoading(true)\n      const res = await onSearch?.(debouncedSearchTerm)\n      if (!active) return\n      setOptions(transToGroupOption(res || [], groupBy))\n      setIsLoading(false)\n    }\n\n    const exec = async () => {\n      if (!onSearch || !open) return\n      if (triggerSearchOnFocus || debouncedSearchTerm) {\n        await doSearch()\n      }\n    }\n\n    void exec()\n    return () => {\n      active = false\n    }\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [debouncedSearchTerm, groupBy, open, triggerSearchOnFocus])\n\n  const creatableNode = React.useMemo(() => {\n    if (!creatable) return undefined\n    if (\n      isOptionsExist(options, [{ value: inputValue, label: inputValue }]) ||\n      selectedValueSet.has(inputValue)\n    ) {\n      return undefined\n    }\n\n    const shouldShow =\n      (!onSearch && inputValue.length > 0) ||\n      (onSearch && debouncedSearchTerm.length > 0 && !isLoading)\n\n    if (!shouldShow) return undefined\n\n    return (\n      <CommandItem\n        value={inputValue}\n        className=\"cursor-pointer\"\n        onMouseDown={(e) => {\n          e.preventDefault()\n          e.stopPropagation()\n        }}\n        onSelect={(value: string) => {\n          if (selected.length >= maxSelected) {\n            onMaxSelected?.(selected.length)\n            return\n          }\n          setInputValue('')\n          const newOptions = [...selected, { value, label: value }]\n          setSelected(newOptions)\n          emitValueChange(newOptions)\n        }}\n      >\n        {`Create \"${inputValue}\"`}\n      </CommandItem>\n    )\n  }, [\n    creatable,\n    debouncedSearchTerm.length,\n    emitValueChange,\n    inputValue,\n    isLoading,\n    maxSelected,\n    onMaxSelected,\n    onSearch,\n    options,\n    selected,\n    selectedValueSet,\n  ])\n\n  const emptyNode = React.useMemo(() => {\n    if (!emptyIndicator) return undefined\n\n    if (onSearch && !creatable && Object.keys(options).length === 0) {\n      return (\n        <CommandItem value=\"-\" disabled>\n          {emptyIndicator}\n        </CommandItem>\n      )\n    }\n\n    return <CommandEmpty>{emptyIndicator}</CommandEmpty>\n  }, [creatable, emptyIndicator, onSearch, options])\n\n  const selectables = React.useMemo<GroupOption>(\n    () => removePickedOption(options, selected),\n    [options, selected]\n  )\n  const selectableEntries = React.useMemo(() => Object.entries(selectables), [selectables])\n  const fixedSelected = React.useMemo(() => selected.filter((item) => item.fixed), [selected])\n\n  /** Avoid Creatable Selector freezing or lagging when paste a long string. */\n  const commandFilter = React.useMemo(() => {\n    if (commandProps?.filter) return commandProps.filter\n    if (!creatable) return undefined\n    return (value: string, search: string) => {\n      return value.toLowerCase().includes(search.toLowerCase()) ? 1 : -1\n    }\n  }, [creatable, commandProps?.filter])\n\n  return (\n    <Command\n      ref={dropdownRef}\n      {...commandProps}\n      onKeyDown={(e) => {\n        handleKeyDown(e)\n        commandProps?.onKeyDown?.(e)\n      }}\n      className={cn(multiselectCommandVariants(), commandProps?.className)}\n      shouldFilter={\n        commandProps?.shouldFilter !== undefined ? commandProps.shouldFilter : !onSearch\n      } // When onSearch is provided, we don&lsquo;t want to filter the options. You can still override it.\n      filter={commandFilter}\n    >\n      <div\n        className={cn(\n          multiselectContainerVariants(),\n          {\n            'p-1': selected.length !== 0,\n            'cursor-text': !disabled && selected.length !== 0,\n          },\n          !hideClearAllButton && 'pe-9',\n          className\n        )}\n        onClick={() => {\n          if (disabled) return\n          inputRef?.current?.focus()\n        }}\n      >\n        <div className=\"flex flex-wrap gap-1\">\n          {selected.map((option) => {\n            return (\n              <div\n                key={option.value}\n                className={cn(multiselectTagVariants(), badgeClassName)}\n                data-fixed={option.fixed}\n                data-disabled={disabled || undefined}\n              >\n                {option.label}\n                <button\n                  className={multiselectTagRemoveVariants()}\n                  onKeyDown={(e) => {\n                    if (e.key === 'Enter') {\n                      handleUnselect(option)\n                    }\n                  }}\n                  onMouseDown={(e) => {\n                    e.preventDefault()\n                    e.stopPropagation()\n                  }}\n                  onClick={() => handleUnselect(option)}\n                  aria-label=\"Remove\"\n                >\n                  <XIcon size={14} aria-hidden=\"true\" />\n                </button>\n              </div>\n            )\n          })}\n          {/* Avoid having the \"Search\" Icon */}\n          <CommandPrimitive.Input\n            {...inputProps}\n            ref={inputRef}\n            value={inputValue}\n            disabled={disabled}\n            onValueChange={(value) => {\n              setInputValue(value)\n              inputProps?.onValueChange?.(value)\n            }}\n            onBlur={(event) => {\n              if (!onScrollbar) {\n                setOpen(false)\n              }\n              inputProps?.onBlur?.(event)\n            }}\n            onFocus={(event) => {\n              setOpen(true)\n              inputProps?.onFocus?.(event)\n            }}\n            placeholder={hidePlaceholderWhenSelected && selected.length !== 0 ? '' : placeholder}\n            className={cn(\n              multiselectInputVariants(),\n              {\n                'w-full': hidePlaceholderWhenSelected,\n                'px-3 py-2': selected.length === 0,\n                'ml-1': selected.length !== 0,\n              },\n              inputProps?.className\n            )}\n          />\n          <button\n            type=\"button\"\n            onClick={() => {\n              setSelected(fixedSelected)\n              emitValueChange(fixedSelected)\n            }}\n            className={cn(\n              multiselectClearButtonVariants(),\n              (hideClearAllButton ||\n                disabled ||\n                selected.length < 1 ||\n                fixedSelected.length === selected.length) &&\n                'hidden'\n            )}\n            aria-label=\"Clear all\"\n          >\n            <XIcon size={16} aria-hidden=\"true\" />\n          </button>\n        </div>\n      </div>\n      <div className=\"relative\">\n        <div\n          className={cn(\n            multiselectDropdownVariants(),\n            'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',\n            !open && 'hidden'\n          )}\n          data-state={open ? 'open' : 'closed'}\n        >\n          {open && (\n            <CommandList\n              className={multiselectListVariants()}\n              onMouseLeave={() => {\n                setOnScrollbar(false)\n              }}\n              onMouseEnter={() => {\n                setOnScrollbar(true)\n              }}\n              onMouseUp={() => {\n                inputRef?.current?.focus()\n              }}\n            >\n              {isLoading ? (\n                <>{loadingIndicator}</>\n              ) : (\n                <>\n                  {emptyNode}\n                  {creatableNode}\n                  {!selectFirstItem && <CommandItem value=\"-\" className=\"hidden\" />}\n                  {selectableEntries.map(([key, dropdowns]) => (\n                    <CommandGroup key={key} heading={key} className={multiselectGroupVariants()}>\n                      <>\n                        {dropdowns.map((option) => {\n                          return (\n                            <CommandItem\n                              key={option.value}\n                              value={option.value}\n                              disabled={option.disable}\n                              onMouseDown={(e) => {\n                                e.preventDefault()\n                                e.stopPropagation()\n                              }}\n                              onSelect={() => {\n                                if (selected.length >= maxSelected) {\n                                  onMaxSelected?.(selected.length)\n                                  return\n                                }\n                                setInputValue('')\n                                const newOptions = [...selected, option]\n                                setSelected(newOptions)\n                                emitValueChange(newOptions)\n                              }}\n                              className={cn(\n                                'cursor-pointer',\n                                option.disable &&\n                                  'pointer-events-none cursor-not-allowed opacity-50'\n                              )}\n                            >\n                              {option.label}\n                            </CommandItem>\n                          )\n                        })}\n                      </>\n                    </CommandGroup>\n                  ))}\n                </>\n              )}\n            </CommandList>\n          )}\n        </div>\n      </div>\n    </Command>\n  )\n}\n\nMultipleSelector.displayName = 'MultipleSelector'\nexport default MultipleSelector\n"
        },
        {
          "path": "registry/default/vue/multiselect/multiselect.vue",
          "target": "components/ui/multiselect/multiselect.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, ref, useId, watch, type Component, type VNodeChild } from \"vue\";\nimport {\n  cn,\n  multiselectClearButtonVariants,\n  multiselectCommandVariants,\n  multiselectContainerVariants,\n  multiselectDropdownVariants,\n  multiselectGroupVariants,\n  multiselectInputVariants,\n  multiselectListVariants,\n  multiselectTagRemoveVariants,\n  multiselectTagVariants,\n} from \"@timui/core\";\nimport { XIcon } from \"lucide-vue-next\";\nimport Command from \"../command/command.vue\";\nimport CommandEmpty from \"../command/command-empty.vue\";\nimport CommandGroup from \"../command/command-group.vue\";\nimport CommandItem from \"../command/command-item.vue\";\nimport CommandList from \"../command/command-list.vue\";\nimport CommandInput from \"../command/command-input.vue\";\nimport type { AssertNoExtraKeys, MultiselectOption, MultiselectVueProps, ComboboxApi } from \"@timui/core\";\n\nexport type Option = MultiselectOption;\n\ninterface GroupOption {\n  [key: string]: Option[];\n}\n\ntype MultiselectProps = MultiselectVueProps & {\n  class?: string;\n  badgeClass?: string;\n  loadingIndicator?: Component | VNodeChild;\n  emptyIndicator?: Component | VNodeChild;\n};\ntype _MultiselectPropsGuard = AssertNoExtraKeys<\n  MultiselectProps,\n  MultiselectVueProps & {\n    class?: string;\n    badgeClass?: string;\n    loadingIndicator?: Component | VNodeChild;\n    emptyIndicator?: Component | VNodeChild;\n  }\n>;\n\nconst props = defineProps<MultiselectProps>();\n\nconst emit = defineEmits([\"update:modelValue\", \"change\"]);\n\nconst inputRef = ref<{ inputEl?: HTMLInputElement | null } | null>(null);\nconst listId = `multiselect-list-${useId()}`;\ntype CommandExpose = { rootEl?: HTMLElement | null; api?: ComboboxApi };\nconst dropdownRef = ref<CommandExpose | null>(null);\nconst open = ref(false);\nconst onScrollbar = ref(false);\nconst isLoading = ref(false);\n\nconst selected = ref<Option[]>(props.modelValue ?? []);\nconst options = ref<GroupOption>({});\nconst inputValue = ref(\"\");\n\nconst maxSelected = computed(() => props.maxSelected ?? Number.MAX_SAFE_INTEGER);\nconst selectFirstItem = computed(() => props.selectFirstItem ?? true);\n\nconst transToGroupOption = (list: Option[] = [], groupBy?: string): GroupOption => {\n  if (list.length === 0) return {};\n  if (!groupBy) return { \"\": list };\n  const groupOption: GroupOption = {};\n  list.forEach((option) => {\n    const key = (option[groupBy] as string) || \"\";\n    if (!groupOption[key]) groupOption[key] = [];\n    groupOption[key].push(option);\n  });\n  return groupOption;\n};\n\nconst removePickedOption = (groupOption: GroupOption, picked: Option[]) => {\n  if (picked.length === 0) return groupOption;\n  const pickedValues = new Set(picked.map((item) => item.value));\n  const next: GroupOption = {};\n  for (const [key, value] of Object.entries(groupOption)) {\n    next[key] = value.filter((val) => !pickedValues.has(val.value));\n  }\n  return next;\n};\n\nconst isOptionsExist = (groupOption: GroupOption, targetOption: Option[]) => {\n  if (targetOption.length === 0) return false;\n  const targetValues = new Set(targetOption.map((item) => item.value));\n  for (const [, value] of Object.entries(groupOption)) {\n    if (value.some((option) => targetValues.has(option.value))) {\n      return true;\n    }\n  }\n  return false;\n};\n\nconst debouncedSearchTerm = ref(\"\");\nlet debounceTimer: number | null = null;\nwatch(\n  () => inputValue.value,\n  (val) => {\n    if (debounceTimer) window.clearTimeout(debounceTimer);\n    debounceTimer = window.setTimeout(() => {\n      debouncedSearchTerm.value = val;\n    }, props.delay ?? 500);\n  }\n);\n\nwatch(\n  () => props.modelValue,\n  (val) => {\n    if (val) selected.value = val;\n  }\n);\n\nwatch(\n  () => props.options,\n  (val) => {\n    if (!val || props.onSearch) return;\n    options.value = transToGroupOption(val, props.groupBy);\n  }\n);\n\nwatch(\n  () => props.defaultOptions,\n  (val) => {\n    if (!props.options && !props.onSearch) {\n      options.value = transToGroupOption(val ?? [], props.groupBy);\n    }\n  },\n  { immediate: true }\n);\n\nwatch(\n  () => [debouncedSearchTerm.value, open.value, props.groupBy],\n  async () => {\n    if (!props.onSearchSync || !open.value) return;\n    if (props.triggerSearchOnFocus || debouncedSearchTerm.value) {\n      const res = props.onSearchSync?.(debouncedSearchTerm.value) ?? [];\n      options.value = transToGroupOption(res, props.groupBy);\n    }\n  }\n);\n\nwatch(\n  () => [debouncedSearchTerm.value, open.value, props.groupBy],\n  async () => {\n    if (!props.onSearch || !open.value) return;\n    if (props.triggerSearchOnFocus || debouncedSearchTerm.value) {\n      isLoading.value = true;\n      const res = (await props.onSearch?.(debouncedSearchTerm.value)) ?? [];\n      options.value = transToGroupOption(res, props.groupBy);\n      isLoading.value = false;\n    }\n  }\n);\n\nconst selectables = computed(() => removePickedOption(options.value, selected.value));\nconst flatSelectables = computed(() =>\n  Object.values(selectables.value).flat().filter((item) => !item.disable)\n);\nconst selectedValueSet = computed(() => new Set(selected.value.map((item) => item.value)));\nconst fixedSelected = computed(() => selected.value.filter((item) => item.fixed));\nconst isClearAllHidden = computed(\n  () =>\n    !!props.hideClearAllButton ||\n    !!props.disabled ||\n    selected.value.length < 1 ||\n    fixedSelected.value.length === selected.value.length\n);\n\nconst setSelected = (next: Option[]) => {\n  selected.value = next;\n  emit(\"update:modelValue\", next);\n  emit(\"change\", next);\n};\n\nconst handleUnselect = (option: Option) => {\n  setSelected(selected.value.filter((s) => s.value !== option.value));\n};\n\nconst getInputEl = () => inputRef.value?.inputEl ?? null;\n\nconst handleClickOutside = (event: MouseEvent | TouchEvent) => {\n  const rootEl = dropdownRef.value?.rootEl ?? null;\n  if (\n    rootEl &&\n    !rootEl.contains(event.target as Node) &&\n    getInputEl() &&\n    !getInputEl()?.contains(event.target as Node)\n  ) {\n    open.value = false;\n    getInputEl()?.blur();\n  }\n};\n\nwatch(open, (isOpen) => {\n  if (isOpen) {\n    document.addEventListener(\"mousedown\", handleClickOutside);\n    document.addEventListener(\"touchend\", handleClickOutside);\n    return;\n  }\n\n  document.removeEventListener(\"mousedown\", handleClickOutside);\n  document.removeEventListener(\"touchend\", handleClickOutside);\n});\n\nonBeforeUnmount(() => {\n  if (debounceTimer) window.clearTimeout(debounceTimer);\n  document.removeEventListener(\"mousedown\", handleClickOutside);\n  document.removeEventListener(\"touchend\", handleClickOutside);\n});\n\nconst creatableItem = computed(() => {\n  if (!props.creatable) return undefined;\n  if (\n    isOptionsExist(options.value, [{ value: inputValue.value, label: inputValue.value }]) ||\n    selectedValueSet.value.has(inputValue.value)\n  ) {\n    return undefined;\n  }\n  if (!props.onSearch && inputValue.value.length > 0) return inputValue.value;\n  if (props.onSearch && debouncedSearchTerm.value.length > 0 && !isLoading.value) {\n    return inputValue.value;\n  }\n  return undefined;\n});\n\nconst emptyIndicatorIsComponent = computed(() => {\n  const value = props.emptyIndicator;\n  return typeof value === \"object\" || typeof value === \"function\";\n});\n\nconst createOption = (value: string): Option => ({ value, label: value });\nconst addCreatableItem = () => {\n  const value = creatableItem.value;\n  if (!value) return;\n  if (selected.value.length >= maxSelected.value) {\n    props.onMaxSelected?.(selected.value.length);\n    return;\n  }\n  inputValue.value = \"\";\n  const next = [...selected.value, createOption(value)];\n  setSelected(next);\n};\n\nconst onInputValueChange = (value: string) => {\n  inputValue.value = value;\n};\n\nconst onKeyDown = (event: KeyboardEvent) => {\n  if (event.key === \"Delete\" || event.key === \"Backspace\") {\n    if (inputValue.value === \"\" && selected.value.length > 0) {\n      const last = selected.value[selected.value.length - 1];\n      if (!last.fixed) handleUnselect(last);\n    }\n  }\n  if (event.key === \"Escape\") {\n    getInputEl()?.blur();\n  }\n};\n\nconst getCommandApi = () => dropdownRef.value?.api ?? null;\nconst highlightFirst = () => {\n  const api = getCommandApi();\n  const first = flatSelectables.value[0];\n  if (api && first) api.setHighlightValue(first.value);\n};\nconst highlightLast = () => {\n  const api = getCommandApi();\n  const last = flatSelectables.value[flatSelectables.value.length - 1];\n  if (api && last) api.setHighlightValue(last.value);\n};\n\nconst onInputKeyDown = (event: KeyboardEvent) => {\n  if (event.key === \"Home\") {\n    event.preventDefault();\n    if (!open.value) {\n      inputValue.value = \"\";\n      return;\n    }\n    highlightFirst();\n    return;\n  }\n  if (event.key === \"End\") {\n    event.preventDefault();\n    if (open.value) {\n      highlightLast();\n      return;\n    }\n    openDropdown();\n    return;\n  }\n  if (event.key === \"PageDown\" || event.key === \"PageUp\") {\n    openDropdown();\n    if (event.key === \"PageDown\") highlightLast();\n    else highlightFirst();\n    return;\n  }\n  if (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n    openDropdown();\n  }\n  onKeyDown(event);\n};\n\nconst openDropdown = () => {\n  if (props.disabled) return;\n  open.value = true;\n  getInputEl()?.focus();\n  if (props.triggerSearchOnFocus) {\n    props.onSearch?.(debouncedSearchTerm.value);\n  }\n};\n</script>\n\n<template>\n  <Command\n    ref=\"dropdownRef\"\n    :class=\"multiselectCommandVariants()\"\n    @keydown=\"onKeyDown\"\n  >\n    <div\n      :class=\"\n        cn(\n          multiselectContainerVariants(),\n          {\n            'p-1': selected.length !== 0,\n            'cursor-text': !props.disabled && selected.length !== 0,\n          },\n          !props.hideClearAllButton && 'pe-9',\n          props.class\n        )\n      \"\n      @focusin=\"openDropdown\"\n      @focusout=\"() => { if (!onScrollbar) open = false }\"\n      @click=\"openDropdown\"\n    >\n      <div class=\"flex flex-wrap gap-1\">\n        <div\n          v-for=\"option in selected\"\n          :key=\"option.value\"\n          :class=\"\n            cn(\n              multiselectTagVariants(),\n              props.badgeClass\n            )\n          \"\n          :data-fixed=\"option.fixed\"\n          :data-disabled=\"props.disabled || undefined\"\n        >\n          {{ option.label }}\n          <button\n            :class=\"multiselectTagRemoveVariants()\"\n            type=\"button\"\n            @mousedown.prevent.stop\n            @click=\"handleUnselect(option)\"\n          >\n            <XIcon :size=\"14\" aria-hidden=\"true\" />\n          </button>\n        </div>\n        <CommandInput\n          ref=\"inputRef\"\n          :on-value-change=\"onInputValueChange\"\n          :list-id=\"listId\"\n          :expanded=\"open\"\n          :placeholder=\"props.hidePlaceholderWhenSelected && selected.length !== 0 ? '' : props.placeholder\"\n          :class=\"\n            cn(\n              multiselectInputVariants(),\n              {\n                'w-full': props.hidePlaceholderWhenSelected,\n                'px-3 py-2': selected.length === 0,\n                'ml-1': selected.length !== 0,\n              }\n            )\n          \"\n          @focus=\"openDropdown\"\n          @blur=\"() => { if (!onScrollbar) open = false }\"\n          @keydown=\"onInputKeyDown\"\n        />\n        <button\n          type=\"button\"\n          :class=\"\n            cn(\n              multiselectClearButtonVariants(),\n              isClearAllHidden && 'hidden'\n            )\n          \"\n          aria-label=\"Clear all\"\n          @click=\"\n            () => {\n              setSelected(fixedSelected);\n            }\n          \"\n        >\n          <XIcon :size=\"16\" aria-hidden=\"true\" />\n        </button>\n      </div>\n    </div>\n    <div class=\"relative\">\n      <div\n        :class=\"\n          cn(\n            multiselectDropdownVariants(),\n            'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',\n            !open && 'hidden'\n          )\n        \"\n        :data-state=\"open ? 'open' : 'closed'\"\n      >\n        <CommandList\n          v-if=\"open\"\n          :id=\"listId\"\n          :class=\"multiselectListVariants()\"\n          @mouseleave=\"onScrollbar = false\"\n          @mouseenter=\"onScrollbar = true\"\n          @mouseup=\"() => getInputEl()?.focus()\"\n        >\n          <template v-if=\"isLoading\">\n            <component :is=\"props.loadingIndicator\" />\n          </template>\n          <template v-else>\n            <CommandEmpty v-if=\"props.emptyIndicator\">\n              <component v-if=\"emptyIndicatorIsComponent\" :is=\"props.emptyIndicator\" />\n              <span v-else>{{ props.emptyIndicator }}</span>\n            </CommandEmpty>\n            <CommandItem\n              v-if=\"creatableItem\"\n              :value=\"creatableItem\"\n              class=\"cursor-pointer\"\n              @mousedown.prevent.stop\n              @click=\"addCreatableItem\"\n            >\n              Create \"{{ creatableItem }}\"\n            </CommandItem>\n            <CommandItem v-if=\"!selectFirstItem\" value=\"-\" class=\"hidden\" />\n            <CommandGroup\n              v-for=\"(dropdowns, key) in selectables\"\n              :key=\"key\"\n              :heading=\"key\"\n              :class=\"multiselectGroupVariants()\"\n            >\n              <CommandItem\n                v-for=\"option in dropdowns\"\n                :key=\"option.value\"\n                :value=\"option.value\"\n                :disabled=\"option.disable\"\n                class=\"cursor-pointer\"\n                @mousedown.prevent.stop\n                @click=\"\n                  () => {\n                    if (selected.length >= maxSelected) {\n                      props.onMaxSelected?.(selected.length);\n                      return;\n                    }\n                    inputValue = '';\n                    const next = [...selected, option];\n                    setSelected(next);\n                  }\n                \"\n              >\n                {{ option.label }}\n              </CommandItem>\n            </CommandGroup>\n          </template>\n        </CommandList>\n      </div>\n    </div>\n  </Command>\n</template>\n"
        },
        {
          "path": "registry/default/html/multiselect.html",
          "target": "components/ui/multiselect.html",
          "type": "registry:component",
          "content": "<label data-slot=\"multiselect\" class=\"border-input absolute top-2 z-10 w-full overflow-hidden rounded-md border\">\n  <span class=\"text-sm font-medium\">Frameworks</span>\n  <select multiple class=\"border-input absolute top-2 z-10 w-full overflow-hidden rounded-md border\">\n    <option>React</option>\n    <option>Vue</option>\n    <option>WeChat Mini Program</option>\n    <option>HTML</option>\n  </select>\n</label>"
        },
        {
          "path": "registry/default/weapp/multiselect.wxml",
          "target": "components/ui/multiselect.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\">\n  <!-- Trigger -->\n  <view \n    class=\"multiselect-trigger\" \n    bindtap=\"onTriggerTap\"\n    data-disabled=\"{{disabled}}\"\n  >\n    <text class=\"multiselect-label\">\n      {{api.value.length > 0 ? '已选 ' + api.value.length + ' 项' : placeholder}}\n    </text>\n    <text class=\"multiselect-arrow\">▼</text>\n  </view>\n\n  <!-- ActionSheet Overlay -->\n  <view \n    wx:if=\"{{api.open}}\" \n    class=\"multiselect-overlay\" \n    bindtap=\"onBackdropTap\"\n  ></view>\n  \n  <!-- ActionSheet Content -->\n  <view \n    wx:if=\"{{api.open}}\" \n    class=\"multiselect-content\"\n    data-state=\"{{api.open ? 'open' : 'closed'}}\"\n  >\n    <view class=\"multiselect-header\">\n      <text class=\"multiselect-title\">{{label || placeholder}}</text>\n      <view class=\"multiselect-close\" bindtap=\"onBackdropTap\">×</view>\n    </view>\n    \n    <scroll-view scroll-y class=\"multiselect-list\">\n      <view \n        wx:for=\"{{items}}\" \n        wx:key=\"{{itemValueKey}}\"\n        class=\"multiselect-item\"\n        data-value=\"{{item[itemValueKey] || item}}\"\n        mark:value=\"{{item[itemValueKey] || item}}\"\n        bindtap=\"onItemTap\"\n        data-selected=\"{{api.value.includes(item[itemValueKey] || item)}}\"\n      >\n        <view class=\"multiselect-checkbox\" data-checked=\"{{api.value.includes(item[itemValueKey] || item)}}\">\n          <text wx:if=\"{{api.value.includes(item[itemValueKey] || item)}}\">✓</text>\n        </view>\n        <text>{{item[itemLabelKey] || item}}</text>\n      </view>\n    </scroll-view>\n\n    <view class=\"multiselect-footer\">\n      <view class=\"multiselect-confirm-btn\" bindtap=\"onConfirmTap\">\n        确认 ({{api.value.length}})\n      </view>\n    </view>\n  </view>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/multiselect.wxss",
          "target": "components/ui/multiselect.wxss",
          "type": "registry:component",
          "content": "/* weapp component styles */\n"
        },
        {
          "path": "registry/default/weapp/multiselect.ts",
          "target": "components/ui/multiselect.ts",
          "type": "registry:component",
          "content": "import { selectCollection } from '@timui/core'\n\nimport { emitTimEvent } from '../utils'\nimport { createCollection, createScopedMachineId } from '../utils/collection'\nimport { setupMultiselectMachine } from './use-multiselect'\n\ntype SelectItemRecord = Record<string, object>\ntype SelectCollection = ReturnType<typeof selectCollection<SelectItemRecord>>\ntype MachineSend = (event: string | { type: string; [key: string]: object }) => void\n\ntype WeappMultiselectApi = {\n  triggerProps?: { onClick?: () => void }\n  selectValue?: (value: string) => void\n  setOpen?: (open: boolean) => void\n  value?: string[]\n}\n\ntype WeappService = {\n  setContext: (context: Record<string, object>) => void\n}\n\ntype WeappMultiselectInternal = WechatMiniprogram.Component.InstanceMethods<\n  Record<string, object>\n> & {\n  _collection?: SelectCollection\n  _service?: WeappService\n  _cleanup?: () => void\n  _send?: MachineSend\n  data: {\n    api: WeappMultiselectApi\n  }\n  properties: {\n    id: string\n    items: SelectItemRecord[]\n    itemLabelKey: string\n    itemValueKey: string\n    value: string[]\n    name: string\n    disabled: boolean\n    multiple: boolean\n    extClass: string\n  }\n}\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    id: { type: String, value: 'multiselect' },\n    items: { type: Array, value: [] },\n    itemLabelKey: { type: String, value: 'label' },\n    itemValueKey: { type: String, value: 'value' },\n    value: { type: Array, value: [] },\n    name: { type: String, value: '' },\n    placeholder: { type: String, value: '请选择' },\n    disabled: { type: Boolean, value: false },\n    label: { type: String, value: '' },\n    multiple: { type: Boolean, value: true },\n    extClass: { type: String, value: '' },\n  },\n\n  data: {\n    api: {} as WeappMultiselectApi,\n    className: '',\n  },\n\n  lifetimes: {\n    attached() {\n      const self = this as WeappMultiselectInternal\n      this.setData({ className: this.properties.extClass })\n      self._collection = createCollection({\n        items: this.properties.items,\n        itemLabelKey: self.properties.itemLabelKey,\n        itemValueKey: self.properties.itemValueKey,\n        factory: selectCollection,\n      })\n\n      const { service, cleanup, send } = setupMultiselectMachine(this, {\n        id: this.properties.id || createScopedMachineId('multiselect'),\n        collection: self._collection,\n        value: this.properties.value,\n        name: this.properties.name,\n        disabled: this.properties.disabled,\n        multiple: this.properties.multiple,\n        onValueChange: (details) => {\n          emitTimEvent(this, 'change', 'change', this.properties.id || 'multiselect', {\n            value: details.value,\n          })\n        },\n      })\n\n      self._service = service as WeappService\n      self._cleanup = cleanup\n      self._send = send\n    },\n    detached() {\n      const self = this as WeappMultiselectInternal\n      self._cleanup?.()\n    },\n  },\n\n  observers: {\n    state: function (state) {\n      const self = this as WeappMultiselectInternal\n      if (!state || !self._send) return\n      const { connect } = setupMultiselectMachine(this, { collection: self._collection })\n      const api = connect(state, self._send) as WeappMultiselectApi\n      this.setData({ api })\n    },\n    items: function (items) {\n      const self = this as WeappMultiselectInternal\n      if (self._service) {\n        self._collection = createCollection({\n          items: items as SelectItemRecord[],\n          itemLabelKey: self.properties.itemLabelKey,\n          itemValueKey: self.properties.itemValueKey,\n          factory: selectCollection,\n        })\n        self._service.setContext({ collection: self._collection })\n      }\n    },\n  },\n\n  methods: {\n    onTriggerTap() {\n      const self = this as WeappMultiselectInternal\n      self.data.api.triggerProps?.onClick?.()\n    },\n    onItemTap(e: WechatMiniprogram.BaseEvent) {\n      const self = this as WeappMultiselectInternal\n      const value = String(e.mark?.value || '')\n      const item = self._collection?.find(value)\n      if (item && self.data.api.selectValue) {\n        self.data.api.selectValue(value)\n      }\n    },\n    onBackdropTap() {\n      const self = this as WeappMultiselectInternal\n      self.data.api.setOpen?.(false)\n    },\n    onConfirmTap() {\n      const self = this as WeappMultiselectInternal\n      self.data.api.setOpen?.(false)\n      this.triggerEvent('confirm', { value: self.data.api.value ?? [] })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/multiselect.json",
          "target": "components/ui/multiselect.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        }
      ],
      "dependencies": [
        "@timui/core"
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core"
            ],
            "optionalPeerDependencies": [
              "cmdk",
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {
            "dependencies": [
              "@timui/core"
            ]
          },
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "navigation-menu",
      "type": "registry:ui",
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/ui/navigation-menu.tsx",
          "type": "registry:ui",
          "target": "components/ui/navigation-menu.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport type { AssertNoExtraKeys, NavigationMenuProps as CoreNavigationMenuProps } from '@timui/core'\nimport {\n  cn,\n  navigationMenuContentVariants,\n  navigationMenuIndicatorIconVariants,\n  navigationMenuIndicatorVariants,\n  navigationMenuItemVariants,\n  navigationMenuLinkVariants,\n  navigationMenuListVariants,\n  navigationMenuTriggerIconVariants,\n  navigationMenuTriggerStyle,\n  navigationMenuVariants,\n  navigationMenuViewportVariants,\n  navigationMenuViewportWrapperVariants,\n} from '@timui/core'\nimport { ChevronDown } from 'lucide-react'\n\nimport { Slot } from './slot'\n\ntype NavigationMenuProps = CoreNavigationMenuProps &\n  Omit<React.HTMLAttributes<HTMLElement>, keyof CoreNavigationMenuProps> & {\n    viewport?: boolean\n  }\ntype _NavigationMenuPropsGuard = AssertNoExtraKeys<\n  NavigationMenuProps,\n  CoreNavigationMenuProps & React.HTMLAttributes<HTMLElement> & { viewport?: boolean }\n>\n\ntype NavigationMenuRootContextValue = {\n  openItem: string | null\n  setOpenItem: React.Dispatch<React.SetStateAction<string | null>>\n  activeItem: string | null\n  setActiveItem: React.Dispatch<React.SetStateAction<string | null>>\n  userSelected: boolean\n  setUserSelected: React.Dispatch<React.SetStateAction<boolean>>\n  viewport: boolean\n}\n\ntype NavigationMenuItemContextValue = {\n  value: string\n  triggerId: string\n  contentId: string\n  open: boolean\n  setOpen: (open: boolean) => void\n}\n\nconst NavigationMenuRootContext = React.createContext<NavigationMenuRootContextValue | null>(null)\nconst NavigationMenuItemContext = React.createContext<NavigationMenuItemContextValue | null>(null)\n\nconst setRef = <T,>(ref: React.Ref<T> | undefined, value: T | null) => {\n  if (!ref) return\n  if (typeof ref === 'function') {\n    ref(value)\n    return\n  }\n  ;(ref as React.MutableRefObject<T | null>).current = value\n}\n\nconst composeRefs = <T,>(...refs: Array<React.Ref<T> | undefined>) => {\n  return (value: T | null) => {\n    refs.forEach((ref) => setRef(ref, value))\n  }\n}\n\nconst composeEventHandlers = <E,>(\n  theirHandler: ((event: E) => void) | undefined,\n  ourHandler: (event: E) => void\n) => {\n  return (event: E) => {\n    theirHandler?.(event)\n    ourHandler(event)\n  }\n}\n\nconst useNavigationMenuRootContext = () => React.useContext(NavigationMenuRootContext)\n\nconst useNavigationMenuItemContext = () => {\n  const context = React.useContext(NavigationMenuItemContext)\n  if (!context) {\n    throw new Error('NavigationMenu subcomponents must be used within NavigationMenuItem.')\n  }\n  return context\n}\n\nconst NavigationMenu = React.forwardRef<HTMLElement, NavigationMenuProps>(\n  ({ className, children, orientation = 'horizontal', viewport = true, ...props }, ref) => {\n    const [openItem, setOpenItem] = React.useState<string | null>(null)\n    const [activeItem, setActiveItem] = React.useState<string | null>(null)\n    const [userSelected, setUserSelected] = React.useState(false)\n    const localRef = React.useRef<HTMLElement | null>(null)\n\n    React.useEffect(() => {\n      const onPointerDown = (event: PointerEvent) => {\n        const target = event.target\n        if (!(target instanceof Node)) return\n        if (!localRef.current?.contains(target)) {\n          setOpenItem(null)\n        }\n      }\n\n      document.addEventListener('pointerdown', onPointerDown)\n      return () => document.removeEventListener('pointerdown', onPointerDown)\n    }, [])\n\n    return (\n      <NavigationMenuRootContext.Provider\n        value={{\n          openItem,\n          setOpenItem,\n          activeItem,\n          setActiveItem,\n          userSelected,\n          setUserSelected,\n          viewport,\n        }}\n      >\n        <nav\n          ref={composeRefs(ref, localRef)}\n          data-slot=\"navigation-menu\"\n          data-orientation={orientation}\n          className={cn(navigationMenuVariants(), className)}\n          {...props}\n        >\n          {children}\n        </nav>\n      </NavigationMenuRootContext.Provider>\n    )\n  }\n)\nNavigationMenu.displayName = 'NavigationMenu'\n\ntype NavigationMenuListProps = React.ComponentPropsWithoutRef<'ul'>\ntype NavigationMenuItemProps = React.ComponentPropsWithoutRef<'li'>\ntype NavigationMenuTriggerProps = React.ComponentPropsWithoutRef<'button'> & {\n  asChild?: boolean\n}\ntype NavigationMenuContentProps = React.ComponentPropsWithoutRef<'div'>\ntype NavigationMenuLinkProps = React.ComponentPropsWithoutRef<'a'> & {\n  asChild?: boolean\n  active?: boolean\n}\ntype NavigationMenuViewportProps = React.ComponentPropsWithoutRef<'div'>\ntype NavigationMenuIndicatorProps = React.ComponentPropsWithoutRef<'div'>\n\nconst NavigationMenuList = React.forwardRef<HTMLUListElement, NavigationMenuListProps>(\n  ({ className, ...props }, ref) => (\n    <ul\n      ref={ref}\n      data-slot=\"navigation-menu-list\"\n      className={cn(navigationMenuListVariants(), className)}\n      {...props}\n    />\n  )\n)\nNavigationMenuList.displayName = 'NavigationMenuList'\n\nconst NavigationMenuItem = React.forwardRef<HTMLLIElement, NavigationMenuItemProps>(\n  ({ className, onBlur, onMouseLeave, ...props }, ref) => {\n    const root = useNavigationMenuRootContext()\n    const value = React.useId()\n    const triggerId = React.useId()\n    const contentId = React.useId()\n    const open = root?.openItem === value\n\n    const setOpen = React.useCallback(\n      (nextOpen: boolean) => root?.setOpenItem(nextOpen ? value : null),\n      [root, value]\n    )\n\n    const handleBlur = composeEventHandlers(onBlur, (event: React.FocusEvent<HTMLLIElement>) => {\n      const relatedTarget = event.relatedTarget as Node | null\n      if (!relatedTarget || !event.currentTarget.contains(relatedTarget)) {\n        setOpen(false)\n      }\n    })\n\n    const handleMouseLeave = composeEventHandlers(onMouseLeave, () => {\n      setOpen(false)\n    })\n\n    return (\n      <NavigationMenuItemContext.Provider value={{ value, triggerId, contentId, open, setOpen }}>\n        <li\n          ref={ref}\n          data-slot=\"navigation-menu-item\"\n          data-state={open ? 'open' : 'closed'}\n          className={cn(navigationMenuItemVariants(), className)}\n          onBlur={handleBlur}\n          onMouseLeave={handleMouseLeave}\n          {...props}\n        />\n      </NavigationMenuItemContext.Provider>\n    )\n  }\n)\nNavigationMenuItem.displayName = 'NavigationMenuItem'\n\nconst NavigationMenuTrigger = React.forwardRef<HTMLButtonElement, NavigationMenuTriggerProps>(\n  ({ className, children, asChild = false, onClick, onKeyDown, onPointerEnter, ...props }, ref) => {\n    const item = useNavigationMenuItemContext()\n    const Comp = asChild ? Slot : 'button'\n    const handleClick = composeEventHandlers(onClick, () => {\n      item.setOpen(!item.open)\n    })\n    const handlePointerEnter = composeEventHandlers(onPointerEnter, () => {\n      item.setOpen(true)\n    })\n    const handleKeyDown = composeEventHandlers(onKeyDown, (event: React.KeyboardEvent) => {\n      if (event.key === 'Escape') {\n        item.setOpen(false)\n        return\n      }\n\n      if (event.key === 'Enter' || event.key === ' ' || event.key === 'ArrowDown') {\n        event.preventDefault()\n        item.setOpen(true)\n      }\n    })\n\n    return (\n      <Comp\n        ref={ref}\n        id={item.triggerId}\n        aria-controls={item.contentId}\n        aria-expanded={item.open}\n        data-slot=\"navigation-menu-trigger\"\n        data-state={item.open ? 'open' : 'closed'}\n        className={cn(navigationMenuTriggerStyle(), 'group', className)}\n        onClick={handleClick}\n        onPointerEnter={handlePointerEnter}\n        onKeyDown={handleKeyDown}\n        {...props}\n      >\n        {children}\n        <ChevronDown className={navigationMenuTriggerIconVariants()} aria-hidden=\"true\" />\n      </Comp>\n    )\n  }\n)\nNavigationMenuTrigger.displayName = 'NavigationMenuTrigger'\n\nconst NavigationMenuContent = React.forwardRef<HTMLDivElement, NavigationMenuContentProps>(\n  ({ className, ...props }, ref) => {\n    const item = useNavigationMenuItemContext()\n    if (!item.open) return null\n\n    return (\n      <div\n        ref={ref}\n        id={item.contentId}\n        aria-labelledby={item.triggerId}\n        data-slot=\"navigation-menu-content\"\n        data-state=\"open\"\n        className={cn(\n          navigationMenuContentVariants(),\n          'absolute left-0 top-full mt-1 md:left-0 md:top-full',\n          className\n        )}\n        {...props}\n      />\n    )\n  }\n)\nNavigationMenuContent.displayName = 'NavigationMenuContent'\n\nconst NavigationMenuLink = React.forwardRef<HTMLAnchorElement, NavigationMenuLinkProps>(\n  ({ className, asChild = false, active, onClick, ...props }, ref) => {\n    const root = useNavigationMenuRootContext()\n    const Comp = asChild ? Slot : 'a'\n    const linkId = React.useId()\n    const isActive = root?.userSelected ? root.activeItem === linkId : !!active\n\n    const handleClick = composeEventHandlers(onClick, () => {\n      root?.setOpenItem(null)\n      root?.setActiveItem(linkId)\n      root?.setUserSelected(true)\n    })\n\n    React.useEffect(() => {\n      if (!root) return\n      if (root.userSelected) return\n      if (!active) return\n      if (root.activeItem) return\n      root.setActiveItem(linkId)\n    }, [active, linkId, root])\n\n    return (\n      <Comp\n        ref={ref}\n        data-slot=\"navigation-menu-link\"\n        data-active={isActive ? '' : undefined}\n        aria-current={isActive ? 'page' : props['aria-current']}\n        className={cn(navigationMenuLinkVariants(), className)}\n        onClick={handleClick}\n        {...props}\n      />\n    )\n  }\n)\nNavigationMenuLink.displayName = 'NavigationMenuLink'\n\nconst NavigationMenuViewport = React.forwardRef<HTMLDivElement, NavigationMenuViewportProps>(\n  ({ className, ...props }, ref) => {\n    const root = useNavigationMenuRootContext()\n    if (root && !root.viewport) return null\n\n    return (\n      <div className={navigationMenuViewportWrapperVariants()}>\n        <div\n          ref={ref}\n          data-slot=\"navigation-menu-viewport\"\n          data-state={root?.openItem ? 'open' : 'closed'}\n          className={cn(navigationMenuViewportVariants(), className)}\n          {...props}\n        />\n      </div>\n    )\n  }\n)\nNavigationMenuViewport.displayName = 'NavigationMenuViewport'\n\nconst NavigationMenuIndicator = React.forwardRef<HTMLDivElement, NavigationMenuIndicatorProps>(\n  ({ className, ...props }, ref) => {\n    const root = useNavigationMenuRootContext()\n    if (!root?.openItem) return null\n\n    return (\n      <div\n        ref={ref}\n        data-slot=\"navigation-menu-indicator\"\n        data-state=\"visible\"\n        className={cn(navigationMenuIndicatorVariants(), className)}\n        {...props}\n      >\n        <div className={navigationMenuIndicatorIconVariants()} />\n      </div>\n    )\n  }\n)\nNavigationMenuIndicator.displayName = 'NavigationMenuIndicator'\n\nexport {\n  NavigationMenu,\n  NavigationMenuList,\n  NavigationMenuItem,\n  NavigationMenuContent,\n  NavigationMenuTrigger,\n  NavigationMenuLink,\n  NavigationMenuIndicator,\n  NavigationMenuViewport,\n  navigationMenuTriggerStyle,\n}\n"
        },
        {
          "path": "registry/default/vue/navigation-menu/navigation-menu-content.vue",
          "target": "components/ui/navigation-menu/navigation-menu-content.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, navigationMenuContentVariants } from '@timui/core'\nimport type { HTMLAttributes } from 'vue'\n\nimport { useNavigationMenuItemContext } from './use-navigation-menu-context'\n\nconst props = defineProps<{ class?: HTMLAttributes['class'] }>()\nconst item = useNavigationMenuItemContext()\n</script>\n\n<template>\n  <div\n    v-if=\"item?.open.value\"\n    :id=\"item?.contentId.value\"\n    :aria-labelledby=\"item?.triggerId.value\"\n    data-slot=\"navigation-menu-content\"\n    data-state=\"open\"\n    :class=\"\n      cn(\n        navigationMenuContentVariants(),\n        'absolute left-0 top-full mt-1 md:left-0 md:top-full',\n        props.class\n      )\n    \"\n  >\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/navigation-menu/navigation-menu-indicator.vue",
          "target": "components/ui/navigation-menu/navigation-menu-indicator.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, navigationMenuIndicatorIconVariants, navigationMenuIndicatorVariants } from '@timui/core'\nimport type { HTMLAttributes } from 'vue'\n\nimport { useNavigationMenuRootContext } from './use-navigation-menu-context'\n\nconst props = defineProps<{ class?: HTMLAttributes['class'] }>()\nconst root = useNavigationMenuRootContext()\n</script>\n\n<template>\n  <div\n    v-if=\"root?.openItem.value\"\n    data-slot=\"navigation-menu-indicator\"\n    data-state=\"visible\"\n    :class=\"\n      cn(\n        navigationMenuIndicatorVariants(),\n        props.class\n      )\n    \"\n  >\n    <div :class=\"navigationMenuIndicatorIconVariants()\" />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/navigation-menu/navigation-menu-item.vue",
          "target": "components/ui/navigation-menu/navigation-menu-item.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, navigationMenuItemVariants } from '@timui/core'\nimport { computed, ref, useId, type HTMLAttributes } from 'vue'\n\nimport {\n  provideNavigationMenuItemContext,\n  useNavigationMenuRootContext,\n} from './use-navigation-menu-context'\n\nconst props = defineProps<{ class?: HTMLAttributes['class'] }>()\nconst root = useNavigationMenuRootContext()\nconst itemRef = ref<HTMLElement | null>(null)\nconst value = ref(useId())\nconst triggerId = ref(`nav-trigger-${useId()}`)\nconst contentId = ref(`nav-content-${useId()}`)\nconst open = computed(() => root?.openItem.value === value.value)\n\nconst setOpen = (nextOpen: boolean) => {\n  root?.setOpenItem(nextOpen ? value.value : null)\n}\n\nconst onFocusOut = (event: FocusEvent) => {\n  const related = event.relatedTarget\n  if (!(related instanceof Node)) {\n    setOpen(false)\n    return\n  }\n  if (!itemRef.value?.contains(related)) {\n    setOpen(false)\n  }\n}\n\nconst onMouseLeave = () => {\n  setOpen(false)\n}\n\nprovideNavigationMenuItemContext({\n  value,\n  triggerId,\n  contentId,\n  open,\n  setOpen,\n})\n</script>\n\n<template>\n  <li\n    ref=\"itemRef\"\n    data-slot=\"navigation-menu-item\"\n    :data-state=\"open ? 'open' : 'closed'\"\n    :class=\"cn(navigationMenuItemVariants(), props.class)\"\n    @focusout=\"onFocusOut\"\n    @mouseleave=\"onMouseLeave\"\n  >\n    <slot />\n  </li>\n</template>\n"
        },
        {
          "path": "registry/default/vue/navigation-menu/navigation-menu-link.vue",
          "target": "components/ui/navigation-menu/navigation-menu-link.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, navigationMenuLinkVariants } from '@timui/core'\nimport { computed, onMounted, useId, type HTMLAttributes } from 'vue'\n\nimport { useNavigationMenuRootContext } from './use-navigation-menu-context'\n\nconst props = defineProps<{ class?: HTMLAttributes['class']; active?: boolean }>()\nconst root = useNavigationMenuRootContext()\nconst linkId = useId()\n\nconst isActive = computed(() => {\n  if (!root) return !!props.active\n  return root.userSelected.value ? root.activeItem.value === linkId : !!props.active\n})\n\nconst onClick = () => {\n  root?.setOpenItem(null)\n  root?.setActiveItem(linkId)\n  root?.setUserSelected(true)\n}\n\nonMounted(() => {\n  if (!root) return\n  if (root.userSelected.value) return\n  if (!props.active) return\n  if (root.activeItem.value) return\n  root.setActiveItem(linkId)\n})\n</script>\n\n<template>\n  <a\n    data-slot=\"navigation-menu-link\"\n    :data-active=\"isActive ? '' : undefined\"\n    :aria-current=\"isActive ? 'page' : undefined\"\n    :class=\"\n      cn(\n        navigationMenuLinkVariants(),\n        props.class\n      )\n    \"\n    @click=\"onClick\"\n  >\n    <slot />\n  </a>\n</template>\n"
        },
        {
          "path": "registry/default/vue/navigation-menu/navigation-menu-list.vue",
          "target": "components/ui/navigation-menu/navigation-menu-list.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, navigationMenuListVariants } from \"@timui/core\";\nimport type { HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\n</script>\n\n<template>\n  <ul\n    data-slot=\"navigation-menu-list\"\n    :class=\"\n      cn(navigationMenuListVariants(), props.class)\n    \"\n  >\n    <slot />\n  </ul>\n</template>\n"
        },
        {
          "path": "registry/default/vue/navigation-menu/navigation-menu-trigger.vue",
          "target": "components/ui/navigation-menu/navigation-menu-trigger.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ChevronDownIcon } from 'lucide-vue-next'\nimport { cn, navigationMenuTriggerIconVariants, navigationMenuTriggerStyle } from '@timui/core'\nimport type { HTMLAttributes } from 'vue'\n\nimport { useNavigationMenuItemContext } from './use-navigation-menu-context'\n\nconst props = defineProps<{ class?: HTMLAttributes['class'] }>()\nconst item = useNavigationMenuItemContext()\n\nconst onClick = () => {\n  if (!item) return\n  item.setOpen(!item.open.value)\n}\n\nconst onPointerEnter = () => {\n  item?.setOpen(true)\n}\n\nconst onKeyDown = (event: KeyboardEvent) => {\n  if (!item) return\n  if (event.key === 'Escape') {\n    item.setOpen(false)\n    return\n  }\n\n  if (event.key === 'Enter' || event.key === ' ' || event.key === 'ArrowDown') {\n    event.preventDefault()\n    item.setOpen(true)\n  }\n}\n</script>\n\n<template>\n  <button\n    :id=\"item?.triggerId.value\"\n    :aria-controls=\"item?.contentId.value\"\n    :aria-expanded=\"item?.open.value ?? false\"\n    data-slot=\"navigation-menu-trigger\"\n    :data-state=\"item?.open.value ? 'open' : 'closed'\"\n    :class=\"cn(navigationMenuTriggerStyle(), 'group', props.class)\"\n    type=\"button\"\n    @click=\"onClick\"\n    @pointerenter=\"onPointerEnter\"\n    @keydown=\"onKeyDown\"\n  >\n    <slot />\n    <ChevronDownIcon\n      :class=\"navigationMenuTriggerIconVariants()\"\n      aria-hidden=\"true\"\n    />\n  </button>\n</template>\n"
        },
        {
          "path": "registry/default/vue/navigation-menu/navigation-menu-viewport.vue",
          "target": "components/ui/navigation-menu/navigation-menu-viewport.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, navigationMenuViewportVariants, navigationMenuViewportWrapperVariants } from '@timui/core'\nimport type { HTMLAttributes } from 'vue'\n\nimport { useNavigationMenuRootContext } from './use-navigation-menu-context'\n\nconst props = defineProps<{ class?: HTMLAttributes['class'] }>()\nconst root = useNavigationMenuRootContext()\n</script>\n\n<template>\n  <div v-if=\"root?.viewport.value\" :class=\"navigationMenuViewportWrapperVariants()\">\n    <div\n      data-slot=\"navigation-menu-viewport\"\n      :data-state=\"root?.openItem.value ? 'open' : 'closed'\"\n      :class=\"\n        cn(\n          navigationMenuViewportVariants(),\n          props.class\n        )\n      \"\n    />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/navigation-menu/navigation-menu.vue",
          "target": "components/ui/navigation-menu/navigation-menu.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport type { AssertNoExtraKeys, NavigationMenuProps } from '@timui/core'\nimport { cn, navigationMenuVariants } from '@timui/core'\nimport {\n  computed,\n  onBeforeUnmount,\n  onMounted,\n  ref,\n  type HTMLAttributes,\n} from 'vue'\n\nimport NavigationMenuViewport from './navigation-menu-viewport.vue'\nimport { provideNavigationMenuRootContext } from './use-navigation-menu-context'\n\ntype Props = NavigationMenuProps & { class?: HTMLAttributes['class']; viewport?: boolean }\ntype _NavigationMenuPropsGuard = AssertNoExtraKeys<\n  Props,\n  NavigationMenuProps & { class?: HTMLAttributes['class']; viewport?: boolean }\n>\n\nconst props = withDefaults(defineProps<Props>(), {\n  orientation: 'horizontal',\n  viewport: true,\n})\n\nconst rootRef = ref<HTMLElement | null>(null)\nconst openItem = ref<string | null>(null)\nconst activeItem = ref<string | null>(null)\nconst userSelected = ref(false)\nconst viewport = computed(() => props.viewport ?? true)\n\nconst setOpenItem = (value: string | null) => {\n  openItem.value = value\n}\n\nconst setActiveItem = (value: string | null) => {\n  activeItem.value = value\n}\n\nconst setUserSelected = (value: boolean) => {\n  userSelected.value = value\n}\n\nconst onPointerDown = (event: PointerEvent) => {\n  const target = event.target\n  if (!(target instanceof Node)) return\n  if (!rootRef.value?.contains(target)) {\n    setOpenItem(null)\n  }\n}\n\nonMounted(() => {\n  document.addEventListener('pointerdown', onPointerDown)\n})\n\nonBeforeUnmount(() => {\n  document.removeEventListener('pointerdown', onPointerDown)\n})\n\nprovideNavigationMenuRootContext({\n  openItem,\n  setOpenItem,\n  activeItem,\n  setActiveItem,\n  userSelected,\n  setUserSelected,\n  viewport,\n})\n</script>\n\n<template>\n  <nav\n    ref=\"rootRef\"\n    data-slot=\"navigation-menu\"\n    :data-orientation=\"props.orientation\"\n    :class=\"\n      cn(navigationMenuVariants(), props.class)\n    \"\n  >\n    <slot />\n    <NavigationMenuViewport v-if=\"props.viewport\" />\n  </nav>\n</template>\n"
        },
        {
          "path": "registry/default/vue/navigation-menu/use-navigation-menu-context.ts",
          "target": "components/ui/navigation-menu/use-navigation-menu-context.ts",
          "type": "registry:component",
          "content": "import { inject, provide, type InjectionKey, type Ref } from 'vue'\n\nexport type NavigationMenuRootContextValue = {\n  openItem: Ref<string | null>\n  setOpenItem: (value: string | null) => void\n  activeItem: Ref<string | null>\n  setActiveItem: (value: string | null) => void\n  userSelected: Ref<boolean>\n  setUserSelected: (value: boolean) => void\n  viewport: Ref<boolean>\n}\n\nexport type NavigationMenuItemContextValue = {\n  value: Ref<string>\n  triggerId: Ref<string>\n  contentId: Ref<string>\n  open: Ref<boolean>\n  setOpen: (open: boolean) => void\n}\n\nconst navigationMenuRootContextKey: InjectionKey<NavigationMenuRootContextValue> = Symbol(\n  'navigationMenuRootContext'\n)\nconst navigationMenuItemContextKey: InjectionKey<NavigationMenuItemContextValue> = Symbol(\n  'navigationMenuItemContext'\n)\n\nexport function provideNavigationMenuRootContext(value: NavigationMenuRootContextValue) {\n  provide(navigationMenuRootContextKey, value)\n}\n\nexport function useNavigationMenuRootContext() {\n  return inject(navigationMenuRootContextKey, null)\n}\n\nexport function provideNavigationMenuItemContext(value: NavigationMenuItemContextValue) {\n  provide(navigationMenuItemContextKey, value)\n}\n\nexport function useNavigationMenuItemContext() {\n  return inject(navigationMenuItemContextKey, null)\n}\n"
        },
        {
          "path": "registry/default/html/navigation-menu.html",
          "target": "components/ui/navigation-menu.html",
          "type": "registry:component",
          "content": "<div data-timui-root data-timui-init=\"auto\">\n  <nav data-slot=\"navigation-menu\" class=\"relative inline-flex items-center gap-2\">\n    <div data-slot=\"navigation-menu-item\" data-state=\"closed\" class=\"relative\">\n      <button\n        data-slot=\"navigation-menu-trigger\"\n        type=\"button\"\n        data-state=\"closed\"\n        aria-expanded=\"false\"\n        class=\"group inline-flex h-10 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state&#x3D;open]:bg-accent/50\"\n      >\n        Platform\n      </button>\n      <div\n        data-slot=\"navigation-menu-content\"\n        data-state=\"closed\"\n        hidden\n        class=\"absolute left-0 top-full z-10 mt-2 w-72 rounded-md border bg-popover p-4 shadow-md\"\n      >\n        <div class=\"grid gap-2 text-sm\">\n          <a href=\"#\" data-slot=\"navigation-menu-link\" class=\"rounded-sm px-2 py-1.5 hover:bg-accent\">React and Vue use shared core variants.</a>\n          <a href=\"#\" data-slot=\"navigation-menu-link\" class=\"rounded-sm px-2 py-1.5 hover:bg-accent\">HTML demos declare template-only or adapter-backed behavior.</a>\n          <a href=\"#\" data-slot=\"navigation-menu-link\" class=\"rounded-sm px-2 py-1.5 hover:bg-accent\">Weapp follows TimEvent and mini-program component rules.</a>\n        </div>\n      </div>\n    </div>\n    <a href=\"#\" data-slot=\"navigation-menu-link\" class=\"group inline-flex h-10 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state&#x3D;open]:bg-accent/50\">Documentation</a>\n  </nav>\n</div>\n<script type=\"module\">\n  import { autoInitHtmlRuntime } from '@timui/html'\n  autoInitHtmlRuntime({ components: ['navigation-menu'] })\n</script>"
        },
        {
          "path": "registry/default/weapp/navigation-menu.wxml",
          "target": "components/ui/navigation-menu.wxml",
          "type": "registry:component",
          "content": "<view class=\"navigation-menu {{extClass}}\">\n  <view\n    wx:for=\"{{items}}\"\n    wx:key=\"value\"\n    class=\"navigation-menu-item {{item.value === value ? 'is-active' : ''}} {{item.disabled ? 'is-disabled' : ''}}\"\n    data-value=\"{{item.value}}\"\n    bindtap=\"onSelect\"\n  >\n    <text>{{item.label}}</text>\n  </view>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/navigation-menu.wxss",
          "target": "components/ui/navigation-menu.wxss",
          "type": "registry:component",
          "content": ".navigation-menu {\n  display: flex;\n  gap: 12rpx;\n  align-items: center;\n}\n\n.navigation-menu-item {\n  padding: 10rpx 16rpx;\n  border-radius: 999rpx;\n  background: #f3f4f6;\n  color: #111827;\n  font-size: 26rpx;\n}\n\n.is-active {\n  background: #111827;\n  color: #ffffff;\n}\n\n.is-disabled {\n  opacity: 0.5;\n}\n"
        },
        {
          "path": "registry/default/weapp/navigation-menu.ts",
          "target": "components/ui/navigation-menu.ts",
          "type": "registry:component",
          "content": "import { emitTimEvent } from '../utils'\n\ntype NavigationItem = {\n  label: string\n  value: string\n  disabled?: boolean\n}\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    items: {\n      type: Array,\n      value: [],\n    },\n    value: {\n      type: String,\n      value: '',\n    },\n    id: {\n      type: String,\n      value: 'navigation-menu',\n    },\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n\n  methods: {\n    onSelect(e: WechatMiniprogram.BaseEvent) {\n      const value = String(e.currentTarget.dataset.value || '')\n      const item = ((this.properties.items || []) as NavigationItem[]).find(\n        (x) => x.value === value\n      )\n      if (!item || item.disabled) return\n      emitTimEvent(this, 'change', 'change', this.properties.id || 'navigation-menu', {\n        value,\n        item,\n      })\n      this.triggerEvent('update:value', value)\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/navigation-menu.json",
          "target": "components/ui/navigation-menu.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        }
      ],
      "dependencies": [
        "@timui/core"
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "pagination",
      "type": "registry:ui",
      "registryDependencies": [
        "button"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/ui/pagination.tsx",
          "type": "registry:ui",
          "target": "components/ui/pagination.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport {\n  cn,\n  paginationEllipsisVariants,\n  paginationListVariants,\n  paginationNextVariants,\n  paginationPreviousVariants,\n  paginationRootVariants,\n} from '@timui/core'\nimport { ChevronLeftIcon, ChevronRightIcon, MoreHorizontalIcon } from 'lucide-react'\n\nimport { Button, buttonVariants } from './button'\n\nfunction Pagination({ className, ...props }: React.ComponentProps<'nav'>) {\n  return (\n    <nav\n      role=\"navigation\"\n      aria-label=\"pagination\"\n      data-slot=\"pagination\"\n      className={cn(paginationRootVariants(), className)}\n      {...props}\n    />\n  )\n}\n\nfunction PaginationContent({ className, ...props }: React.ComponentProps<'ul'>) {\n  return (\n    <ul\n      data-slot=\"pagination-content\"\n      className={cn(paginationListVariants(), className)}\n      {...props}\n    />\n  )\n}\n\nfunction PaginationItem({ ...props }: React.ComponentProps<'li'>) {\n  return <li data-slot=\"pagination-item\" {...props} />\n}\n\ntype PaginationLinkProps = {\n  isActive?: boolean\n  isDisabled?: boolean\n} & Pick<React.ComponentProps<typeof Button>, 'size'> &\n  React.ComponentProps<'a'>\n\nfunction PaginationLink({ className, isActive, size = 'icon', ...props }: PaginationLinkProps) {\n  return (\n    <a\n      aria-current={isActive ? 'page' : undefined}\n      data-slot=\"pagination-link\"\n      data-active={isActive}\n      className={cn(\n        buttonVariants({\n          variant: isActive ? 'outline' : 'ghost',\n          size,\n        }),\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction PaginationPrevious({ className, ...props }: React.ComponentProps<typeof PaginationLink>) {\n  return (\n    <PaginationLink\n      aria-label=\"Go to previous page\"\n      size=\"default\"\n      className={cn(paginationPreviousVariants(), className)}\n      {...props}\n    >\n      <ChevronLeftIcon size={16} />\n      <span>Previous</span>\n    </PaginationLink>\n  )\n}\n\nfunction PaginationNext({ className, ...props }: React.ComponentProps<typeof PaginationLink>) {\n  return (\n    <PaginationLink\n      aria-label=\"Go to next page\"\n      size=\"default\"\n      className={cn(paginationNextVariants(), className)}\n      {...props}\n    >\n      <span>Next</span>\n      <ChevronRightIcon size={16} />\n    </PaginationLink>\n  )\n}\n\nfunction PaginationEllipsis({ className, ...props }: React.ComponentProps<'span'>) {\n  return (\n    <span\n      aria-hidden\n      data-slot=\"pagination-ellipsis\"\n      className={cn(paginationEllipsisVariants(), className)}\n      {...props}\n    >\n      <MoreHorizontalIcon size={16} />\n      <span className=\"sr-only\">More pages</span>\n    </span>\n  )\n}\n\nexport {\n  Pagination,\n  PaginationContent,\n  PaginationEllipsis,\n  PaginationItem,\n  PaginationLink,\n  PaginationNext,\n  PaginationPrevious,\n}\n"
        },
        {
          "path": "registry/default/vue/pagination/pagination-content.vue",
          "target": "components/ui/pagination/pagination-content.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed, inject, useSlots } from \"vue\";\nimport { cn, paginationListVariants } from '@timui/core';\nimport { PaginationContextKey } from \"./pagination-context\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\nconst slots = useSlots();\nconst context = inject(PaginationContextKey, null);\nconst pages = computed(() => context?.api.value?.pages ?? []);\n</script>\n\n<template>\n  <ul :class=\"cn(paginationListVariants(), props.class)\">\n    <slot>\n      <template v-for=\"(item, index) in pages\" :key=\"index\">\n        <li v-if=\"item.type === 'page'\">\n          <slot name=\"page\" :page=\"item.value\" />\n        </li>\n        <li v-else>\n          <slot name=\"ellipsis\" :index=\"index\" />\n        </li>\n      </template>\n    </slot>\n  </ul>\n</template>\n"
        },
        {
          "path": "registry/default/vue/pagination/pagination-context.ts",
          "target": "components/ui/pagination/pagination-context.ts",
          "type": "registry:component",
          "content": "import type { PaginationApi } from '@timui/core'\nimport type { ComputedRef, InjectionKey } from 'vue'\n\nexport type PaginationContextValue = {\n  api: ComputedRef<PaginationApi | null>\n}\n\nexport const PaginationContextKey = Symbol(\n  'PaginationContext'\n) as InjectionKey<PaginationContextValue>\n"
        },
        {
          "path": "registry/default/vue/pagination/pagination-ellipsis.vue",
          "target": "components/ui/pagination/pagination-ellipsis.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed, inject } from \"vue\";\nimport { MoreHorizontal } from \"lucide-vue-next\";\nimport { cn, paginationEllipsisVariants } from '@timui/core';\nimport { PaginationContextKey } from \"./pagination-context\";\n\nconst props = defineProps<{ index: number; class?: HTMLAttributes[\"class\"] }>();\nconst context = inject(PaginationContextKey, null);\nconst ellipsisProps = computed(() =>\n  context?.api.value?.getEllipsisProps?.({ index: props.index }) ?? {}\n);\n</script>\n\n<template>\n  <li>\n    <span\n      v-bind=\"ellipsisProps\"\n      :class=\"cn(paginationEllipsisVariants(), props.class)\"\n    >\n      <slot>\n        <MoreHorizontal class=\"h-4 w-4\" />\n        <span class=\"sr-only\">More pages</span>\n      </slot>\n    </span>\n  </li>\n</template>\n"
        },
        {
          "path": "registry/default/vue/pagination/pagination-first.vue",
          "target": "components/ui/pagination/pagination-first.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed, inject } from \"vue\";\nimport { ChevronsLeft } from \"lucide-vue-next\";\nimport { cn, paginationFirstVariants } from '@timui/core';\nimport Button from \"../button/button.vue\";\nimport { PaginationContextKey } from \"./pagination-context\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\nconst context = inject(PaginationContextKey, null);\nconst triggerProps = computed(() => context?.api.value?.getFirstTriggerProps?.() ?? {});\n</script>\n\n<template>\n  <li>\n    <Button\n      v-bind=\"triggerProps\"\n      :class=\"cn(paginationFirstVariants(), props.class)\"\n      variant=\"ghost\"\n      size=\"default\"\n    >\n      <slot>\n        <ChevronsLeft class=\"h-4 w-4\" />\n        <span class=\"sr-only\">First</span>\n      </slot>\n    </Button>\n  </li>\n</template>\n"
        },
        {
          "path": "registry/default/vue/pagination/pagination-item.vue",
          "target": "components/ui/pagination/pagination-item.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed } from \"vue\";\nimport { cn } from '@timui/core';\n\nconst props = defineProps<{\n  class?: HTMLAttributes[\"class\"];\n}>();\n</script>\n\n<template>\n  <li :class=\"cn('', props.class)\">\n    <slot />\n  </li>\n</template>\n"
        },
        {
          "path": "registry/default/vue/pagination/pagination-last.vue",
          "target": "components/ui/pagination/pagination-last.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed, inject } from \"vue\";\nimport { ChevronsRight } from \"lucide-vue-next\";\nimport { cn, paginationLastVariants } from '@timui/core';\nimport Button from \"../button/button.vue\";\nimport { PaginationContextKey } from \"./pagination-context\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\nconst context = inject(PaginationContextKey, null);\nconst triggerProps = computed(() => context?.api.value?.getLastTriggerProps?.() ?? {});\n</script>\n\n<template>\n  <li>\n    <Button\n      v-bind=\"triggerProps\"\n      :class=\"cn(paginationLastVariants(), props.class)\"\n      variant=\"ghost\"\n      size=\"default\"\n    >\n      <slot>\n        <ChevronsRight class=\"h-4 w-4\" />\n        <span class=\"sr-only\">Last</span>\n      </slot>\n    </Button>\n  </li>\n</template>\n"
        },
        {
          "path": "registry/default/vue/pagination/pagination-link.vue",
          "target": "components/ui/pagination/pagination-link.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed, inject } from \"vue\";\nimport Button from \"../button/button.vue\";\nimport { cn } from '@timui/core';\nimport { PaginationContextKey } from \"./pagination-context\";\n\nconst props = defineProps<{\n  page: number;\n  class?: HTMLAttributes[\"class\"];\n}>();\n\nconst context = inject(PaginationContextKey, null);\nconst itemProps = computed(() =>\n  context?.api.value?.getItemProps?.({ type: \"page\", value: props.page }) ?? {}\n);\nconst isActive = computed(() => context?.api.value?.page === props.page);\n</script>\n\n<template>\n  <li>\n    <Button\n      v-bind=\"itemProps\"\n      :class=\"cn(\n        'h-9 w-9 p-0',\n        isActive ? 'pointer-events-none' : '',\n        props.class\n      )\"\n      :variant=\"isActive ? 'outline' : 'ghost'\"\n      size=\"icon\"\n    >\n      <slot />\n    </Button>\n  </li>\n</template>\n"
        },
        {
          "path": "registry/default/vue/pagination/pagination-next.vue",
          "target": "components/ui/pagination/pagination-next.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed, inject } from \"vue\";\nimport { ChevronRight } from \"lucide-vue-next\";\nimport { cn, paginationNextVariants } from '@timui/core';\nimport Button from \"../button/button.vue\";\nimport { PaginationContextKey } from \"./pagination-context\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\nconst context = inject(PaginationContextKey, null);\nconst triggerProps = computed(() => context?.api.value?.getNextTriggerProps?.() ?? {});\n</script>\n\n<template>\n  <li>\n    <Button\n      v-bind=\"triggerProps\"\n      :class=\"cn(paginationNextVariants(), props.class)\"\n      variant=\"ghost\"\n      size=\"default\"\n    >\n      <slot>\n        <span>Next</span>\n        <ChevronRight class=\"h-4 w-4\" />\n      </slot>\n    </Button>\n  </li>\n</template>\n"
        },
        {
          "path": "registry/default/vue/pagination/pagination-previous.vue",
          "target": "components/ui/pagination/pagination-previous.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed, inject } from \"vue\";\nimport { ChevronLeft } from \"lucide-vue-next\";\nimport { cn, paginationPreviousVariants } from '@timui/core';\nimport Button from \"../button/button.vue\";\nimport { PaginationContextKey } from \"./pagination-context\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\nconst context = inject(PaginationContextKey, null);\nconst triggerProps = computed(() => context?.api.value?.getPrevTriggerProps?.() ?? {});\n</script>\n\n<template>\n  <li>\n    <Button\n      v-bind=\"triggerProps\"\n      :class=\"cn(paginationPreviousVariants(), props.class)\"\n      variant=\"ghost\"\n      size=\"default\"\n    >\n      <slot>\n        <ChevronLeft class=\"h-4 w-4\" />\n        <span>Previous</span>\n      </slot>\n    </Button>\n  </li>\n</template>\n"
        },
        {
          "path": "registry/default/vue/pagination/pagination.vue",
          "target": "components/ui/pagination/pagination.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, provide } from \"vue\";\nimport { cn, paginationRootVariants } from '@timui/core';\nimport { PaginationContextKey } from \"./pagination-context\";\nimport { usePagination } from './use-pagination';\n\nconst props = defineProps<{\n  id?: string;\n  page?: number;\n  defaultPage?: number;\n  pageSize?: number;\n  defaultPageSize?: number;\n  count?: number;\n  siblingCount?: number;\n  boundaryCount?: number;\n  onPageChange?: (details: { page: number; pageSize: number }) => void;\n  onPageSizeChange?: (details: { page: number; pageSize: number }) => void;\n  class?: HTMLAttributes[\"class\"];\n}>();\n\nconst emit = defineEmits<{\n  (e: \"update:page\", value: number): void;\n  (e: \"update:pageSize\", value: number): void;\n  (e: \"change\", value: { page: number; pageSize: number }): void;\n}>();\n\nconst api = usePagination(props, emit);\nprovide(PaginationContextKey, { api });\n</script>\n\n<template>\n  <nav\n    role=\"navigation\"\n    aria-label=\"pagination\"\n    :class=\"cn(paginationRootVariants(), props.class)\"\n    v-bind=\"api?.getRootProps?.()\"\n  >\n    <slot />\n  </nav>\n</template>\n"
        },
        {
          "path": "registry/default/vue/pagination/use-pagination.ts",
          "target": "components/ui/pagination/use-pagination.ts",
          "type": "registry:component",
          "content": "import { paginationConnect, paginationMachine } from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/vue'\nimport { computed, useId } from 'vue'\n\nexport type UsePaginationProps = {\n  id?: string\n  page?: number\n  defaultPage?: number\n  pageSize?: number\n  defaultPageSize?: number\n  count?: number\n  siblingCount?: number\n  boundaryCount?: number\n  onPageChange?: (details: PaginationChangeDetails) => void\n  onPageSizeChange?: (details: PaginationChangeDetails) => void\n}\n\ntype PaginationChangeDetails = {\n  page: number\n  pageSize: number\n}\n\ntype UsePaginationEmit = {\n  (event: 'update:page', page: number): void\n  (event: 'change', details: PaginationChangeDetails): void\n  (event: 'update:pageSize', pageSize: number): void\n}\n\nexport function usePagination(props: UsePaginationProps, emit: UsePaginationEmit) {\n  const generatedId = useId()\n\n  const service = useMachine(\n    paginationMachine as never,\n    {\n      id: props.id ?? generatedId,\n      page: props.page,\n      defaultPage: props.defaultPage,\n      pageSize: props.pageSize,\n      defaultPageSize: props.defaultPageSize,\n      count: props.count,\n      siblingCount: props.siblingCount,\n      boundaryCount: props.boundaryCount,\n      onPageChange(details: PaginationChangeDetails) {\n        props.onPageChange?.(details)\n        emit('update:page', details.page)\n        emit('change', { page: details.page, pageSize: details.pageSize })\n      },\n      onPageSizeChange(details: PaginationChangeDetails) {\n        props.onPageSizeChange?.(details)\n        emit('update:pageSize', details.pageSize)\n      },\n    } as never\n  )\n\n  return computed(() => paginationConnect(service as never, normalizeProps))\n}\n"
        },
        {
          "path": "registry/default/html/pagination.html",
          "target": "components/ui/pagination.html",
          "type": "registry:component",
          "content": "<nav role=\"navigation\" aria-label=\"pagination\" data-slot=\"pagination\" class=\"mx-auto flex w-full justify-center\">\n  <ul data-slot=\"pagination-content\" class=\"flex flex-row items-center gap-1\">\n    <li data-slot=\"pagination-item\">\n      <a data-slot=\"pagination-link\" href=\"#\" class=\"inline-flex items-center\">\n        <span>Previous</span>\n      </a>\n    </li>\n    <li data-slot=\"pagination-item\">\n      <a data-slot=\"pagination-link\" href=\"#\" class=\"inline-flex items-center\">1</a>\n    </li>\n    <li data-slot=\"pagination-item\">\n      <span data-slot=\"pagination-ellipsis\" class=\"flex size-9 items-center justify-center\">…</span>\n    </li>\n    <li data-slot=\"pagination-item\">\n      <a data-slot=\"pagination-link\" href=\"#\" class=\"inline-flex items-center\">\n        <span>Next</span>\n      </a>\n    </li>\n  </ul>\n</nav>"
        },
        {
          "path": "registry/default/weapp/pagination.wxml",
          "target": "components/ui/pagination.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}} pagination\">\n  <!-- Previous Button -->\n  <view \n    class=\"pagination-btn pagination-prev\"\n    bindtap=\"onPrevTap\"\n    data-disabled=\"{{!api.previousPage}}\"\n  >\n    <text>上一页</text>\n  </view>\n\n  <!-- Page Numbers -->\n  <view class=\"pagination-pages\">\n    <block wx:for=\"{{api.pages}}\" wx:key=\"index\">\n      <view \n        wx:if=\"{{item.type === 'page'}}\"\n        class=\"pagination-page\"\n        data-page=\"{{item.value}}\"\n        data-current=\"{{item.value === api.page}}\"\n        bindtap=\"onPageTap\"\n      >\n        {{item.value}}\n      </view>\n      <text \n        wx:elif=\"{{item.type === 'ellipsis'}}\"\n        class=\"pagination-ellipsis\"\n      >\n        ...\n      </text>\n    </block>\n  </view>\n\n  <!-- Next Button -->\n  <view \n    class=\"pagination-btn pagination-next\"\n    bindtap=\"onNextTap\"\n    data-disabled=\"{{!api.nextPage}}\"\n  >\n    <text>下一页</text>\n  </view>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/pagination.wxss",
          "target": "components/ui/pagination.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/pagination.ts",
          "target": "components/ui/pagination.ts",
          "type": "registry:component",
          "content": "// @ts-nocheck\nimport { emitTimEvent } from '../utils'\nimport {\n  connectPaginationMachine,\n  setupPaginationMachine,\n  type WeappPaginationApi,\n  type WeappPaginationService,\n} from './use-pagination'\n\ntype MachineEvent =\n  | string\n  | {\n      type: string\n      [key: string]: string | number | boolean | string[] | number[] | null | undefined\n    }\n\ntype PageTapEvent = WechatMiniprogram.BaseEvent & {\n  currentTarget: {\n    dataset: {\n      page?: number\n    }\n  }\n}\n\ntype WeappPaginationInternal = WechatMiniprogram.Component.InstanceMethods<{}> & {\n  _service?: WeappPaginationService\n  _cleanup?: () => void\n  _send?: (event: MachineEvent) => void\n  data: {\n    api: WeappPaginationApi\n  }\n  properties: {\n    page: number\n    pageSize: number\n    total: number\n    siblingCount: number\n    id: string\n    extClass: string\n  }\n}\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    page: { type: Number, value: 1 },\n    pageSize: { type: Number, value: 10 },\n    total: { type: Number, value: 0 },\n    siblingCount: { type: Number, value: 1 },\n    id: { type: String, value: 'pagination' },\n    extClass: { type: String, value: '' },\n  },\n\n  data: {\n    api: {} as WeappPaginationApi,\n    className: '',\n  },\n\n  lifetimes: {\n    attached() {\n      const self = this as WeappPaginationInternal\n      const controller = setupPaginationMachine(this, {\n        id: this.properties.id,\n        page: this.properties.page,\n        pageSize: this.properties.pageSize,\n        count: this.properties.total,\n        siblingCount: this.properties.siblingCount,\n        onPageChange: (details) => {\n          emitTimEvent(this, 'change', 'change', this.properties.id || 'pagination', {\n            page: details.page,\n            pageSize: details.pageSize,\n          })\n        },\n      })\n\n      self._service = controller.service as WeappPaginationService\n      self._cleanup = controller.start()\n      self._send = controller.send as (event: MachineEvent) => void\n    },\n    detached() {\n      const self = this as WeappPaginationInternal\n      self._cleanup?.()\n    },\n  },\n\n  observers: {\n    state: function (state) {\n      const self = this as WeappPaginationInternal\n      if (!state || !self._send) return\n      const api = connectPaginationMachine(state, self._send) as WeappPaginationApi\n      this.setData({ api, className: this.properties.extClass })\n    },\n  },\n\n  methods: {\n    onPrevTap() {\n      const self = this as WeappPaginationInternal\n      self.data.api.goToPrevPage?.()\n    },\n    onNextTap() {\n      const self = this as WeappPaginationInternal\n      self.data.api.goToNextPage?.()\n    },\n    onPageTap(e: PageTapEvent) {\n      const self = this as WeappPaginationInternal\n      const page = e.currentTarget.dataset.page\n      if (typeof page === 'number') {\n        self.data.api.goToPage?.(page)\n      }\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/pagination.json",
          "target": "components/ui/pagination.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        },
        {
          "path": "registry/default/weapp/pagination-content/pagination-content.wxml",
          "target": "components/ui/pagination-content/pagination-content.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\" data-slot=\"pagination-content\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/pagination-content/pagination-content.wxss",
          "target": "components/ui/pagination-content/pagination-content.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/pagination-content/pagination-content.json",
          "target": "components/ui/pagination-content/pagination-content.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/pagination-content/pagination-content.ts",
          "target": "components/ui/pagination-content/pagination-content.ts",
          "type": "registry:component",
          "content": "Component({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n  data: {\n    className: '',\n  },\n  lifetimes: {\n    attached() {\n      this.setData({\n        className: `flex flex-row items-center gap-1 ${this.properties.extClass}`.trim(),\n      })\n    },\n  },\n  observers: {\n    extClass(extClass) {\n      this.setData({\n        className: `flex flex-row items-center gap-1 ${extClass}`.trim(),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/pagination-ellipsis/pagination-ellipsis.wxml",
          "target": "components/ui/pagination-ellipsis/pagination-ellipsis.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\" data-slot=\"pagination-ellipsis\" aria-hidden=\"true\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/pagination-ellipsis/pagination-ellipsis.wxss",
          "target": "components/ui/pagination-ellipsis/pagination-ellipsis.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/pagination-ellipsis/pagination-ellipsis.json",
          "target": "components/ui/pagination-ellipsis/pagination-ellipsis.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/pagination-ellipsis/pagination-ellipsis.ts",
          "target": "components/ui/pagination-ellipsis/pagination-ellipsis.ts",
          "type": "registry:component",
          "content": "Component({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n  data: {\n    className: '',\n  },\n  lifetimes: {\n    attached() {\n      this.setData({\n        className: `flex size-9 items-center justify-center ${this.properties.extClass}`.trim(),\n      })\n    },\n  },\n  observers: {\n    extClass(extClass) {\n      this.setData({\n        className: `flex size-9 items-center justify-center ${extClass}`.trim(),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/pagination-item/pagination-item.wxml",
          "target": "components/ui/pagination-item/pagination-item.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\" data-slot=\"pagination-item\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/pagination-item/pagination-item.wxss",
          "target": "components/ui/pagination-item/pagination-item.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/pagination-item/pagination-item.json",
          "target": "components/ui/pagination-item/pagination-item.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/pagination-item/pagination-item.ts",
          "target": "components/ui/pagination-item/pagination-item.ts",
          "type": "registry:component",
          "content": "Component({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n  data: {\n    className: '',\n  },\n  lifetimes: {\n    attached() {\n      this.setData({\n        className: this.properties.extClass || '',\n      })\n    },\n  },\n  observers: {\n    extClass(extClass) {\n      this.setData({\n        className: extClass || '',\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/pagination-link/pagination-link.wxml",
          "target": "components/ui/pagination-link/pagination-link.wxml",
          "type": "registry:component",
          "content": "<button class=\"{{className}}\" data-slot=\"pagination-link\" aria-current=\"{{active ? 'page' : ''}}\">\n  <slot></slot>\n</button>\n"
        },
        {
          "path": "registry/default/weapp/pagination-link/pagination-link.wxss",
          "target": "components/ui/pagination-link/pagination-link.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/pagination-link/pagination-link.json",
          "target": "components/ui/pagination-link/pagination-link.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/pagination-link/pagination-link.ts",
          "target": "components/ui/pagination-link/pagination-link.ts",
          "type": "registry:component",
          "content": "Component({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: {\n      type: String,\n      value: '',\n    },\n    active: {\n      type: Boolean,\n      value: false,\n    },\n  },\n  data: {\n    className: '',\n  },\n  lifetimes: {\n    attached() {\n      this.setData({\n        className:\n          `inline-flex items-center justify-center rounded-md px-2.5 py-3 text-sm ${this.properties.extClass}`.trim(),\n      })\n    },\n  },\n  observers: {\n    extClass(extClass) {\n      this.setData({\n        className:\n          `inline-flex items-center justify-center rounded-md px-2.5 py-3 text-sm ${extClass}`.trim(),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/pagination-next/pagination-next.wxml",
          "target": "components/ui/pagination-next/pagination-next.wxml",
          "type": "registry:component",
          "content": "<button class=\"{{className}}\" data-slot=\"pagination-next\" aria-label=\"Go to next page\">\n  <slot></slot>\n</button>\n"
        },
        {
          "path": "registry/default/weapp/pagination-next/pagination-next.wxss",
          "target": "components/ui/pagination-next/pagination-next.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/pagination-next/pagination-next.json",
          "target": "components/ui/pagination-next/pagination-next.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/pagination-next/pagination-next.ts",
          "target": "components/ui/pagination-next/pagination-next.ts",
          "type": "registry:component",
          "content": "Component({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n  data: {\n    className: '',\n  },\n  lifetimes: {\n    attached() {\n      this.setData({\n        className:\n          `inline-flex items-center gap-1 rounded-md px-2.5 py-3 text-sm ${this.properties.extClass}`.trim(),\n      })\n    },\n  },\n  observers: {\n    extClass(extClass) {\n      this.setData({\n        className:\n          `inline-flex items-center gap-1 rounded-md px-2.5 py-3 text-sm ${extClass}`.trim(),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/pagination-previous/pagination-previous.wxml",
          "target": "components/ui/pagination-previous/pagination-previous.wxml",
          "type": "registry:component",
          "content": "<button class=\"{{className}}\" data-slot=\"pagination-previous\" aria-label=\"Go to previous page\">\n  <slot></slot>\n</button>\n"
        },
        {
          "path": "registry/default/weapp/pagination-previous/pagination-previous.wxss",
          "target": "components/ui/pagination-previous/pagination-previous.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/pagination-previous/pagination-previous.json",
          "target": "components/ui/pagination-previous/pagination-previous.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/pagination-previous/pagination-previous.ts",
          "target": "components/ui/pagination-previous/pagination-previous.ts",
          "type": "registry:component",
          "content": "Component({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n  data: {\n    className: '',\n  },\n  lifetimes: {\n    attached() {\n      this.setData({\n        className:\n          `inline-flex items-center gap-1 rounded-md px-2.5 py-3 text-sm ${this.properties.extClass}`.trim(),\n      })\n    },\n  },\n  observers: {\n    extClass(extClass) {\n      this.setData({\n        className:\n          `inline-flex items-center gap-1 rounded-md px-2.5 py-3 text-sm ${extClass}`.trim(),\n      })\n    },\n  },\n})\n"
        }
      ],
      "dependencies": [
        "@timui/core"
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@zag-js/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "popover",
      "type": "registry:ui",
      "dependencies": [
        "@timui/core",
        "@zag-js/popper",
        "@zag-js/react"
      ],
      "registryDependencies": [
        "use-machine"
      ],
      "files": [
        {
          "path": "registry/default/ui/popover.tsx",
          "type": "registry:ui",
          "target": "components/ui/popover.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport { cn, popoverContentVariants } from '@timui/core'\nimport type { Placement } from '@zag-js/popper'\nimport { mergeProps } from '@zag-js/react'\nimport { createPortal } from 'react-dom'\n\nimport { usePopover, type UsePopoverProps } from './popover/use-popover'\nimport { PopoverProvider, usePopoverContext } from './popover/use-popover-context'\nimport { Slot } from './slot'\n\nconst Popover = ({ children, ...props }: UsePopoverProps & { children: React.ReactNode }) => {\n  const api = usePopover(props)\n  return <PopoverProvider value={api}>{children}</PopoverProvider>\n}\nPopover.displayName = 'Popover'\n\nconst PopoverTrigger = React.forwardRef<\n  HTMLButtonElement,\n  React.ButtonHTMLAttributes<HTMLButtonElement> & { asChild?: boolean }\n>(({ className, onClick, asChild = false, ...props }, ref) => {\n  const api = usePopoverContext()\n\n  const Comp = asChild ? Slot : 'button'\n  const triggerProps = api.getTriggerProps()\n  const mergedProps = mergeProps(triggerProps, props)\n\n  return (\n    <Comp\n      ref={ref}\n      data-slot=\"popover-trigger\"\n      type=\"button\"\n      className={cn(className)}\n      {...mergedProps}\n    />\n  )\n})\nPopoverTrigger.displayName = 'PopoverTrigger'\n\nconst PopoverContent = React.forwardRef<\n  HTMLDivElement,\n  React.HTMLAttributes<HTMLDivElement> & {\n    align?: 'center' | 'start' | 'end'\n    side?: 'top' | 'bottom' | 'left' | 'right'\n    sideOffset?: number\n    showArrow?: boolean\n  }\n>(\n  (\n    {\n      className,\n      align = 'center',\n      side = 'bottom',\n      sideOffset = 4,\n      showArrow = false,\n      style,\n      children,\n      ...props\n    },\n    ref\n  ) => {\n    const api = usePopoverContext()\n    const placement = (align === 'center' ? side : `${side}-${align}`) as Placement\n    React.useEffect(() => {\n      if (!api.open) return\n      api.reposition({ placement, gutter: sideOffset })\n    }, [api, placement, sideOffset])\n    if (!api.open) return null\n    if (typeof window === 'undefined') return null\n\n    const positionerProps = api.getPositionerProps()\n    const contentProps = api.getContentProps()\n    const mergedProps = mergeProps(contentProps, props) as React.HTMLAttributes<HTMLDivElement>\n\n    return createPortal(\n      <div {...positionerProps} style={{ ...positionerProps.style, zIndex: 50 }}>\n        <div\n          ref={ref}\n          data-slot=\"popover-content\"\n          data-state=\"open\"\n          data-align={align}\n          style={{ ...mergedProps.style, ...style }}\n          className={cn(popoverContentVariants(), showArrow ? 'relative' : undefined, className)}\n          {...mergedProps}\n        >\n          {children}\n          {showArrow ? (\n            <span\n              data-slot=\"popover-arrow\"\n              className=\"absolute -top-1 left-6 h-2 w-2 rotate-45 border border-border bg-popover\"\n            />\n          ) : null}\n        </div>\n      </div>,\n      document.body\n    )\n  }\n)\nPopoverContent.displayName = 'PopoverContent'\n\nexport { Popover, PopoverTrigger, PopoverContent }\n"
        },
        {
          "path": "registry/default/ui/popover/use-popover-context.tsx",
          "target": "components/ui/popover/use-popover-context.tsx",
          "type": "registry:ui",
          "content": "import * as React from 'react'\n\nimport type { usePopover } from './use-popover'\n\nexport type UsePopoverReturn = ReturnType<typeof usePopover>\n\nconst PopoverContext = React.createContext<UsePopoverReturn | null>(null)\n\nexport function PopoverProvider({\n  children,\n  value,\n}: {\n  children: React.ReactNode\n  value: UsePopoverReturn\n}) {\n  return <PopoverContext.Provider value={value}> {children} </PopoverContext.Provider>\n}\n\nexport function usePopoverContext() {\n  const context = React.useContext(PopoverContext)\n  if (!context) {\n    throw new Error('usePopoverContext must be used within a PopoverProvider')\n  }\n  return context\n}\n"
        },
        {
          "path": "registry/default/ui/popover/use-popover.ts",
          "target": "components/ui/popover/use-popover.ts",
          "type": "registry:ui",
          "content": "import * as React from 'react'\nimport { popoverConnect, popoverMachine } from '@timui/core'\nimport type { PositioningOptions } from '@zag-js/popper'\nimport { normalizeProps, useMachine } from '@zag-js/react'\n\nexport interface UsePopoverProps {\n  id?: string\n  open?: boolean\n  defaultOpen?: boolean\n  onOpenChange?: (open: boolean) => void\n  modal?: boolean\n  positioning?: PositioningOptions\n  closeOnInteractOutside?: boolean\n  closeOnEscape?: boolean\n}\n\nexport function usePopover(props: UsePopoverProps) {\n  const generatedId = React.useId()\n  const service = useMachine(popoverMachine, {\n    id: props.id ?? generatedId,\n    open: props.open,\n    defaultOpen: props.defaultOpen,\n    modal: props.modal,\n    positioning: props.positioning,\n    closeOnInteractOutside: props.closeOnInteractOutside,\n    closeOnEscape: props.closeOnEscape,\n    onOpenChange: (details) => props.onOpenChange?.(details.open),\n  })\n\n  const api = React.useMemo(() => popoverConnect(service, normalizeProps), [service])\n\n  return api\n}\n"
        },
        {
          "path": "registry/default/vue/popover/popover-anchor.vue",
          "target": "components/ui/popover/popover-anchor.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, type Component, type HTMLAttributes } from 'vue'\nimport { cn } from '@timui/core'\nimport { Primitive } from '../../primitive'\nimport { usePopoverContext } from './use-popover-context'\n\nconst props = withDefaults(\n  defineProps<{\n    as?: string | Component\n    asChild?: boolean\n    class?: HTMLAttributes['class']\n  }>(),\n  {\n    as: 'div',\n  }\n)\n\nconst context = usePopoverContext()\nconst anchorProps = computed(() => ({\n  ...(context.value.getAnchorProps?.() ?? {}),\n  'data-slot': 'popover-anchor',\n}))\n</script>\n\n<template>\n  <Primitive\n    :as=\"props.as\"\n    :as-child=\"props.asChild\"\n    :class=\"cn(props.class)\"\n    v-bind=\"anchorProps\"\n  >\n    <slot />\n  </Primitive>\n</template>\n"
        },
        {
          "path": "registry/default/vue/popover/popover-content.vue",
          "target": "components/ui/popover/popover-content.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, watch } from \"vue\";\nimport { cn, popoverContentVariants } from \"@timui/core\";\nimport { usePopoverContext } from \"./use-popover-context\";\nimport Presence from \"../presence/presence.vue\";\nimport type { Placement } from \"@zag-js/popper\";\n\ndefineOptions({\n  inheritAttrs: false,\n});\n\nconst props = withDefaults(\n  defineProps<{\n    class?: string;\n    align?: \"center\" | \"start\" | \"end\";\n    side?: \"top\" | \"bottom\" | \"left\" | \"right\";\n    sideOffset?: number;\n    showArrow?: boolean;\n  }>(),\n  {\n    align: \"center\",\n    side: \"bottom\",\n    sideOffset: 4,\n    showArrow: false,\n  }\n);\n\nconst context = usePopoverContext();\nconst isOpen = computed(() => context.value.open ?? false);\nconst positionerProps = computed(() => context.value.getPositionerProps?.() ?? {});\nconst contentProps = computed(() => context.value.getContentProps?.() ?? {});\nconst placement = computed(() =>\n  props.align === \"center\" ? props.side : `${props.side}-${props.align}`,\n);\n\nwatch(\n  () => [placement.value, props.sideOffset],\n  () => {\n    context.value.reposition?.({ placement: placement.value as Placement, gutter: props.sideOffset });\n  },\n  { immediate: true }\n);\n</script>\n\n<template>\n  <Teleport to=\"body\">\n    <Presence :present=\"isOpen\" :unmountOnExit=\"true\" v-bind=\"positionerProps\" style=\"z-index: 50\">\n      <div\n        v-bind=\"contentProps\"\n        data-slot=\"popover-content\"\n        data-state=\"open\"\n        :data-align=\"props.align\"\n        :class=\"cn(popoverContentVariants(), props.showArrow && 'relative', props.class)\"\n      >\n        <slot />\n        <span\n          v-if=\"props.showArrow\"\n          data-slot=\"popover-arrow\"\n          class=\"absolute -top-1 left-6 h-2 w-2 rotate-45 border border-border bg-popover\"\n        />\n      </div>\n    </Presence>\n  </Teleport>\n</template>\n"
        },
        {
          "path": "registry/default/vue/popover/popover-trigger.vue",
          "target": "components/ui/popover/popover-trigger.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, type Component, type HTMLAttributes } from \"vue\";\nimport { cn } from \"@timui/core\";\nimport { Primitive } from '../../primitive';\nimport { usePopoverContext } from \"./use-popover-context\";\n\nconst props = withDefaults(\n  defineProps<{\n    as?: string | Component;\n    asChild?: boolean;\n    class?: HTMLAttributes[\"class\"];\n  }>(),\n  {\n    as: \"button\",\n  }\n);\n\nconst context = usePopoverContext();\nconst triggerProps = computed(() => ({\n  ...(context.value.getTriggerProps?.() ?? {}),\n  type: props.asChild ? undefined : \"button\",\n  \"data-slot\": \"popover-trigger\",\n}));\n</script>\n\n<template>\n  <Primitive\n    :as=\"props.as\"\n    :as-child=\"props.asChild\"\n    :class=\"cn(props.class)\"\n    v-bind=\"triggerProps\"\n  >\n    <slot />\n  </Primitive>\n</template>\n"
        },
        {
          "path": "registry/default/vue/popover/popover.vue",
          "target": "components/ui/popover/popover.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes } from \"vue\";\nimport type { PositioningOptions } from \"@zag-js/popper\";\nimport { usePopover } from \"./use-popover\";\nimport { PopoverProvider } from \"./use-popover-context\";\n\nconst props = defineProps<{\n  open?: boolean;\n  defaultOpen?: boolean;\n  modal?: boolean;\n  closeOnInteractOutside?: boolean;\n  closeOnEscape?: boolean;\n  positioning?: PositioningOptions;\n  onOpenChange?: (open: boolean) => void;\n  id?: string;\n  class?: HTMLAttributes[\"class\"];\n}>();\n\nconst emit = defineEmits([\"update:open\", \"change\"]);\n\nconst api = usePopover(props, emit);\nPopoverProvider(api);\n</script>\n\n<template>\n  <slot />\n</template>\n"
        },
        {
          "path": "registry/default/vue/popover/use-popover-context.ts",
          "target": "components/ui/popover/use-popover-context.ts",
          "type": "registry:component",
          "content": "import { createContext } from '../../hooks/create-context'\nimport type { usePopover } from './use-popover'\n\nexport type UsePopoverReturn = ReturnType<typeof usePopover>\n\nexport const [PopoverProvider, usePopoverContext] = createContext<UsePopoverReturn>({\n  id: 'popoverContext',\n  providerName: '<Popover />',\n})\n"
        },
        {
          "path": "registry/default/vue/popover/use-popover.ts",
          "target": "components/ui/popover/use-popover.ts",
          "type": "registry:component",
          "content": "import { popoverConnect, popoverMachine } from '@timui/core'\nimport type { PositioningOptions } from '@zag-js/popper'\nimport { normalizeProps, useMachine } from '@zag-js/vue'\nimport { computed, useId, watch } from 'vue'\n\nexport interface UsePopoverProps {\n  id?: string\n  open?: boolean\n  defaultOpen?: boolean\n  modal?: boolean\n  closeOnInteractOutside?: boolean\n  closeOnEscape?: boolean\n  positioning?: PositioningOptions\n  onOpenChange?: (open: boolean) => void\n}\n\nexport interface UsePopoverEmits {\n  (e: 'update:open', value: boolean): void\n  (e: 'change', value: boolean): void\n}\n\nexport function usePopover(props: UsePopoverProps, emit: UsePopoverEmits) {\n  const generatedId = useId()\n\n  const machineProps = computed(() => ({\n    id: props.id ?? generatedId,\n    open: props.open,\n    defaultOpen: props.open === undefined ? props.defaultOpen : undefined,\n    modal: props.modal,\n    closeOnInteractOutside: props.closeOnInteractOutside,\n    closeOnEscape: props.closeOnEscape,\n    positioning: props.positioning,\n    onOpenChange(details: { open: boolean }) {\n      props.onOpenChange?.(details.open)\n      emit('update:open', details.open)\n      emit('change', details.open)\n    },\n  }))\n\n  const service = useMachine(popoverMachine, machineProps)\n  const api = computed(() => popoverConnect(service, normalizeProps))\n\n  watch(\n    () => props.open,\n    (val?: boolean) => {\n      if (val !== undefined && val !== api.value.open) {\n        api.value.setOpen(val)\n      }\n    }\n  )\n\n  return api\n}\n"
        },
        {
          "path": "registry/default/html/popover.html",
          "target": "components/ui/popover.html",
          "type": "registry:component",
          "content": "<div data-timui-root data-timui-init=\"auto\">\n  <div data-slot=\"popover\" class=\"relative\">\n    <button data-slot=\"popover-trigger\" aria-expanded=\"false\" class=\"inline-flex items-center\">\n      Open popover\n    </button>\n    <div\n      data-slot=\"popover-content\"\n      data-state=\"closed\"\n      hidden\n      class=\"absolute z-50 mt-2 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md\"\n    >\n      Popover content\n    </div>\n  </div>\n</div>\n<script type=\"module\">\n  import { autoInitHtmlRuntime } from '@timui/html'\n  autoInitHtmlRuntime({ components: ['popover'] })\n</script>"
        },
        {
          "path": "registry/default/weapp/popover.wxml",
          "target": "components/ui/popover.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\">\n  <!-- Trigger -->\n  <view \n    id=\"{{api.triggerProps.id}}\"\n    bindtap=\"onTriggerTap\"\n    data-state=\"{{api.open ? 'open' : 'closed'}}\"\n  >\n    <slot name=\"trigger\"></slot>\n  </view>\n\n  <!-- Backdrop (if modal) -->\n  <view \n    wx:if=\"{{api.open && modal}}\"\n    class=\"popover-backdrop\"\n    bindtap=\"onBackdropTap\"\n  ></view>\n\n  <!-- Content -->\n  <view \n    wx:if=\"{{api.open}}\"\n    id=\"{{api.contentProps.id}}\"\n    class=\"popover-content\"\n    data-state=\"{{api.open ? 'open' : 'closed'}}\"\n  >\n    <view class=\"popover-arrow\" wx:if=\"{{showArrow}}\"></view>\n    \n    <view class=\"popover-header\" wx:if=\"{{title}}\">\n      <text class=\"popover-title\">{{title}}</text>\n      <view \n        class=\"popover-close\" \n        bindtap=\"onCloseTap\"\n      >×</view>\n    </view>\n\n    <view class=\"popover-body\">\n      <slot name=\"content\"></slot>\n    </view>\n  </view>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/popover.wxss",
          "target": "components/ui/popover.wxss",
          "type": "registry:component",
          "content": "/* weapp component styles */\n"
        },
        {
          "path": "registry/default/weapp/popover.ts",
          "target": "components/ui/popover.ts",
          "type": "registry:component",
          "content": "import { setupPopoverMachine } from './use-popover'\n\ntype WeappPopoverApi = {\n  triggerProps?: { onClick?: () => void }\n  open?: () => void\n  close?: () => void\n}\n\ntype WeappService = {\n  setContext: (context: Record<string, object>) => void\n}\ntype MachineEvent = string | { type: string; [key: string]: object }\ntype MachineSend = (event: MachineEvent) => void\n\ntype WeappPopoverInternal = WechatMiniprogram.Component.InstanceMethods<WeappPopoverApi> & {\n  _service?: WeappService\n  _cleanup?: () => void\n  _send?: (event: object) => void\n  _connect?: (state: object, send: MachineSend) => WeappPopoverApi\n  data: {\n    api: WeappPopoverApi\n  }\n  properties: {\n    open: boolean\n    modal: boolean\n    portalled: boolean\n    closeOnInteractOutside: boolean\n    id: string\n    extClass: string\n  }\n}\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    open: { type: Boolean, value: false },\n    modal: { type: Boolean, value: false },\n    portalled: { type: Boolean, value: true },\n    closeOnInteractOutside: { type: Boolean, value: true },\n    id: { type: String, value: 'popover' },\n    extClass: { type: String, value: '' },\n  },\n\n  data: {\n    api: {} as WeappPopoverApi,\n    className: '',\n  },\n\n  lifetimes: {\n    attached() {\n      const self = this as WeappPopoverInternal\n      const { controller, connect } = setupPopoverMachine(self)\n\n      self._service = controller.service as WeappService\n      self._cleanup = controller.start()\n      self._send = controller.send as MachineSend\n      self._connect = connect\n    },\n    detached() {\n      const self = this as WeappPopoverInternal\n      self._cleanup?.()\n    },\n  },\n\n  observers: {\n    state: function (state) {\n      const self = this as WeappPopoverInternal\n      if (!state || !self._send || !self._connect) return\n      const api = self._connect(state, self._send) as WeappPopoverApi\n      this.setData({ api, className: this.properties.extClass })\n    },\n\n    open: function (val) {\n      const self = this as WeappPopoverInternal\n      if (self._service) {\n        if (val) {\n          self.data.api.open?.()\n        } else {\n          self.data.api.close?.()\n        }\n      }\n    },\n  },\n\n  methods: {\n    onTriggerTap() {\n      const self = this as WeappPopoverInternal\n      self.data.api.triggerProps?.onClick?.()\n    },\n    onBackdropTap() {\n      const self = this as WeappPopoverInternal\n      self.data.api.close?.()\n    },\n    onCloseTap() {\n      const self = this as WeappPopoverInternal\n      self.data.api.close?.()\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/popover.json",
          "target": "components/ui/popover.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        },
        {
          "path": "registry/default/weapp/popover-content/popover-content.wxml",
          "target": "components/ui/popover-content/popover-content.wxml",
          "type": "registry:component",
          "content": "<root-portal wx:if=\"{{visible}}\">\n  <!-- Transparent overlay for clicking outside (simplified) -->\n  <view class=\"fixed inset-0 z-40\" bindtap=\"hide\" catchtouchmove=\"noop\"></view>\n  \n  <view id=\"popover-content\" class=\"fixed z-50 {{baseClass}}\" style=\"{{style}}\" catchtap=\"noop\">\n    <slot></slot>\n  </view>\n</root-portal>\n"
        },
        {
          "path": "registry/default/weapp/popover-content/popover-content.wxss",
          "target": "components/ui/popover-content/popover-content.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/popover-content/popover-content.json",
          "target": "components/ui/popover-content/popover-content.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/popover-content/popover-content.ts",
          "target": "components/ui/popover-content/popover-content.ts",
          "type": "registry:component",
          "content": "import { popoverContentVariants } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  relations: {\n    '../popover/popover': {\n      type: 'parent',\n    },\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: { type: String, value: '' },\n  },\n  data: {\n    visible: false,\n    style: 'opacity: 0;', // Initial hidden\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass: string) {\n      this.setData({\n        // Simulating data-state for variants if needed?\n        // Shared variant uses `data-[state=open]:animate-in`.\n        // WeApp won't trigger that animation naturally without state change.\n        // For now, allow base classes.\n        className: popoverContentVariants({ className: extClass }),\n      })\n    },\n  },\n  methods: {\n    showForMeasure() {\n      this.setData({\n        visible: true,\n        style: 'opacity: 0; pointer-events: none;',\n      })\n    },\n    updatePosition(top: number, left: number) {\n      this.setData({\n        style: `top: ${top}px; left: ${left}px; opacity: 1; transition: opacity 0.2s;`,\n      })\n    },\n    hide() {\n      this.setData({ visible: false, style: 'opacity: 0;' })\n    },\n    getRect() {\n      return new Promise((resolve) => {\n        this.createSelectorQuery()\n          .select('#popover-content')\n          .boundingClientRect((rect) => {\n            resolve(rect)\n          })\n          .exec()\n      })\n    },\n    noop() {},\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/popover-trigger/popover-trigger.wxml",
          "target": "components/ui/popover-trigger/popover-trigger.wxml",
          "type": "registry:component",
          "content": "<view id=\"popover-trigger\" class=\"inline-block\" bindtap=\"onTap\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/popover-trigger/popover-trigger.wxss",
          "target": "components/ui/popover-trigger/popover-trigger.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/popover-trigger/popover-trigger.json",
          "target": "components/ui/popover-trigger/popover-trigger.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/popover-trigger/popover-trigger.ts",
          "target": "components/ui/popover-trigger/popover-trigger.ts",
          "type": "registry:component",
          "content": "Component({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: { type: String, value: '' },\n  },\n  relations: {\n    '../popover/popover': {\n      type: 'parent',\n    },\n  },\n  methods: {\n    onTap() {\n      const parents = this.getRelationNodes('../popover/popover')\n      if (parents.length) {\n        parents[0].toggle()\n      }\n    },\n    getRect() {\n      return new Promise((resolve) => {\n        this.createSelectorQuery()\n          .select('#popover-trigger')\n          .boundingClientRect((rect) => {\n            resolve(rect)\n          })\n          .exec()\n      })\n    },\n  },\n})\n"
        }
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@zag-js/popper",
              "@zag-js/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@zag-js/popper",
              "@zag-js/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "progress",
      "type": "registry:ui",
      "dependencies": [
        "@timui/core",
        "@zag-js/react"
      ],
      "registryDependencies": [
        "use-machine"
      ],
      "files": [
        {
          "path": "registry/default/ui/progress.tsx",
          "type": "registry:ui",
          "target": "components/ui/progress.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport { cn, progressIndicatorVariants, progressRootVariants } from '@timui/core'\n\nimport { useProgress } from './progress/use-progress'\n\nconst Progress = React.forwardRef<\n  HTMLDivElement,\n  React.HTMLAttributes<HTMLDivElement> & { value?: number | null; max?: number }\n>(({ className, value, max = 100, ...props }, ref) => {\n  const { progressValue, percent } = useProgress({ value, max })\n\n  return (\n    <div\n      ref={ref}\n      role=\"progressbar\"\n      aria-valuemax={max}\n      aria-valuemin={0}\n      aria-valuenow={value ?? undefined}\n      data-max={max}\n      data-value={value}\n      data-state={progressValue === null ? 'indeterminate' : 'loading'}\n      className={cn(progressRootVariants(), className)}\n      {...props}\n    >\n      <div\n        data-slot=\"progress-indicator\"\n        className={progressIndicatorVariants()}\n        style={{ transform: `translateX(-${100 - percent}%)` }}\n      />\n    </div>\n  )\n})\nProgress.displayName = 'Progress'\n\nexport { Progress }\n"
        },
        {
          "path": "registry/default/ui/progress/use-progress.ts",
          "target": "components/ui/progress/use-progress.ts",
          "type": "registry:ui",
          "content": "import * as React from 'react'\nimport { progressConnect, progressMachine } from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/react'\n\nexport type UseProgressProps = {\n  value?: number | null\n  max?: number\n}\n\nexport function useProgress(props: UseProgressProps) {\n  const { value, max = 100 } = props\n  const generatedId = React.useId()\n\n  const service = useMachine(progressMachine, {\n    id: generatedId,\n    value: value ?? null,\n    max,\n  })\n\n  const api = React.useMemo(() => progressConnect(service, normalizeProps), [service])\n\n  // Sync controlled value changes into the machine\n  React.useEffect(() => {\n    if (value !== undefined) {\n      api.setValue(value)\n    }\n  }, [value, api])\n\n  return {\n    progressValue: api.value,\n    percent: api.percent ?? 0,\n  }\n}\n"
        },
        {
          "path": "registry/default/vue/progress/progress.vue",
          "target": "components/ui/progress/progress.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, type HTMLAttributes } from 'vue'\nimport { progressIndicatorVariants, progressRootVariants } from '@timui/core'\nimport { cn } from '@timui/core'\nimport { useProgress } from './use-progress'\n\nconst props = defineProps<{\n  modelValue?: number | null\n  max?: number\n  class?: HTMLAttributes['class']\n}>()\n\nconst api = useProgress(props)\n\nconst percent = computed(() => {\n  return api.value.percent\n})\n</script>\n\n<template>\n  <div\n    role=\"progressbar\"\n    data-slot=\"progress\"\n    :aria-valuemax=\"props.max ?? 100\"\n    aria-valuemin=\"0\"\n    :aria-valuenow=\"props.modelValue ?? undefined\"\n    :data-max=\"props.max ?? 100\"\n    :data-value=\"props.modelValue ?? undefined\"\n    :data-state=\"props.modelValue == null ? 'indeterminate' : 'loading'\"\n    :class=\"cn(progressRootVariants(), props.class)\"\n  >\n    <div\n      data-slot=\"progress-indicator\"\n      :class=\"progressIndicatorVariants()\"\n      :style=\"`transform: translateX(-${100 - percent}%);`\"\n    />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/progress/use-progress.ts",
          "target": "components/ui/progress/use-progress.ts",
          "type": "registry:component",
          "content": "import { progressConnect, progressMachine } from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/vue'\nimport { computed, watch } from 'vue'\n\nexport type UseProgressProps = {\n  modelValue?: number | null\n  max?: number\n}\n\nexport function useProgress(props: UseProgressProps) {\n  const machineProps = computed(() => ({\n    value: props.modelValue ?? null,\n    max: props.max ?? 100,\n  }))\n\n  const service = useMachine(progressMachine, machineProps)\n  const api = computed(() => progressConnect(service, normalizeProps))\n\n  watch(\n    () => props.modelValue,\n    (val) => {\n      if (val !== undefined && val !== api.value.value) {\n        api.value.setValue(val)\n      }\n    }\n  )\n\n  return api\n}\n"
        },
        {
          "path": "registry/default/html/progress.html",
          "target": "components/ui/progress.html",
          "type": "registry:component",
          "content": "<div role=\"progressbar\" data-slot=\"progress\" class=\"relative h-2 w-full overflow-hidden rounded-full bg-secondary\">\n    <div data-slot=\"progress-indicator\" class=\"h-full w-full flex-1 bg-primary transition-all\"\n        style=\"transform: translateX(-100%)\"></div>\n</div>"
        },
        {
          "path": "registry/default/weapp/progress.wxml",
          "target": "components/ui/progress.wxml",
          "type": "registry:component",
          "content": "<view \n  id=\"{{api.rootProps.id}}\"\n  class=\"{{rootClass}}\" \n  role=\"progressbar\" \n  aria-valuemin=\"{{api.min}}\"\n  aria-valuenow=\"{{api.value}}\" \n  aria-valuemax=\"{{api.max}}\"\n  data-state=\"{{api.state}}\"\n>\n  <view \n    class=\"{{indicatorClass}}\" \n    style=\"transform: translateX(-{{100 - api.percent}}%)\"\n  ></view>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/progress.wxss",
          "target": "components/ui/progress.wxss",
          "type": "registry:component",
          "content": "/* Progress specific styles */\n"
        },
        {
          "path": "registry/default/weapp/progress.ts",
          "target": "components/ui/progress.ts",
          "type": "registry:component",
          "content": "// @ts-nocheck\nimport { progressIndicatorVariants, progressRootVariants, resolveClasses } from '../utils'\nimport {\n  connectProgressMachine,\n  setupProgressMachine,\n  type WeappProgressApi,\n  type WeappProgressService,\n} from './use-progress'\n\ntype WeappProgressInternal = WechatMiniprogram.Component.InstanceMethods<{}> & {\n  _service?: WeappProgressService\n  _cleanup?: () => void\n  _send?: (event: object) => void\n  data: {\n    api: WeappProgressApi\n  }\n  properties: {\n    value: number\n    max: number\n    min: number\n    id: string\n    extClass: string\n  }\n}\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    value: {\n      type: Number,\n      value: 0,\n    },\n    max: {\n      type: Number,\n      value: 100,\n    },\n    min: {\n      type: Number,\n      value: 0,\n    },\n    id: {\n      type: String,\n      value: 'progress',\n    },\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n\n  data: {\n    api: {} as WeappProgressApi,\n    rootClass: '',\n    indicatorClass: '',\n  },\n\n  lifetimes: {\n    attached() {\n      const self = this as WeappProgressInternal\n      const controller = setupProgressMachine(this, {\n        id: this.properties.id,\n        value: this.properties.value,\n        max: this.properties.max,\n        min: this.properties.min,\n      })\n\n      self._service = controller.service as WeappProgressService\n      self._cleanup = controller.start()\n      self._send = controller.send as (event: object) => void\n    },\n    detached() {\n      const self = this as WeappProgressInternal\n      self._cleanup?.()\n    },\n  },\n\n  observers: {\n    state: function (state) {\n      const self = this as WeappProgressInternal\n      if (!state || !self._send) return\n      const api = connectProgressMachine(state, self._send) as WeappProgressApi\n\n      const { baseClass: rootClass } = resolveClasses(\n        progressRootVariants(),\n        self.properties.extClass\n      )\n      const { baseClass: indicatorClass } = resolveClasses(progressIndicatorVariants())\n\n      this.setData({ api, rootClass, indicatorClass })\n    },\n\n    value: function (val) {\n      const self = this as WeappProgressInternal\n      if (self._service) {\n        self._service.setContext({ value: val })\n      }\n    },\n\n    max: function (val) {\n      const self = this as WeappProgressInternal\n      if (self._service) {\n        self._service.setContext({ max: val })\n      }\n    },\n\n    min: function (val) {\n      const self = this as WeappProgressInternal\n      if (self._service) {\n        self._service.setContext({ min: val })\n      }\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/progress.json",
          "target": "components/ui/progress.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        }
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@zag-js/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@zag-js/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "radio-group",
      "type": "registry:ui",
      "dependencies": [
        "@timui/core",
        "@zag-js/react"
      ],
      "registryDependencies": [
        "use-machine"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/ui/radio-group.tsx",
          "type": "registry:ui",
          "target": "components/ui/radio-group.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport type {\n  AssertNoExtraKeys,\n  RadioGroupItemProps as CoreRadioGroupItemProps,\n  RadioGroupProps as CoreRadioGroupProps,\n} from '@timui/core'\nimport {\n  cn,\n  createTimEvent,\n  radioGroupConnect,\n  radioGroupIndicatorIconVariants,\n  radioGroupIndicatorVariants,\n  radioGroupItemVariants,\n  radioGroupMachine,\n  radioGroupVariants,\n} from '@timui/core'\nimport { mergeProps } from '@zag-js/react'\nimport { CircleIcon } from 'lucide-react'\n\nimport { useRadioGroup } from './radio-group/use-radio-group'\nimport { RadioGroupProvider, useRadioGroupContext } from './radio-group/use-radio-group-context'\n\ntype RadioGroupProps = CoreRadioGroupProps &\n  Omit<React.HTMLAttributes<HTMLDivElement>, keyof CoreRadioGroupProps>\ntype _RadioGroupPropsGuard = AssertNoExtraKeys<\n  RadioGroupProps,\n  CoreRadioGroupProps & React.HTMLAttributes<HTMLDivElement>\n>\n\nconst RadioGroup = React.forwardRef<HTMLDivElement, RadioGroupProps>(\n  (\n    { className, value, defaultValue, onValueChange, disabled, required, name, id, ...props },\n    ref\n  ) => {\n    const api = useRadioGroup({ value, defaultValue, onValueChange, disabled, required, name, id })\n    const rootProps = api.getRootProps()\n    const mergedRootProps = mergeProps(rootProps, props)\n    const { className: rootClassName, ...rootRest } = mergedRootProps\n\n    return (\n      <RadioGroupProvider value={api}>\n        <div\n          {...rootRest}\n          ref={ref}\n          data-slot=\"radio-group\"\n          className={cn(radioGroupVariants(), rootClassName, className)}\n        />\n      </RadioGroupProvider>\n    )\n  }\n)\nRadioGroup.displayName = 'RadioGroup'\n\ntype RadioGroupItemProps = CoreRadioGroupItemProps &\n  Omit<React.HTMLAttributes<HTMLDivElement>, keyof CoreRadioGroupItemProps>\ntype _RadioGroupItemPropsGuard = AssertNoExtraKeys<\n  RadioGroupItemProps,\n  CoreRadioGroupItemProps & React.HTMLAttributes<HTMLDivElement>\n>\n\nconst RadioGroupItem = React.forwardRef<HTMLDivElement, RadioGroupItemProps>(\n  ({ className, value, disabled: itemDisabled, ...props }, ref) => {\n    const api = useRadioGroupContext()\n    const itemProps = api.getItemProps({ value, disabled: itemDisabled })\n    const controlProps = api.getItemControlProps({ value, disabled: itemDisabled })\n    const hiddenInputProps = api.getItemHiddenInputProps({ value, disabled: itemDisabled })\n    const itemState = api.getItemState({ value, disabled: itemDisabled })\n    const mergedControlProps = mergeProps(controlProps, props)\n    const { className: controlClassName, ...controlRest } = mergedControlProps\n\n    return (\n      <label {...itemProps} data-slot=\"radio-group-item\">\n        <div\n          {...controlRest}\n          ref={ref}\n          data-slot=\"radio-control\"\n          className={cn(radioGroupItemVariants(), controlClassName, className)}\n        >\n          <span data-slot=\"radio-indicator\" className={radioGroupIndicatorVariants()}>\n            {itemState.checked && (\n              <CircleIcon className={radioGroupIndicatorIconVariants()} strokeWidth={0} />\n            )}\n          </span>\n        </div>\n        <input {...hiddenInputProps} />\n      </label>\n    )\n  }\n)\nRadioGroupItem.displayName = 'RadioGroupItem'\n\nexport { RadioGroup, RadioGroupItem }\n"
        },
        {
          "path": "registry/default/ui/radio-group/use-radio-group-context.tsx",
          "target": "components/ui/radio-group/use-radio-group-context.tsx",
          "type": "registry:ui",
          "content": "import * as React from 'react'\n\nimport type { useRadioGroup } from './use-radio-group'\n\nexport type UseRadioGroupReturn = ReturnType<typeof useRadioGroup>\n\nconst RadioGroupContext = React.createContext<UseRadioGroupReturn | null>(null)\n\nexport function RadioGroupProvider({\n  children,\n  value,\n}: {\n  children: React.ReactNode\n  value: UseRadioGroupReturn\n}) {\n  return <RadioGroupContext.Provider value={value}>{children}</RadioGroupContext.Provider>\n}\n\nexport function useRadioGroupContext() {\n  const context = React.useContext(RadioGroupContext)\n  if (!context) {\n    throw new Error('useRadioGroupContext must be used within a RadioGroupProvider')\n  }\n  return context\n}\n"
        },
        {
          "path": "registry/default/ui/radio-group/use-radio-group.ts",
          "target": "components/ui/radio-group/use-radio-group.ts",
          "type": "registry:ui",
          "content": "import * as React from 'react'\nimport type { RadioGroupProps as CoreRadioGroupProps } from '@timui/core'\nimport { createTimEvent, radioGroupConnect, radioGroupMachine } from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/react'\n\nexport interface UseRadioGroupProps extends Omit<CoreRadioGroupProps, 'id'> {\n  id?: string\n}\n\nexport function useRadioGroup(props: UseRadioGroupProps) {\n  const generatedId = React.useId()\n  const radioGroupId = props.id ?? generatedId\n\n  const service = useMachine(radioGroupMachine, {\n    id: radioGroupId,\n    value: props.value,\n    defaultValue: props.defaultValue,\n    disabled: props.disabled,\n    required: props.required,\n    name: props.name,\n    onValueChange(details) {\n      props.onValueChange?.(createTimEvent('change', radioGroupId, { value: details.value }))\n    },\n  })\n\n  const api = React.useMemo(() => radioGroupConnect(service, normalizeProps), [service])\n\n  return api\n}\n"
        },
        {
          "path": "registry/default/vue/radio-group/radio-group-item.vue",
          "target": "components/ui/radio-group/radio-group-item.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, inject, type ComputedRef } from \"vue\";\nimport {\n  cn,\n  radioGroupIndicatorIconVariants,\n  radioGroupIndicatorVariants,\n  radioGroupItemVariants,\n} from \"@timui/core\";\nimport type { RadioGroupApi } from \"@timui/core\";\nimport { Circle } from \"lucide-vue-next\";\nimport { useRadioGroupContext } from \"./use-radio-group-context\";\n\nconst props = defineProps<{ value: string; class?: string; disabled?: boolean }>();\nconst api = useRadioGroupContext();\n\nconst itemState = computed(() =>\n  api?.value?.getItemState?.({ value: props.value, disabled: props.disabled })\n);\nconst itemProps = computed(() =>\n  api?.value?.getItemProps?.({ value: props.value, disabled: props.disabled }) ?? {}\n);\nconst controlProps = computed(() =>\n  api?.value?.getItemControlProps?.({ value: props.value, disabled: props.disabled }) ?? {}\n);\nconst hiddenInputProps = computed(() =>\n  api?.value?.getItemHiddenInputProps?.({ value: props.value, disabled: props.disabled }) ?? {}\n);\n</script>\n\n<template>\n  <label v-bind=\"itemProps\" data-slot=\"radio-group-item\">\n    <div\n      v-bind=\"controlProps\"\n      data-slot=\"radio-control\"\n      :class=\"cn(radioGroupItemVariants(), controlProps.class, props.class)\"\n    >\n      <span data-slot=\"radio-indicator\" :class=\"radioGroupIndicatorVariants()\">\n        <Circle\n          v-if=\"itemState?.checked\"\n          :class=\"radioGroupIndicatorIconVariants()\"\n        />\n      </span>\n    </div>\n    <input v-bind=\"hiddenInputProps\" />\n  </label>\n</template>\n"
        },
        {
          "path": "registry/default/vue/radio-group/radio-group.vue",
          "target": "components/ui/radio-group/radio-group.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, provide, type ComputedRef } from \"vue\";\nimport type { AssertNoExtraKeys, RadioGroupVueProps } from \"@timui/core\";\nimport { radioGroupConnect, radioGroupMachine } from \"@timui/core\";\nimport { normalizeProps, useMachine } from \"@zag-js/vue\";\nimport { cn, radioGroupVariants } from \"@timui/core\";\nimport type { HTMLAttributes } from \"vue\";\nimport type { RadioGroupApi } from \"@timui/core\";\n\nimport { useRadioGroup } from \"./use-radio-group\";\nimport { provideRadioGroupContext } from \"./use-radio-group-context\";\n\ntype RadioGroupProps = RadioGroupVueProps & { class?: HTMLAttributes[\"class\"] };\ntype _RadioGroupPropsGuard = AssertNoExtraKeys<RadioGroupProps, RadioGroupProps>;\n\nconst props = defineProps<RadioGroupProps>();\n\nconst emit = defineEmits([\"update:modelValue\", \"change\"]);\n\nconst api = useRadioGroup(props, emit);\nprovideRadioGroupContext(api);\n</script>\n\n<template>\n  <div\n    v-bind=\"api.getRootProps()\"\n    data-slot=\"radio-group\"\n    :class=\"cn(radioGroupVariants(), props.class)\"\n  >\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/radio-group/use-radio-group-context.ts",
          "target": "components/ui/radio-group/use-radio-group-context.ts",
          "type": "registry:component",
          "content": "import { inject, provide } from 'vue'\n\nimport type { useRadioGroup } from './use-radio-group'\n\nexport type UseRadioGroupReturn = ReturnType<typeof useRadioGroup>\n\nexport const RadioGroupContextKey = Symbol('radioGroupContext')\n\nexport function provideRadioGroupContext(context: UseRadioGroupReturn) {\n  provide(RadioGroupContextKey, context)\n}\n\nexport function useRadioGroupContext() {\n  const context = inject<UseRadioGroupReturn>(RadioGroupContextKey)\n  if (!context) {\n    throw new Error('useRadioGroupContext must be used within a RadioGroup component')\n  }\n  return context\n}\n"
        },
        {
          "path": "registry/default/vue/radio-group/use-radio-group.ts",
          "target": "components/ui/radio-group/use-radio-group.ts",
          "type": "registry:component",
          "content": "import type { RadioGroupVueProps } from '@timui/core'\nimport { radioGroupConnect, radioGroupMachine } from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/vue'\nimport { computed, useId } from 'vue'\n\ntype RadioGroupEmits = {\n  (event: 'update:modelValue', value: string | null): void\n  (event: 'change', value: string | null): void\n}\n\nexport function useRadioGroup(props: RadioGroupVueProps, emit: RadioGroupEmits) {\n  const generatedId = useId()\n\n  const machineProps = computed(() => ({\n    id: props.id ?? generatedId,\n    value: props.modelValue ?? props.value,\n    defaultValue:\n      props.modelValue === undefined && props.value === undefined ? props.defaultValue : undefined,\n    disabled: props.disabled,\n    required: props.required,\n    name: props.name,\n    onValueChange(details: { value: string | null }) {\n      props.onValueChange?.(details.value)\n      emit('update:modelValue', details.value)\n      emit('change', details.value)\n    },\n  }))\n\n  const service = useMachine(radioGroupMachine, machineProps)\n  const api = computed(() => radioGroupConnect(service, normalizeProps))\n\n  return api\n}\n"
        },
        {
          "path": "registry/default/html/radio-group.html",
          "target": "components/ui/radio-group.html",
          "type": "registry:component",
          "content": "<div class=\"grid gap-2\">\n    <div class=\"flex items-center justify-center\">\n        <button type=\"button\" role=\"radio\" aria-checked=\"true\" data-state=\"checked\" value=\"default\"\n            class=\"h-4 w-4\">\n            <span class=\"flex items-center justify-center\">\n                <svg width=\"6\" height=\"6\" viewBox=\"0 0 6 6\" fill=\"currentcolor\" xmlns=\"http://www.w3.org/2000/svg\">\n                    <circle cx=\"3\" cy=\"3\" r=\"3\" />\n                </svg>\n            </span>\n        </button>\n        <label\n            class=\"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\">Default</label>\n    </div>\n</div>"
        },
        {
          "path": "registry/default/weapp/radio-group.wxml",
          "target": "components/ui/radio-group.wxml",
          "type": "registry:component",
          "content": "<view \n  id=\"{{api.rootProps.id}}\"\n  class=\"{{className}}\" \n  role=\"radiogroup\"\n  data-orientation=\"{{api.orientation}}\"\n  data-disabled=\"{{api.disabled}}\"\n>\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/radio-group.wxss",
          "target": "components/ui/radio-group.wxss",
          "type": "registry:component",
          "content": "/* packages/weapp/src/radio-group/radio-group.wxss */\n"
        },
        {
          "path": "registry/default/weapp/radio-group.ts",
          "target": "components/ui/radio-group.ts",
          "type": "registry:component",
          "content": "import { radioGroupVariants, resolveClasses } from '../utils'\nimport { setupRadioGroupMachine } from './use-radio-group'\n\ntype WeappRadioGroupApi = Record<string, object>\n\ntype WeappService = {\n  setContext: (context: Record<string, object>) => void\n}\ntype MachineEvent = string | { type: string; [key: string]: object }\ntype MachineSend = (event: MachineEvent) => void\n\ntype WeappRadioGroupInternal = WechatMiniprogram.Component.InstanceMethods<{}, {}, {}> & {\n  _service?: WeappService\n  _cleanup?: () => void\n  _send?: (event: object) => void\n  _connect?: (state: object, send: MachineSend) => WeappRadioGroupApi\n  data: {\n    api: WeappRadioGroupApi\n  }\n  properties: {\n    value: string\n    name: string\n    disabled: boolean\n    orientation: string\n    id: string\n    extClass: string\n  }\n}\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    value: {\n      type: String,\n      value: '',\n    },\n    name: {\n      type: String,\n      value: '',\n    },\n    disabled: {\n      type: Boolean,\n      value: false,\n    },\n    orientation: {\n      type: String,\n      value: 'vertical',\n    },\n    id: {\n      type: String,\n      value: 'radio-group',\n    },\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n\n  data: {\n    api: {} as WeappRadioGroupApi,\n    className: '',\n  },\n\n  lifetimes: {\n    attached() {\n      const self = this as WeappRadioGroupInternal\n      const { controller, connect } = setupRadioGroupMachine(this)\n      self._service = controller.service as WeappService\n      self._cleanup = controller.start()\n      self._send = controller.send as MachineSend\n      self._connect = connect\n    },\n    detached() {\n      const self = this as WeappRadioGroupInternal\n      self._cleanup?.()\n    },\n  },\n\n  observers: {\n    state: function (state) {\n      const self = this as WeappRadioGroupInternal\n      if (!state || !self._send || !self._connect) return\n      const api = self._connect(state, self._send) as WeappRadioGroupApi\n\n      const { baseClass } = resolveClasses(radioGroupVariants(), self.properties.extClass)\n\n      this.setData({ api, className: baseClass })\n    },\n\n    value: function (val) {\n      const self = this as WeappRadioGroupInternal\n      if (self._service) {\n        self._service.setContext({ value: val })\n      }\n    },\n\n    disabled: function (val) {\n      const self = this as WeappRadioGroupInternal\n      if (self._service) {\n        self._service.setContext({ disabled: val })\n      }\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/radio-group.json",
          "target": "components/ui/radio-group.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/radio-group-item/radio-group-item.wxml",
          "target": "components/ui/radio-group-item/radio-group-item.wxml",
          "type": "registry:component",
          "content": "<view \n  class=\"{{className}} flex items-center justify-center\"\n  data-state=\"{{checked ? 'checked' : 'unchecked'}}\"\n  bindtap=\"handleTap\"\n>\n  <view class=\"flex items-center justify-center text-current\" wx:if=\"{{checked}}\">\n    <image class=\"w-2.5 h-2.5 bg-current rounded-full\" src=\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNiIgaGVpZ2h0PSI2IiB2aWV3Qm94PSIwIDAgNiA2IiBmaWxsPSJjdXJyZW50Y29sb3IiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGNpcmNsZSBjeD0iMyIgY3k9IjMiIHI9IjMiIC8+PC9zdmc+\" />\n  </view>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/radio-group-item/radio-group-item.wxss",
          "target": "components/ui/radio-group-item/radio-group-item.wxss",
          "type": "registry:component",
          "content": "/* packages/weapp/src/radio-group-item/radio-group-item.wxss */\n"
        },
        {
          "path": "registry/default/weapp/radio-group-item/radio-group-item.json",
          "target": "components/ui/radio-group-item/radio-group-item.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/radio-group-item/radio-group-item.ts",
          "target": "components/ui/radio-group-item/radio-group-item.ts",
          "type": "registry:component",
          "content": "import type { RadioGroupItemWeappProps } from '@timui/core'\n\nimport { radioGroupItemVariants } from '../utils'\n\ntype RadioGroupItemProperty = {\n  type: StringConstructor | BooleanConstructor\n  value: string | boolean\n}\n\ntype RadioGroupParent = {\n  handleChildChange: (value: string) => void\n}\n\nconst radioGroupItemProps = {\n  value: { type: String, value: '' },\n  disabled: { type: Boolean, value: false },\n  invalid: { type: Boolean, value: false },\n  extClass: { type: String, value: '' },\n} satisfies Record<keyof RadioGroupItemWeappProps, RadioGroupItemProperty>\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: radioGroupItemProps,\n  relations: {\n    '../radio-group/radio-group': {\n      type: 'ancestor',\n    },\n  },\n  data: {\n    checked: false,\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass: string) {\n      // Note: We cannot easily toggle classes based on 'checked' inside observer if the variant doesn't support it directly without 'data-state'.\n      // But we can manually toggle.\n      // Shared variant: '... data-[state=checked]:bg-primary ...'\n      // We will rely on template logic for the data-state attribute or conditional classes?\n      // Since we are using standard `radioGroupItemVariants`, it expects `className`.\n      // It DOES NOT accept `checked` as a variant prop in the current definition (it uses data-attributes in React).\n      // So we just generate the base class here.\n      this.setData({\n        className: radioGroupItemVariants({ className: extClass }),\n      })\n    },\n  },\n  methods: {\n    handleTap() {\n      if (this.properties.disabled) return\n      const parent = this.getRelationNodes('../radio-group/radio-group')[0] as\n        | RadioGroupParent\n        | undefined\n      if (parent) {\n        parent.handleChildChange(this.properties.value)\n      }\n    },\n  },\n})\n"
        }
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@zag-js/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@zag-js/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {
            "dependencies": [
              "@timui/core"
            ]
          },
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "scroll-area",
      "type": "registry:ui",
      "dependencies": [
        "@timui/core"
      ],
      "files": [
        {
          "path": "registry/default/ui/scroll-area.tsx",
          "type": "registry:ui",
          "target": "components/ui/scroll-area.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport type { AssertNoExtraKeys, ScrollAreaProps as CoreScrollAreaProps } from '@timui/core'\nimport { cn, scrollAreaVariants, scrollAreaViewportVariants } from '@timui/core'\n\ntype ScrollAreaProps = CoreScrollAreaProps &\n  React.HTMLAttributes<HTMLDivElement> & { scrollBarClassName?: string }\ntype _ScrollAreaPropsGuard = AssertNoExtraKeys<\n  ScrollAreaProps,\n  CoreScrollAreaProps & React.HTMLAttributes<HTMLDivElement> & { scrollBarClassName?: string }\n>\n\nconst ScrollArea = React.forwardRef<HTMLDivElement, ScrollAreaProps>(\n  ({ className, children, orientation = 'vertical', scrollBarClassName, ...props }, ref) => (\n    <div\n      ref={ref}\n      data-slot=\"scroll-area\"\n      className={cn(scrollAreaVariants(), className)}\n      {...props}\n    >\n      <div\n        data-slot=\"scroll-viewport\"\n        className={cn(scrollAreaViewportVariants(), scrollBarClassName)}\n      >\n        {children}\n      </div>\n    </div>\n  )\n)\nScrollArea.displayName = 'ScrollArea'\n\n// Mock ScrollBar component for API compatibility\nconst ScrollBar = React.forwardRef<\n  HTMLDivElement,\n  React.HTMLAttributes<HTMLDivElement> & { orientation?: 'vertical' | 'horizontal' }\n>(\n  ({ className, orientation = 'vertical', ...props }, ref) =>\n    null // Native scroll doesn't need a separate scrollbar element usually unless specialized\n)\nScrollBar.displayName = 'ScrollBar'\n\nexport { ScrollArea, ScrollBar }\n"
        },
        {
          "path": "registry/default/vue/scroll-area/scroll-area.vue",
          "target": "components/ui/scroll-area/scroll-area.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ScrollAreaRoot, ScrollAreaViewport, ScrollAreaCorner, type ScrollAreaRootProps } from 'radix-vue'\nimport ScrollBar from '../scroll-bar/scroll-bar.vue'\nimport { cn, scrollAreaVariants, scrollAreaViewportVariants } from '@timui/core'\nimport type { HTMLAttributes } from 'vue'\n\nconst props = defineProps<ScrollAreaRootProps & { class?: HTMLAttributes['class'] }>()\n</script>\n\n<template>\n  <ScrollAreaRoot\n    v-bind=\"props\"\n    :class=\"cn(scrollAreaVariants(), props.class)\"\n  >\n    <ScrollAreaViewport :class=\"scrollAreaViewportVariants()\">\n      <slot />\n    </ScrollAreaViewport>\n    <ScrollBar />\n    <ScrollAreaCorner />\n  </ScrollAreaRoot>\n</template>\n"
        },
        {
          "path": "registry/default/html/scroll-area.html",
          "target": "components/ui/scroll-area.html",
          "type": "registry:component",
          "content": "<div data-slot=\"scroll-area\" class=\"h-full w-full rounded-[inherit]\">\n  <p>Scrollable content line 1</p>\n  <p>Scrollable content line 2</p>\n  <p>Scrollable content line 3</p>\n  <p>Scrollable content line 4</p>\n  <p>Scrollable content line 5</p>\n  <p>Scrollable content line 6</p>\n  <p>Scrollable content line 7</p>\n  <p>Scrollable content line 8</p>\n</div>"
        },
        {
          "path": "registry/default/weapp/scroll-area.wxml",
          "target": "components/ui/scroll-area.wxml",
          "type": "registry:component",
          "content": "<scroll-view\n  class=\"scroll-area {{extClass}}\"\n  scroll-y=\"{{scrollY}}\"\n  scroll-x=\"{{scrollX}}\"\n  style=\"height: {{height}};\"\n  bindscroll=\"onScroll\"\n>\n  <slot />\n</scroll-view>\n"
        },
        {
          "path": "registry/default/weapp/scroll-area.wxss",
          "target": "components/ui/scroll-area.wxss",
          "type": "registry:component",
          "content": ".scroll-area {\n  width: 100%;\n  border: 1px solid #e5e7eb;\n  border-radius: 12rpx;\n  box-sizing: border-box;\n}\n"
        },
        {
          "path": "registry/default/weapp/scroll-area.ts",
          "target": "components/ui/scroll-area.ts",
          "type": "registry:component",
          "content": "Component({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    scrollY: {\n      type: Boolean,\n      value: true,\n    },\n    scrollX: {\n      type: Boolean,\n      value: false,\n    },\n    height: {\n      type: String,\n      value: '320rpx',\n    },\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n\n  methods: {\n    onScroll(e: WechatMiniprogram.ScrollViewScroll) {\n      this.triggerEvent('scroll', e.detail)\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/scroll-area.json",
          "target": "components/ui/scroll-area.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        }
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core"
            ],
            "optionalPeerDependencies": [
              "radix-vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "select-native",
      "type": "registry:ui",
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/ui/select-native.tsx",
          "type": "registry:ui",
          "target": "components/ui/select-native.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport type { AssertNoExtraKeys, SelectNativeProps as CoreSelectNativeProps } from '@timui/core'\nimport {\n  cn,\n  selectNativeIndicatorVariants,\n  selectNativeVariants,\n  selectNativeWrapperVariants,\n} from '@timui/core'\nimport { ChevronDownIcon } from 'lucide-react'\n\ntype SelectNativeProps = CoreSelectNativeProps &\n  Omit<React.ComponentProps<'select'>, keyof CoreSelectNativeProps>\ntype _SelectNativePropsGuard = AssertNoExtraKeys<\n  SelectNativeProps,\n  CoreSelectNativeProps & React.ComponentProps<'select'>\n>\n\nconst SelectNative = ({\n  className,\n  children,\n  onValueChange,\n  onChange,\n  ...props\n}: SelectNativeProps) => {\n  const handleChange = (event: React.ChangeEvent<HTMLSelectElement>) => {\n    onChange?.(event)\n    if (props.multiple) {\n      const values = Array.from(event.target.selectedOptions).map((option) => option.value)\n      onValueChange?.(values)\n      return\n    }\n    onValueChange?.(event.target.value)\n  }\n\n  return (\n    <div className={selectNativeWrapperVariants()}>\n      <select\n        data-slot=\"select-native\"\n        className={cn(selectNativeVariants({ multiple: props.multiple }), className)}\n        onChange={handleChange}\n        {...props}\n      >\n        {children}\n      </select>\n      {!props.multiple && (\n        <span className={selectNativeIndicatorVariants()}>\n          <ChevronDownIcon size={16} aria-hidden=\"true\" />\n        </span>\n      )}\n    </div>\n  )\n}\n\nexport { SelectNative }\n"
        },
        {
          "path": "registry/default/vue/select-native/select-native.vue",
          "target": "components/ui/select-native/select-native.vue",
          "type": "registry:component",
          "content": "<script lang=\"ts\">\nexport { default } from '../select/select-native.vue'\n</script>\n"
        },
        {
          "path": "registry/default/html/select-native.html",
          "target": "components/ui/select-native.html",
          "type": "registry:component",
          "content": "<select data-slot=\"select-native\" class=\"border-input text-foreground focus-visible:border-ring focus-visible:ring-ring/50 has-[option[disabled]:checked]:text-muted-foreground aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive inline-flex w-full cursor-pointer appearance-none items-center rounded-md border text-sm shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 h-9 ps-3 pe-8\">\n  <option>Option one</option>\n  <option>Option two</option>\n</select>"
        },
        {
          "path": "registry/default/weapp/select-native.wxml",
          "target": "components/ui/select-native.wxml",
          "type": "registry:component",
          "content": "<picker range=\"{{options}}\" value=\"{{value}}\" bindchange=\"handleChange\">\n  <view class=\"{{className}}\" data-slot=\"select-native\">\n    {{displayText}}\n  </view>\n</picker>\n"
        },
        {
          "path": "registry/default/weapp/select-native.wxss",
          "target": "components/ui/select-native.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/select-native.ts",
          "target": "components/ui/select-native.ts",
          "type": "registry:component",
          "content": "import { emitTimEvent } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    options: {\n      type: Array,\n      value: [],\n    },\n    value: {\n      type: Number,\n      value: 0,\n    },\n    id: {\n      type: String,\n      value: 'select-native',\n    },\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n  data: {\n    className: '',\n    displayText: '',\n  },\n  lifetimes: {\n    attached() {\n      this.updateDisplay()\n      this.setData({\n        className:\n          `border-input text-foreground focus-visible:border-ring focus-visible:ring-ring/50 inline-flex w-full cursor-pointer appearance-none items-center rounded-md border bg-background px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] ${this.properties.extClass}`.trim(),\n      })\n    },\n  },\n  observers: {\n    'options, value, extClass': function () {\n      this.updateDisplay()\n      this.setData({\n        className:\n          `border-input text-foreground focus-visible:border-ring focus-visible:ring-ring/50 inline-flex w-full cursor-pointer appearance-none items-center rounded-md border bg-background px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] ${this.properties.extClass}`.trim(),\n      })\n    },\n  },\n  methods: {\n    updateDisplay() {\n      const options = this.properties.options || []\n      const value = this.properties.value || 0\n      const displayText = options[value] || ''\n      this.setData({ displayText })\n    },\n    handleChange(e: WechatMiniprogram.CustomEvent<{ value: string }>) {\n      const value = Number(e.detail.value)\n      emitTimEvent(this, 'change', 'change', this.properties.id || 'select-native', {\n        value,\n      })\n      this.setData({ displayText: (this.properties.options || [])[value] || '' })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/select-native.json",
          "target": "components/ui/select-native.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        }
      ],
      "dependencies": [
        "@timui/core"
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {},
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "select",
      "type": "registry:ui",
      "dependencies": [
        "@timui/core",
        "@zag-js/react"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/ui/select.tsx",
          "type": "registry:ui",
          "target": "components/ui/select.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport {\n  cn,\n  selectCollection,\n  selectContentPopperVariants,\n  selectContentVariants,\n  selectItemVariants,\n  selectLabelVariants,\n  selectSeparatorVariants,\n  selectTriggerIconVariants,\n  selectTriggerVariants,\n  selectValueVariants,\n} from '@timui/core'\nimport { mergeProps, Portal } from '@zag-js/react'\nimport { CheckIcon, ChevronDownIcon } from 'lucide-react'\n\nimport { useSelect, type SelectItemData, type SelectProps } from './select/use-select'\nimport { SelectProvider, useSelectContext } from './select/use-select-context'\nimport { Slot } from './slot'\n\nconst Select = (props: SelectProps) => {\n  const { children, collection: externalCollection } = props\n  const internalCollectionRef = React.useRef(selectCollection<SelectItemData>({ items: [] }))\n  const [itemLabels, setItemLabels] = React.useState<Record<string, string>>({})\n  const collection = externalCollection ?? internalCollectionRef.current\n  const api = useSelect({ ...props, collection })\n\n  const registerItem = React.useCallback(\n    (item: SelectItemData) => {\n      if (!externalCollection) {\n        internalCollectionRef.current.upsert(item.value, item)\n      }\n      setItemLabels((prev) => {\n        if (prev[item.value] === item.label) return prev\n        return { ...prev, [item.value]: item.label }\n      })\n    },\n    [externalCollection]\n  )\n\n  const unregisterItem = React.useCallback(\n    (value: string) => {\n      if (!externalCollection) {\n        internalCollectionRef.current.remove(value)\n      }\n      setItemLabels((prev) => {\n        if (!(value in prev)) return prev\n        const next = { ...prev }\n        delete next[value]\n        return next\n      })\n    },\n    [externalCollection]\n  )\n\n  const getItemLabel = React.useCallback(\n    (value: string) => {\n      if (externalCollection) return externalCollection.find(value)?.label\n      return itemLabels[value]\n    },\n    [externalCollection, itemLabels]\n  )\n\n  const contextValue = React.useMemo(\n    () => ({ ...api, registerItem, unregisterItem, getItemLabel }),\n    [api, getItemLabel, registerItem, unregisterItem]\n  )\n\n  return <SelectProvider value={contextValue}>{children}</SelectProvider>\n}\n\ntype SelectTriggerProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {\n  asChild?: boolean\n}\n\nconst SelectTrigger = React.forwardRef<HTMLButtonElement, SelectTriggerProps>(\n  ({ className, children, asChild = false, ...props }, ref) => {\n    const api = useSelectContext()\n    const Comp = asChild ? Slot : 'button'\n    const triggerProps = api.getTriggerProps?.() ?? {}\n    const mergedProps = mergeProps(triggerProps, props)\n\n    if (asChild) {\n      return (\n        <Comp ref={ref} className={cn(className)} {...mergedProps}>\n          {children}\n        </Comp>\n      )\n    }\n\n    return (\n      <Comp ref={ref} className={cn(selectTriggerVariants(), className)} {...mergedProps}>\n        {children}\n        <ChevronDownIcon className={selectTriggerIconVariants()} />\n      </Comp>\n    )\n  }\n)\nSelectTrigger.displayName = 'SelectTrigger'\n\ntype SelectContentProps = React.HTMLAttributes<HTMLDivElement> & {\n  position?: 'popper' | 'item-aligned'\n}\n\nconst SelectContent = React.forwardRef<HTMLDivElement, SelectContentProps>(\n  ({ className, children, position = 'popper', ...props }, ref) => {\n    const api = useSelectContext()\n    const positionerProps = api.getPositionerProps?.() ?? {}\n    const contentProps = api.getContentProps?.() ?? {}\n    const mergedProps = mergeProps(contentProps, props) as React.HTMLAttributes<HTMLDivElement>\n\n    return (\n      <Portal>\n        <div {...positionerProps} style={{ ...positionerProps.style, zIndex: 50 }}>\n          <div\n            ref={ref}\n            className={cn(\n              selectContentVariants(),\n              position === 'popper' && selectContentPopperVariants(),\n              className\n            )}\n            {...mergedProps}\n          >\n            {children}\n          </div>\n        </div>\n      </Portal>\n    )\n  }\n)\nSelectContent.displayName = 'SelectContent'\n\ntype SelectItemProps = React.HTMLAttributes<HTMLDivElement> & {\n  value: string\n  label?: string\n  disabled?: boolean\n  children?: React.ReactNode\n}\n\nconst isSelected = (apiValue: string | string[] | undefined, value: string) => {\n  if (Array.isArray(apiValue)) return apiValue.includes(value)\n  return apiValue === value\n}\n\nconst SelectItem = React.forwardRef<HTMLDivElement, SelectItemProps>(\n  ({ className, children, value, label, disabled, ...props }, ref) => {\n    const api = useSelectContext()\n    const itemLabel = React.useMemo(() => {\n      if (label) return label\n      if (typeof children === 'string' || typeof children === 'number') return String(children)\n      return value\n    }, [children, label, value])\n    const item = React.useMemo<SelectItemData>(\n      () => ({ label: itemLabel, value, disabled }),\n      [disabled, itemLabel, value]\n    )\n    const itemProps = api?.getItemProps?.({ item }) ?? {}\n    const mergedProps = mergeProps(itemProps, props) as React.HTMLAttributes<HTMLDivElement>\n    const registerItem = api.registerItem\n    const unregisterItem = api.unregisterItem\n\n    React.useEffect(() => {\n      registerItem?.(item)\n      return () => {\n        unregisterItem?.(item.value)\n      }\n    }, [item, registerItem, unregisterItem])\n\n    return (\n      <div\n        ref={ref}\n        className={cn(selectItemVariants(), className)}\n        {...mergedProps}\n      >\n        <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n          {isSelected(api?.value, value) ? <CheckIcon className=\"h-4 w-4\" /> : null}\n        </span>\n        <span className=\"truncate\">{children}</span>\n      </div>\n    )\n  }\n)\nSelectItem.displayName = 'SelectItem'\n\nconst SelectLabel = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, ...props }, ref) => (\n    <div ref={ref} className={cn(selectLabelVariants(), className)} {...props} />\n  )\n)\nSelectLabel.displayName = 'SelectLabel'\n\nconst SelectSeparator = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, ...props }, ref) => (\n    <div ref={ref} className={cn(selectSeparatorVariants(), className)} {...props} />\n  )\n)\nSelectSeparator.displayName = 'SelectSeparator'\n\ntype SelectValueProps = React.HTMLAttributes<HTMLSpanElement> & {\n  placeholder?: string\n}\n\nconst SelectValue = React.forwardRef<HTMLSpanElement, SelectValueProps>(\n  ({ className, placeholder, ...props }, ref) => {\n    const api = useSelectContext()\n    const values = api?.value ?? []\n    const fallbackValue = values.map((value) => api.getItemLabel?.(value) ?? value).join(', ')\n    const hasRegisteredLabel = values.some((value) => api.getItemLabel?.(value) !== undefined)\n    const displayValue = (hasRegisteredLabel ? fallbackValue : api?.valueAsString || fallbackValue) || placeholder\n    return (\n      <span ref={ref} className={cn(selectValueVariants(), className)} {...props}>\n        {displayValue}\n      </span>\n    )\n  }\n)\nSelectValue.displayName = 'SelectValue'\n\nconst SelectGroup = (props: React.HTMLAttributes<HTMLDivElement>) => <div {...props} />\nconst SelectScrollUpButton = (props: React.HTMLAttributes<HTMLDivElement>) => <div {...props} />\nconst SelectScrollDownButton = (props: React.HTMLAttributes<HTMLDivElement>) => <div {...props} />\n\nexport {\n  Select,\n  SelectGroup,\n  SelectValue,\n  SelectTrigger,\n  SelectContent,\n  SelectLabel,\n  SelectItem,\n  SelectSeparator,\n  SelectScrollUpButton,\n  SelectScrollDownButton,\n}\n"
        },
        {
          "path": "registry/default/vue/select.vue",
          "type": "registry:ui",
          "target": "components/ui/select.vue",
          "content": "<script setup lang=\"ts\">\nimport { selectCollection, type SelectItem, type SelectVueProps } from \"@timui/core\";\nimport { ref } from \"vue\";\nimport { useSelect } from \"./use-select\";\nimport { provideSelectContext } from \"./use-select-context\";\nimport { provideSelectItemsContext } from \"./use-select-items-context\";\n\nconst props = defineProps<SelectVueProps>();\n\nconst emit = defineEmits([\"update:modelValue\", \"change\"]);\n\nconst internalCollection = selectCollection<SelectItem>({ items: [] });\nconst itemLabels = ref<Record<string, string>>({});\n\nconst registerItem = (item: SelectItem) => {\n  if (!props.collection) {\n    internalCollection.upsert(item.value, item);\n  }\n  itemLabels.value = { ...itemLabels.value, [item.value]: item.label };\n};\n\nconst unregisterItem = (value: string) => {\n  if (!props.collection) {\n    internalCollection.remove(value);\n  }\n  if (!(value in itemLabels.value)) return;\n  const next = { ...itemLabels.value };\n  delete next[value];\n  itemLabels.value = next;\n};\n\nconst api = useSelect(props, emit, internalCollection);\nprovideSelectContext(api);\nprovideSelectItemsContext({ registerItem, unregisterItem, itemLabels });\n</script>\n\n<template>\n  <slot />\n</template>\n"
        },
        {
          "path": "registry/default/ui/select/use-select-context.tsx",
          "target": "components/ui/select/use-select-context.tsx",
          "type": "registry:ui",
          "content": "import * as React from 'react'\n\nimport type { SelectItemData } from './use-select'\n\nexport type SelectApiLike = {\n  open?: boolean\n  value?: string[]\n  valueAsString?: string\n  getTriggerProps?: () => React.HTMLAttributes<HTMLElement>\n  getPositionerProps?: () => React.HTMLAttributes<HTMLElement> & { style?: React.CSSProperties }\n  getContentProps?: () => React.HTMLAttributes<HTMLElement>\n  getItemProps?: (options: { item: SelectItemData }) => React.HTMLAttributes<HTMLElement>\n  registerItem?: (item: SelectItemData) => void\n  unregisterItem?: (value: string) => void\n  getItemLabel?: (value: string) => string | undefined\n}\n\nexport const SelectContext = React.createContext<SelectApiLike | null>(null)\nexport const SelectProvider = SelectContext.Provider\n\nexport function useSelectContext() {\n  const context = React.useContext(SelectContext)\n  if (!context) {\n    throw new Error('useSelectContext must be used within a Select component')\n  }\n  return context\n}\n"
        },
        {
          "path": "registry/default/ui/select/use-select.ts",
          "target": "components/ui/select/use-select.ts",
          "type": "registry:ui",
          "content": "import * as React from 'react'\nimport type { SelectProps as CoreSelectProps, SelectValueChangeEvent } from '@timui/core'\nimport { createTimEvent, selectCollection, selectConnect, selectMachine } from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/react'\n\nexport type SelectItemData = {\n  label: string\n  value: string\n  disabled?: boolean\n}\n\nexport type SelectProps = {\n  id?: string\n  collection?: ReturnType<typeof selectCollection<SelectItemData>>\n  value?: string\n  defaultValue?: string\n  disabled?: boolean\n  required?: boolean\n  name?: string\n  open?: boolean\n  defaultOpen?: boolean\n  onValueChange?: (event: SelectValueChangeEvent) => void\n  onOpenChange?: CoreSelectProps['onOpenChange']\n  children?: React.ReactNode\n}\n\nexport function useSelect(props: SelectProps) {\n  const generatedId = React.useId()\n  const selectId = props.id ?? generatedId\n  const value = props.value !== undefined ? [props.value] : undefined\n  const defaultValue = props.value === undefined && props.defaultValue !== undefined\n    ? [props.defaultValue]\n    : undefined\n  const service = useMachine(selectMachine, {\n    id: selectId,\n    collection: props.collection ?? selectCollection<SelectItemData>({ items: [] }),\n    value,\n    defaultValue,\n    disabled: props.disabled,\n    required: props.required,\n    name: props.name,\n    open: props.open,\n    defaultOpen: props.defaultOpen,\n    onOpenChange: props.onOpenChange,\n    onValueChange(details) {\n      props.onValueChange?.(\n        createTimEvent('change', selectId, { value: details.value }) as SelectValueChangeEvent\n      )\n    },\n  })\n\n  return React.useMemo(() => selectConnect(service, normalizeProps), [service])\n}\n"
        },
        {
          "path": "registry/default/vue/select/select-content.vue",
          "target": "components/ui/select/select-content.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { useSelectContext } from \"./use-select-context\";\nimport { computed, inject, type HTMLAttributes, type Ref } from \"vue\";\nimport { ChevronDownIcon, ChevronUpIcon } from \"lucide-vue-next\";\nimport { cn, selectContentPopperVariants, selectContentVariants } from \"@timui/core\";\nimport Presence from \"../presence/presence.vue\";\n\nconst props = withDefaults(\n  defineProps<{ class?: HTMLAttributes[\"class\"]; position?: \"popper\" | \"item-aligned\" }>(),\n  {\n    position: \"popper\",\n  }\n);\n\ntype BindValue = string | number | boolean | null | undefined | ((...args: never[]) => void);\ntype SelectApi = {\n  open?: boolean;\n  getPositionerProps?: () => Record<string, BindValue>;\n  getContentProps?: () => Record<string, BindValue>;\n};\n\nconst api = useSelectContext() as Ref<SelectApi | undefined> | undefined;\nconst isOpen = computed(() => api?.value?.open);\nconst positionerProps = computed(() => api?.value?.getPositionerProps?.() || {});\nconst contentProps = computed(() => api?.value?.getContentProps?.() || {});\n</script>\n\n<template>\n  <Teleport to=\"body\">\n    <Presence\n      :present=\"isOpen || false\"\n      :lazyMount=\"false\"\n      :unmountOnExit=\"false\"\n      v-bind=\"positionerProps\"\n      style=\"z-index: 50\"\n    >\n      <div\n        v-bind=\"contentProps\"\n        :class=\"\n          cn(\n            selectContentVariants(),\n            props.position === 'popper' &&\n              selectContentPopperVariants(),\n            props.class\n          )\n        \"\n      >\n        <div class=\"flex cursor-default items-center justify-center py-1\">\n          <ChevronUpIcon class=\"h-4 w-4\" />\n        </div>\n\n        <div\n          :class=\"\n            cn(\n              'p-1',\n              props.position === 'popper' &&\n                'h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]'\n            )\n          \"\n        >\n          <slot />\n        </div>\n\n        <div class=\"flex cursor-default items-center justify-center py-1\">\n          <ChevronDownIcon class=\"h-4 w-4\" />\n        </div>\n      </div>\n    </Presence>\n  </Teleport>\n</template>\n"
        },
        {
          "path": "registry/default/vue/select/select-group.vue",
          "target": "components/ui/select/select-group.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn } from \"@timui/core\";\nimport type { HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\n</script>\n\n<template>\n  <div :class=\"cn('p-1 w-full', props.class)\">\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/select/select-item.vue",
          "target": "components/ui/select/select-item.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { useSelectContext } from \"./use-select-context\";\nimport { useSelectItemsContext } from \"./use-select-items-context\";\nimport { computed, onBeforeUnmount, useSlots, watch, type Ref, type VNode } from \"vue\";\nimport { CheckIcon } from \"lucide-vue-next\";\nimport { cn, selectItemVariants } from \"@timui/core\";\n\nconst props = defineProps<{\n  value: string;\n  label?: string;\n  disabled?: boolean;\n  class?: string;\n}>();\n\ntype BindValue = string | number | boolean | null | undefined | ((...args: never[]) => void);\ntype SelectItem = { label: string; value: string; disabled?: boolean };\ntype SelectApi = {\n  value?: string | string[];\n  getItemProps?: (options: { item: SelectItem }) => Record<string, BindValue>;\n};\n\nconst api = useSelectContext() as Ref<SelectApi | undefined> | undefined;\nconst itemsContext = useSelectItemsContext();\nconst slots = useSlots();\n\nconst getTextContent = (nodes?: VNode[]): string => {\n  if (!nodes) return \"\";\n  return nodes\n    .map((node) => {\n      if (typeof node.children === \"string\" || typeof node.children === \"number\") {\n        return String(node.children);\n      }\n      if (Array.isArray(node.children)) {\n        return getTextContent(node.children as VNode[]);\n      }\n      return \"\";\n    })\n    .join(\"\");\n};\n\nconst itemLabel = computed(() => {\n  if (props.label) return props.label;\n  const slotText = getTextContent(slots.default?.()).trim();\n  return slotText || props.value;\n});\n\nconst item = computed(() => ({\n  label: itemLabel.value,\n  value: props.value,\n  disabled: props.disabled,\n}));\nconst itemProps = computed(() => api?.value?.getItemProps?.({ item: item.value }) || {});\n\nwatch(\n  item,\n  (next, prev) => {\n    if (prev && prev.value !== next.value) {\n      itemsContext.unregisterItem(prev.value);\n    }\n    itemsContext.registerItem(next);\n  },\n  { immediate: true, deep: true }\n);\n\nonBeforeUnmount(() => {\n  itemsContext.unregisterItem(props.value);\n});\n\nconst isSelected = computed(() => {\n  const value = api?.value?.value;\n  if (Array.isArray(value)) return value.includes(props.value);\n  return value === props.value;\n});\n</script>\n\n<template>\n  <div\n    v-bind=\"itemProps\"\n    :class=\"\n      cn(\n        selectItemVariants(),\n        props.class\n      )\n    \"\n  >\n    <span class=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n      <CheckIcon v-if=\"isSelected\" class=\"h-4 w-4\" />\n    </span>\n    <span class=\"truncate\">\n      <slot />\n    </span>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/select/select-label.vue",
          "target": "components/ui/select/select-label.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, selectLabelVariants } from \"@timui/core\";\nimport type { HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\n</script>\n\n<template>\n  <div :class=\"cn(selectLabelVariants(), props.class)\">\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/select/select-native.vue",
          "target": "components/ui/select/select-native.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, ref, useAttrs, watch } from \"vue\";\nimport { ChevronDownIcon } from \"lucide-vue-next\";\nimport {\n  cn,\n  selectNativeIndicatorVariants,\n  selectNativeVariants,\n  selectNativeWrapperVariants,\n} from \"@timui/core\";\nimport type { HTMLAttributes } from \"vue\";\nimport type { AssertNoExtraKeys, SelectNativeVueProps } from \"@timui/core\";\n\ndefineOptions({\n  inheritAttrs: false,\n});\n\ntype SelectNativeProps = SelectNativeVueProps & { class?: HTMLAttributes[\"class\"] };\ntype _SelectNativePropsGuard = AssertNoExtraKeys<\n  SelectNativeProps,\n  SelectNativeVueProps & { class?: HTMLAttributes[\"class\"] }\n>;\n\nconst props = defineProps<SelectNativeProps>();\n\nconst emit = defineEmits([\"update:modelValue\", \"change\"]);\nconst attrs = useAttrs();\n\nconst localValue = ref<string | string[] | undefined>(\n  props.modelValue ?? props.defaultValue\n);\n\nwatch(\n  () => props.modelValue,\n  (val) => {\n    if (val !== undefined) localValue.value = val;\n  }\n);\n\nconst onChange = (event: Event) => {\n  const target = event.target as HTMLSelectElement;\n  const value = props.multiple\n    ? Array.from(target.selectedOptions).map((option) => option.value)\n    : target.value;\n  localValue.value = value;\n  emit(\"update:modelValue\", value);\n  emit(\"change\", value);\n};\n\nconst selectClass = computed(() =>\n  cn(\n    selectNativeVariants({ multiple: props.multiple }),\n    props.class\n  )\n);\n</script>\n\n<template>\n  <div :class=\"selectNativeWrapperVariants()\">\n    <select\n      data-slot=\"select-native\"\n      :multiple=\"props.multiple\"\n      :class=\"selectClass\"\n      v-model=\"localValue\"\n      v-bind=\"attrs\"\n      @change=\"onChange\"\n    >\n      <slot />\n    </select>\n    <span v-if=\"!props.multiple\" :class=\"selectNativeIndicatorVariants()\">\n      <ChevronDownIcon :size=\"16\" aria-hidden=\"true\" />\n    </span>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/select/select-scroll-down-button.vue",
          "target": "components/ui/select/select-scroll-down-button.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ChevronDownIcon } from \"lucide-vue-next\";\nimport { cn } from \"@timui/core\";\nimport type { HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\n</script>\n\n<template>\n  <div :class=\"cn('flex cursor-default items-center justify-center py-1', props.class)\">\n    <slot>\n      <ChevronDownIcon class=\"h-4 w-4\" />\n    </slot>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/select/select-scroll-up-button.vue",
          "target": "components/ui/select/select-scroll-up-button.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ChevronUpIcon } from \"lucide-vue-next\";\nimport { cn } from \"@timui/core\";\nimport type { HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\n</script>\n\n<template>\n  <div :class=\"cn('flex cursor-default items-center justify-center py-1', props.class)\">\n    <slot>\n      <ChevronUpIcon class=\"h-4 w-4\" />\n    </slot>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/select/select-separator.vue",
          "target": "components/ui/select/select-separator.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, selectSeparatorVariants } from \"@timui/core\";\nimport type { HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\n</script>\n\n<template>\n  <div :class=\"cn(selectSeparatorVariants(), props.class)\">\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/select/select-trigger.vue",
          "target": "components/ui/select/select-trigger.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { useSelectContext } from \"./use-select-context\";\nimport { computed, inject, type Component, type HTMLAttributes, type Ref } from \"vue\";\nimport { ChevronDownIcon } from \"lucide-vue-next\";\nimport { cn, selectTriggerIconVariants, selectTriggerVariants } from \"@timui/core\";\nimport { Primitive } from '../../primitive';\n\nconst props = withDefaults(\n  defineProps<{\n    as?: string | Component;\n    asChild?: boolean;\n    class?: HTMLAttributes[\"class\"];\n  }>(),\n  {\n    as: \"button\",\n  }\n);\n\ntype BindValue = string | number | boolean | null | undefined | ((...args: never[]) => void);\ntype SelectApi = {\n  getTriggerProps?: () => Record<string, BindValue>;\n};\n\nconst api = useSelectContext() as Ref<SelectApi | undefined> | undefined;\nconst triggerProps = computed(() => api?.value?.getTriggerProps?.() || {});\n</script>\n\n<template>\n  <Primitive\n    :as=\"props.as\"\n    :as-child=\"props.asChild\"\n    v-bind=\"triggerProps\"\n    :class=\"\n      cn(\n        !props.asChild && selectTriggerVariants(),\n        props.class\n      )\n    \"\n  >\n    <slot />\n    <ChevronDownIcon v-if=\"!props.asChild\" :class=\"selectTriggerIconVariants()\" />\n  </Primitive>\n</template>\n"
        },
        {
          "path": "registry/default/vue/select/select-value.vue",
          "target": "components/ui/select/select-value.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { useSelectContext } from \"./use-select-context\";\nimport { useSelectItemsContext } from \"./use-select-items-context\";\nimport { computed, type Ref } from \"vue\";\nimport { cn, selectValueVariants } from \"@timui/core\";\n\nconst props = defineProps<{ class?: string; placeholder?: string }>();\ntype SelectApi = {\n  valueAsString?: string;\n  value?: string | string[];\n};\n\nconst api = useSelectContext() as Ref<SelectApi | undefined> | undefined;\nconst itemsContext = useSelectItemsContext();\nconst displayValue = computed(() => {\n  const rawValue = api?.value?.value;\n  const values = Array.isArray(rawValue) ? rawValue : rawValue ? [rawValue] : [];\n\n  if (!values || values.length === 0) return props.placeholder;\n\n  const fallback = values\n    .map((value) => itemsContext.itemLabels.value[value] ?? value)\n    .join(\", \");\n  const hasRegisteredLabel = values.some((value) => itemsContext.itemLabels.value[value] !== undefined);\n  const valueAsString = api?.value?.valueAsString;\n  const resolved = hasRegisteredLabel ? fallback : valueAsString || fallback;\n\n  return resolved || props.placeholder;\n});\n</script>\n\n<template>\n  <span :class=\"cn(selectValueVariants(), props.class)\">\n    <slot>\n      {{ displayValue }}\n    </slot>\n  </span>\n</template>\n"
        },
        {
          "path": "registry/default/vue/select/select.vue",
          "target": "components/ui/select/select.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { selectCollection, type SelectItem, type SelectVueProps } from \"@timui/core\";\nimport { ref } from \"vue\";\nimport { useSelect } from \"./use-select\";\nimport { provideSelectContext } from \"./use-select-context\";\nimport { provideSelectItemsContext } from \"./use-select-items-context\";\n\nconst props = defineProps<SelectVueProps>();\n\nconst emit = defineEmits([\"update:modelValue\", \"change\"]);\n\nconst internalCollection = selectCollection<SelectItem>({ items: [] });\nconst itemLabels = ref<Record<string, string>>({});\n\nconst registerItem = (item: SelectItem) => {\n  if (!props.collection) {\n    internalCollection.upsert(item.value, item);\n  }\n  itemLabels.value = { ...itemLabels.value, [item.value]: item.label };\n};\n\nconst unregisterItem = (value: string) => {\n  if (!props.collection) {\n    internalCollection.remove(value);\n  }\n  if (!(value in itemLabels.value)) return;\n  const next = { ...itemLabels.value };\n  delete next[value];\n  itemLabels.value = next;\n};\n\nconst api = useSelect(props, emit, internalCollection);\nprovideSelectContext(api);\nprovideSelectItemsContext({ registerItem, unregisterItem, itemLabels });\n</script>\n\n<template>\n  <slot />\n</template>\n"
        },
        {
          "path": "registry/default/vue/select/use-select-context.ts",
          "target": "components/ui/select/use-select-context.ts",
          "type": "registry:component",
          "content": "import type { SelectApi } from '@timui/core'\nimport { inject, provide, type ComputedRef } from 'vue'\n\nexport const SelectContextKey = Symbol('selectContext')\n\nexport function provideSelectContext(context: ComputedRef<SelectApi>) {\n  provide(SelectContextKey, context)\n}\n\nexport function useSelectContext(): ComputedRef<SelectApi> {\n  const context = inject<ComputedRef<SelectApi>>(SelectContextKey)\n  if (!context) {\n    throw new Error('useSelectContext must be used within a Select component')\n  }\n  return context\n}\n"
        },
        {
          "path": "registry/default/vue/select/use-select-items-context.ts",
          "target": "components/ui/select/use-select-items-context.ts",
          "type": "registry:component",
          "content": "import type { SelectItem } from '@timui/core'\nimport { inject, provide, type Ref } from 'vue'\n\ntype SelectItemsContext = {\n  registerItem: (item: SelectItem) => void\n  unregisterItem: (value: string) => void\n  itemLabels: Ref<Record<string, string>>\n}\n\nconst SelectItemsContextKey = Symbol('selectItemsContext')\n\nexport function provideSelectItemsContext(context: SelectItemsContext) {\n  provide(SelectItemsContextKey, context)\n}\n\nexport function useSelectItemsContext(): SelectItemsContext {\n  const context = inject<SelectItemsContext>(SelectItemsContextKey)\n  if (!context) {\n    throw new Error('useSelectItemsContext must be used within a Select component')\n  }\n  return context\n}\n"
        },
        {
          "path": "registry/default/vue/select/use-select.ts",
          "target": "components/ui/select/use-select.ts",
          "type": "registry:component",
          "content": "import { selectCollection, selectConnect, selectMachine } from '@timui/core'\nimport type { SelectItem, SelectVueProps } from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/vue'\nimport { computed, useId, watch } from 'vue'\n\ntype SelectEmits = {\n  (e: 'update:modelValue', value?: string): void\n  (e: 'change', value?: string): void\n}\n\nexport function useSelect(\n  props: SelectVueProps,\n  emit: SelectEmits,\n  fallbackCollection?: ReturnType<typeof selectCollection<SelectItem>>\n) {\n  const generatedId = useId()\n  const defaultCollection = fallbackCollection ?? selectCollection<SelectItem>({ items: [] })\n  const collection = computed(() => props.collection ?? defaultCollection)\n  const currentValue = computed(() => {\n    if (props.modelValue !== undefined) return props.modelValue\n    if (props.value !== undefined) return props.value\n    return undefined\n  })\n\n  const machineProps = computed(() => ({\n    id: props.id ?? generatedId,\n    collection: collection.value,\n    value: currentValue.value !== undefined ? [currentValue.value] : undefined,\n    defaultValue:\n      currentValue.value === undefined && props.defaultValue !== undefined\n        ? [props.defaultValue]\n        : undefined,\n    disabled: props.disabled,\n    required: props.required,\n    name: props.name,\n    open: props.open,\n    defaultOpen: props.defaultOpen,\n    onValueChange(details: { value: string[] }) {\n      const nextValue = details.value?.[0]\n      props.onValueChange?.(nextValue)\n      emit('update:modelValue', nextValue)\n      emit('change', nextValue)\n    },\n    onOpenChange(details: { open: boolean }) {\n      props.onOpenChange?.(details.open)\n    },\n  }))\n\n  const service = useMachine(selectMachine, machineProps)\n  const api = computed(() => selectConnect(service, normalizeProps))\n\n  watch(\n    () => currentValue.value,\n    (val) => {\n      if (val !== undefined && val !== api.value?.value?.[0]) {\n        api.value?.setValue([val])\n      }\n    }\n  )\n\n  return api\n}\n"
        },
        {
          "path": "registry/default/html/select.html",
          "target": "components/ui/select.html",
          "type": "registry:component",
          "content": "<div data-slot=\"select\" class=\"focus:bg-accent focus:text-accent-foreground relative flex w-full cursor-default items-center rounded-sm py-1.5 pr-8 ps-2 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50\">\n  <button data-slot=\"select-trigger\" class=\"focus:bg-accent focus:text-accent-foreground relative flex w-full cursor-default items-center rounded-sm py-1.5 pr-8 ps-2 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50\">\n    <span data-slot=\"select-value\" class=\"line-clamp-1\">Select option</span>\n  </button>\n  <div\n    data-slot=\"select-content\"\n    class=\"bg-popover text-popover-foreground data-[state&#x3D;open]:animate-in data-[state&#x3D;closed]:animate-out data-[state&#x3D;closed]:fade-out-0 data-[state&#x3D;open]:fade-in-0 data-[state&#x3D;closed]:zoom-out-95 data-[state&#x3D;open]:zoom-in-95 data-[side&#x3D;bottom]:slide-in-from-top-2 data-[side&#x3D;left]:slide-in-from-right-2 data-[side&#x3D;right]:slide-in-from-left-2 data-[side&#x3D;top]:slide-in-from-bottom-2 relative z-50 max-h-96 min-w-32 overflow-hidden rounded-md border shadow-md\"\n  >\n    <div data-slot=\"select-item\" class=\"py-1.5 pl-8 pr-2 text-sm font-semibold\">\n      Option one\n    </div>\n    <div data-slot=\"select-item\" class=\"py-1.5 pl-8 pr-2 text-sm font-semibold\">\n      Option two\n    </div>\n  </div>\n</div>"
        },
        {
          "path": "registry/default/weapp/select.wxml",
          "target": "components/ui/select.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\">\n  <!-- Trigger (read-only input) -->\n  <view \n    class=\"select-trigger\" \n    bindtap=\"onTriggerTap\"\n    data-disabled=\"{{disabled}}\"\n  >\n    <text>{{api.valueAsString || placeholder}}</text>\n  </view>\n\n  <!-- ActionSheet-style picker (bottom sheet) -->\n  <view \n    wx:if=\"{{api.open}}\" \n    class=\"select-overlay\" \n    bindtap=\"onBackdropTap\"\n  ></view>\n  \n  <view \n    wx:if=\"{{api.open}}\" \n    class=\"select-content\"\n    data-state=\"{{api.open ? 'open' : 'closed'}}\"\n  >\n    <view class=\"select-header\">\n      <text class=\"select-title\">{{label || placeholder}}</text>\n      <view class=\"select-close\" bindtap=\"onBackdropTap\">×</view>\n    </view>\n    \n    <scroll-view scroll-y class=\"select-list\">\n      <view \n        wx:for=\"{{items}}\" \n        wx:key=\"{{itemValueKey}}\"\n        class=\"select-item\"\n        data-value=\"{{item[itemValueKey] || item}}\"\n        mark:value=\"{{item[itemValueKey] || item}}\"\n        bindtap=\"onItemTap\"\n        data-selected=\"{{api.value.includes(item[itemValueKey] || item)}}\"\n      >\n        <text>{{item[itemLabelKey] || item}}</text>\n        <text wx:if=\"{{api.value.includes(item[itemValueKey] || item)}}\" class=\"select-check\">✓</text>\n      </view>\n    </scroll-view>\n  </view>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/select.wxss",
          "target": "components/ui/select.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/select.ts",
          "target": "components/ui/select.ts",
          "type": "registry:component",
          "content": "// @ts-nocheck — WeApp Component API's `this` context is structurally incompatible with\n// the custom WeappSelectInternal interface; this is a known limitation of the WeApp SDK typings.\nimport { selectCollection } from '@timui/core'\n\nimport { emitTimEvent } from '../utils'\nimport { createCollection, createScopedMachineId } from '../utils/collection'\nimport {\n  connectSelectMachine,\n  setupSelectMachine,\n  type WeappSelectApi,\n  type WeappSelectService,\n} from './use-select'\n\ntype SelectItemRecord = Record<string, object>\ntype SelectCollection = ReturnType<typeof selectCollection<SelectItemRecord>>\n\ntype WeappSelectInternal = WechatMiniprogram.Component.InstanceMethods<{}> & {\n  _collection: SelectCollection\n  _service?: WeappSelectService\n  _cleanup?: () => void\n  _send?: (event: object) => void\n  data: {\n    api: WeappSelectApi\n  }\n  properties: {\n    id: string\n    items: SelectItemRecord[]\n    itemLabelKey: string\n    itemValueKey: string\n    value: string[]\n    name: string\n    disabled: boolean\n    extClass: string\n  }\n}\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    id: { type: String, value: 'select' },\n    items: { type: Array, value: [] },\n    itemLabelKey: { type: String, value: 'label' },\n    itemValueKey: { type: String, value: 'value' },\n    value: { type: Array, value: [] },\n    name: { type: String, value: '' },\n    placeholder: { type: String, value: 'Select an item' },\n    disabled: { type: Boolean, value: false },\n    label: { type: String, value: '' },\n    extClass: { type: String, value: '' },\n  },\n\n  data: {\n    api: {} as WeappSelectApi,\n    className: '',\n  },\n\n  lifetimes: {\n    attached() {\n      const self = this as WeappSelectInternal\n      this.setData({ className: this.properties.extClass })\n      self._collection = createCollection({\n        items: this.properties.items,\n        itemLabelKey: self.properties.itemLabelKey,\n        itemValueKey: self.properties.itemValueKey,\n        factory: selectCollection,\n      })\n\n      const { service, cleanup, send } = setupSelectMachine(this, {\n        id: this.properties.id || createScopedMachineId('select'),\n        collection: self._collection,\n        value: this.properties.value,\n        name: this.properties.name,\n        disabled: this.properties.disabled,\n        onValueChange: (details) => {\n          emitTimEvent(this, 'change', 'change', this.properties.id || 'select', {\n            value: details.value,\n          })\n        },\n      })\n\n      self._service = service\n      self._cleanup = cleanup\n      self._send = send\n    },\n    detached() {\n      const self = this as WeappSelectInternal\n      self._cleanup?.()\n    },\n  },\n\n  observers: {\n    state: function (state) {\n      const self = this as WeappSelectInternal\n      if (!state || !self._send) return\n      const api = connectSelectMachine(state, self._send)\n      this.setData({ api })\n    },\n    items: function (items) {\n      const self = this as WeappSelectInternal\n      if (self._service) {\n        self._collection = createCollection({\n          items: items as SelectItemRecord[],\n          itemLabelKey: self.properties.itemLabelKey,\n          itemValueKey: self.properties.itemValueKey,\n          factory: selectCollection as (items: object[]) => ListCollection<SelectItemRecord>,\n        })\n        self._service.setContext({ collection: self._collection as Record<string, object> })\n      }\n    },\n    value: function (val) {\n      const self = this as WeappSelectInternal\n      if (self._service) {\n        self._service.setContext({ value: val as Record<string, object> })\n      }\n    },\n  },\n\n  methods: {\n    onTriggerTap() {\n      const self = this as WeappSelectInternal\n      self.data.api.triggerProps?.onClick?.()\n    },\n    onItemTap(e: WechatMiniprogram.BaseEvent) {\n      const self = this as WeappSelectInternal\n      const value = String(e.mark?.value || '')\n      const item = self._collection.find(value)\n      if (item && self.data.api.selectValue) {\n        self.data.api.selectValue(value)\n        self.data.api.setOpen?.(false)\n      }\n    },\n    onBackdropTap() {\n      const self = this as WeappSelectInternal\n      self.data.api.setOpen?.(false)\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/select.json",
          "target": "components/ui/select.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/select-content/select-content.wxml",
          "target": "components/ui/select-content/select-content.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\" data-slot=\"select-content\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/select-content/select-content.wxss",
          "target": "components/ui/select-content/select-content.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/select-content/select-content.json",
          "target": "components/ui/select-content/select-content.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/select-content/select-content.ts",
          "target": "components/ui/select-content/select-content.ts",
          "type": "registry:component",
          "content": "Component({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n  data: {\n    className: '',\n  },\n  lifetimes: {\n    attached() {\n      this.setData({\n        className:\n          `relative z-50 min-w-32 overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md ${this.properties.extClass}`.trim(),\n      })\n    },\n  },\n  observers: {\n    extClass(extClass) {\n      this.setData({\n        className:\n          `relative z-50 min-w-32 overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md ${extClass}`.trim(),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/select-group/select-group.wxml",
          "target": "components/ui/select-group/select-group.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\" data-slot=\"select-group\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/select-group/select-group.wxss",
          "target": "components/ui/select-group/select-group.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/select-group/select-group.json",
          "target": "components/ui/select-group/select-group.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/select-group/select-group.ts",
          "target": "components/ui/select-group/select-group.ts",
          "type": "registry:component",
          "content": "Component({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n  data: {\n    className: '',\n  },\n  lifetimes: {\n    attached() {\n      this.setData({\n        className: this.properties.extClass || '',\n      })\n    },\n  },\n  observers: {\n    extClass(extClass) {\n      this.setData({\n        className: extClass || '',\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/select-item/select-item.wxml",
          "target": "components/ui/select-item/select-item.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\" data-slot=\"select-item\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/select-item/select-item.wxss",
          "target": "components/ui/select-item/select-item.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/select-item/select-item.json",
          "target": "components/ui/select-item/select-item.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/select-item/select-item.ts",
          "target": "components/ui/select-item/select-item.ts",
          "type": "registry:component",
          "content": "Component({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: {\n      type: String,\n      value: '',\n    },\n    disabled: {\n      type: Boolean,\n      value: false,\n    },\n  },\n  data: {\n    className: '',\n  },\n  lifetimes: {\n    attached() {\n      this.setData({\n        className:\n          `relative flex w-full items-center rounded-sm py-3 pl-8 pr-2 text-sm ${this.properties.extClass}`.trim(),\n      })\n    },\n  },\n  observers: {\n    extClass(extClass) {\n      this.setData({\n        className:\n          `relative flex w-full items-center rounded-sm py-3 pl-8 pr-2 text-sm ${extClass}`.trim(),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/select-label/select-label.wxml",
          "target": "components/ui/select-label/select-label.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\" data-slot=\"select-label\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/select-label/select-label.wxss",
          "target": "components/ui/select-label/select-label.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/select-label/select-label.json",
          "target": "components/ui/select-label/select-label.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/select-label/select-label.ts",
          "target": "components/ui/select-label/select-label.ts",
          "type": "registry:component",
          "content": "Component({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n  data: {\n    className: '',\n  },\n  lifetimes: {\n    attached() {\n      this.setData({\n        className: `py-1.5 pl-8 pr-2 text-sm font-semibold ${this.properties.extClass}`.trim(),\n      })\n    },\n  },\n  observers: {\n    extClass(extClass) {\n      this.setData({\n        className: `py-1.5 pl-8 pr-2 text-sm font-semibold ${extClass}`.trim(),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/select-native/select-native.wxml",
          "target": "components/ui/select-native/select-native.wxml",
          "type": "registry:component",
          "content": "<picker range=\"{{options}}\" value=\"{{value}}\" bindchange=\"handleChange\">\n  <view class=\"{{className}}\" data-slot=\"select-native\">\n    {{displayText}}\n  </view>\n</picker>\n"
        },
        {
          "path": "registry/default/weapp/select-native/select-native.wxss",
          "target": "components/ui/select-native/select-native.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/select-native/select-native.json",
          "target": "components/ui/select-native/select-native.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/select-native/select-native.ts",
          "target": "components/ui/select-native/select-native.ts",
          "type": "registry:component",
          "content": "import { emitTimEvent } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    options: {\n      type: Array,\n      value: [],\n    },\n    value: {\n      type: Number,\n      value: 0,\n    },\n    id: {\n      type: String,\n      value: 'select-native',\n    },\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n  data: {\n    className: '',\n    displayText: '',\n  },\n  lifetimes: {\n    attached() {\n      this.updateDisplay()\n      this.setData({\n        className:\n          `border-input text-foreground focus-visible:border-ring focus-visible:ring-ring/50 inline-flex w-full cursor-pointer appearance-none items-center rounded-md border bg-background px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] ${this.properties.extClass}`.trim(),\n      })\n    },\n  },\n  observers: {\n    'options, value, extClass': function () {\n      this.updateDisplay()\n      this.setData({\n        className:\n          `border-input text-foreground focus-visible:border-ring focus-visible:ring-ring/50 inline-flex w-full cursor-pointer appearance-none items-center rounded-md border bg-background px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] ${this.properties.extClass}`.trim(),\n      })\n    },\n  },\n  methods: {\n    updateDisplay() {\n      const options = this.properties.options || []\n      const value = this.properties.value || 0\n      const displayText = options[value] || ''\n      this.setData({ displayText })\n    },\n    handleChange(e: WechatMiniprogram.CustomEvent<{ value: string }>) {\n      const value = Number(e.detail.value)\n      emitTimEvent(this, 'change', 'change', this.properties.id || 'select-native', {\n        value,\n      })\n      this.setData({ displayText: (this.properties.options || [])[value] || '' })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/select-scroll-down-button/select-scroll-down-button.wxml",
          "target": "components/ui/select-scroll-down-button/select-scroll-down-button.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\" data-slot=\"select-scroll-down-button\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/select-scroll-down-button/select-scroll-down-button.wxss",
          "target": "components/ui/select-scroll-down-button/select-scroll-down-button.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/select-scroll-down-button/select-scroll-down-button.json",
          "target": "components/ui/select-scroll-down-button/select-scroll-down-button.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/select-scroll-down-button/select-scroll-down-button.ts",
          "target": "components/ui/select-scroll-down-button/select-scroll-down-button.ts",
          "type": "registry:component",
          "content": "Component({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n  data: {\n    className: '',\n  },\n  lifetimes: {\n    attached() {\n      this.setData({\n        className: `flex items-center justify-center py-1 ${this.properties.extClass}`.trim(),\n      })\n    },\n  },\n  observers: {\n    extClass(extClass) {\n      this.setData({\n        className: `flex items-center justify-center py-1 ${extClass}`.trim(),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/select-scroll-up-button/select-scroll-up-button.wxml",
          "target": "components/ui/select-scroll-up-button/select-scroll-up-button.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\" data-slot=\"select-scroll-up-button\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/select-scroll-up-button/select-scroll-up-button.wxss",
          "target": "components/ui/select-scroll-up-button/select-scroll-up-button.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/select-scroll-up-button/select-scroll-up-button.json",
          "target": "components/ui/select-scroll-up-button/select-scroll-up-button.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/select-scroll-up-button/select-scroll-up-button.ts",
          "target": "components/ui/select-scroll-up-button/select-scroll-up-button.ts",
          "type": "registry:component",
          "content": "Component({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n  data: {\n    className: '',\n  },\n  lifetimes: {\n    attached() {\n      this.setData({\n        className: `flex items-center justify-center py-1 ${this.properties.extClass}`.trim(),\n      })\n    },\n  },\n  observers: {\n    extClass(extClass) {\n      this.setData({\n        className: `flex items-center justify-center py-1 ${extClass}`.trim(),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/select-separator/select-separator.wxml",
          "target": "components/ui/select-separator/select-separator.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\" data-slot=\"select-separator\"></view>\n"
        },
        {
          "path": "registry/default/weapp/select-separator/select-separator.wxss",
          "target": "components/ui/select-separator/select-separator.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/select-separator/select-separator.json",
          "target": "components/ui/select-separator/select-separator.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/select-separator/select-separator.ts",
          "target": "components/ui/select-separator/select-separator.ts",
          "type": "registry:component",
          "content": "Component({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n  data: {\n    className: '',\n  },\n  lifetimes: {\n    attached() {\n      this.setData({\n        className: `-mx-1 my-1 h-px bg-muted ${this.properties.extClass}`.trim(),\n      })\n    },\n  },\n  observers: {\n    extClass(extClass) {\n      this.setData({\n        className: `-mx-1 my-1 h-px bg-muted ${extClass}`.trim(),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/select-trigger/select-trigger.wxml",
          "target": "components/ui/select-trigger/select-trigger.wxml",
          "type": "registry:component",
          "content": "<button class=\"{{className}}\" data-slot=\"select-trigger\">\n  <slot></slot>\n</button>\n"
        },
        {
          "path": "registry/default/weapp/select-trigger/select-trigger.wxss",
          "target": "components/ui/select-trigger/select-trigger.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/select-trigger/select-trigger.json",
          "target": "components/ui/select-trigger/select-trigger.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/select-trigger/select-trigger.ts",
          "target": "components/ui/select-trigger/select-trigger.ts",
          "type": "registry:component",
          "content": "Component({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n  data: {\n    className: '',\n  },\n  lifetimes: {\n    attached() {\n      this.setData({\n        className:\n          `flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ${this.properties.extClass}`.trim(),\n      })\n    },\n  },\n  observers: {\n    extClass(extClass) {\n      this.setData({\n        className:\n          `flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ${extClass}`.trim(),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/select-value/select-value.wxml",
          "target": "components/ui/select-value/select-value.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\" data-slot=\"select-value\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/select-value/select-value.wxss",
          "target": "components/ui/select-value/select-value.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/select-value/select-value.json",
          "target": "components/ui/select-value/select-value.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/select-value/select-value.ts",
          "target": "components/ui/select-value/select-value.ts",
          "type": "registry:component",
          "content": "Component({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n  data: {\n    className: '',\n  },\n  lifetimes: {\n    attached() {\n      this.setData({\n        className: `line-clamp-1 ${this.properties.extClass}`.trim(),\n      })\n    },\n  },\n  observers: {\n    extClass(extClass) {\n      this.setData({\n        className: `line-clamp-1 ${extClass}`.trim(),\n      })\n    },\n  },\n})\n"
        }
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@zag-js/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@zag-js/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {
            "dependencies": [
              "@timui/core"
            ]
          },
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "slider",
      "type": "registry:ui",
      "dependencies": [
        "@timui/core",
        "@zag-js/react"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/tooltip.json",
        "use-machine"
      ],
      "files": [
        {
          "path": "registry/default/ui/slider.tsx",
          "type": "registry:ui",
          "target": "components/ui/slider.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport type { SliderProps as CoreSliderProps } from '@timui/core'\nimport {\n  cn,\n  sliderRangeVariants,\n  sliderRootVariants,\n  sliderThumbVariants,\n  sliderTrackVariants,\n} from '@timui/core'\nimport { mergeProps } from '@zag-js/react'\n\nimport { useSlider } from './slider/use-slider'\n\ntype SliderProps = CoreSliderProps &\n  Omit<React.HTMLAttributes<HTMLDivElement>, keyof CoreSliderProps>\n\nconst Slider = React.forwardRef<HTMLDivElement, SliderProps>(\n  (\n    {\n      className,\n      value,\n      defaultValue,\n      min = 0,\n      max = 100,\n      step = 1,\n      minStepsBetweenThumbs,\n      origin,\n      thumbAlignment,\n      thumbSize,\n      thumbCollisionBehavior,\n      name,\n      form,\n      dir,\n      readOnly,\n      invalid,\n      getAriaValueText,\n      onFocusChange,\n      orientation = 'horizontal',\n      ['aria-label']: ariaLabel,\n      ['aria-labelledby']: ariaLabelledBy,\n      ids,\n      showTooltip = false,\n      tooltipContent,\n      onValueChange,\n      onValueChangeEnd,\n      disabled,\n      id,\n      ...props\n    },\n    ref\n  ) => {\n    const api = useSlider({\n      id,\n      value,\n      defaultValue,\n      min,\n      max,\n      step,\n      minStepsBetweenThumbs,\n      orientation,\n      origin,\n      thumbAlignment,\n      thumbSize,\n      thumbCollisionBehavior,\n      name,\n      form,\n      dir,\n      readOnly,\n      invalid,\n      getAriaValueText,\n      onFocusChange,\n      'aria-label': ariaLabel,\n      'aria-labelledby': ariaLabelledBy,\n      ids,\n      disabled,\n      onValueChange,\n      onValueChangeEnd,\n    })\n    const rootProps = api.getRootProps()\n    const controlProps = api.getControlProps()\n    const trackProps = api.getTrackProps()\n    const rangeProps = api.getRangeProps()\n    const mergedRootProps = mergeProps(\n      rootProps,\n      props as React.HTMLAttributes<HTMLDivElement>\n    ) as React.HTMLAttributes<HTMLDivElement>\n    const { className: rootClassName, ...rootRest } = mergedRootProps as {\n      className?: string\n    }\n\n    return (\n      <div\n        {...(rootRest as React.HTMLAttributes<HTMLDivElement>)}\n        ref={ref}\n        data-slot=\"slider\"\n        className={cn(sliderRootVariants(), rootClassName, className)}\n      >\n        <div\n          {...controlProps}\n          data-slot=\"slider-control\"\n          className={cn(\n            'relative flex w-full touch-none items-center select-none data-[orientation=vertical]:h-full data-[orientation=vertical]:min-h-44 data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col',\n            controlProps.className\n          )}\n        >\n          <div\n            {...trackProps}\n            data-slot=\"slider-track\"\n            className={cn(sliderTrackVariants(), trackProps.className)}\n          >\n            <div\n              {...rangeProps}\n              data-slot=\"slider-range\"\n              className={cn(sliderRangeVariants(), rangeProps.className)}\n            />\n          </div>\n          {api.value.map((_, index) => {\n            const thumbProps = api.getThumbProps({ index })\n            const hiddenInputProps = api.getHiddenInputProps({ index })\n            const thumbValue = api.value[index] ?? min\n            const tooltipText = tooltipContent?.(thumbValue) ?? `${thumbValue}`\n            return (\n              <React.Fragment key={index}>\n                <div\n                  {...thumbProps}\n                  data-slot=\"slider-thumb\"\n                  className={cn(sliderThumbVariants(), thumbProps.className)}\n                >\n                  {showTooltip ? (\n                    <span\n                      className={cn(\n                        'bg-foreground text-background pointer-events-none absolute z-10 inline-flex min-w-6 items-center justify-center rounded px-1.5 py-0.5 text-[11px] leading-none font-medium whitespace-nowrap shadow-sm',\n                        orientation === 'vertical'\n                          ? 'top-1/2 left-full ml-2 -translate-y-1/2'\n                          : '-top-8 left-1/2 -translate-x-1/2'\n                      )}\n                    >\n                      {tooltipText}\n                    </span>\n                  ) : null}\n                </div>\n                <input {...hiddenInputProps} />\n              </React.Fragment>\n            )\n          })}\n        </div>\n      </div>\n    )\n  }\n)\nSlider.displayName = 'Slider'\n\nexport { Slider }\n"
        },
        {
          "path": "registry/default/vue/slider.vue",
          "type": "registry:ui",
          "target": "components/ui/slider.vue",
          "content": "<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport type { AssertNoExtraKeys, SliderVueProps } from '@timui/core'\nimport {\n  cn,\n  sliderRangeVariants,\n  sliderRootVariants,\n  sliderThumbVariants,\n  sliderTrackVariants,\n} from '@timui/core'\nimport type { HTMLAttributes } from 'vue'\n\nimport { useSlider } from './use-slider'\n\ntype SliderProps = SliderVueProps & { class?: HTMLAttributes['class'] }\ntype _SliderPropsGuard = AssertNoExtraKeys<SliderProps, SliderProps>\n\nconst props = defineProps<SliderProps>()\n\nconst emit = defineEmits(['update:modelValue', 'change', 'commit'])\n\nconst api = useSlider(props, emit)\nconst rootProps = computed(() => api.value?.getRootProps?.() ?? {})\nconst controlProps = computed(() => api.value?.getControlProps?.() ?? {})\nconst trackProps = computed(() => api.value?.getTrackProps?.() ?? {})\nconst rangeProps = computed(() => api.value?.getRangeProps?.() ?? {})\n\nconst getThumbProps = (index: number) =>\n  api.value?.getThumbProps?.({ index }) ?? {}\nconst getHiddenInputProps = (index: number) =>\n  api.value?.getHiddenInputProps?.({ index }) ?? {}\n\nconst thumbPropsList = computed(() =>\n  (api.value?.value ?? []).map((_, index) => getThumbProps(index))\n)\nconst hiddenInputPropsList = computed(() =>\n  (api.value?.value ?? []).map((_, index) => getHiddenInputProps(index))\n)\nconst isVertical = computed(() => (props.orientation ?? 'horizontal') === 'vertical')\n\nfunction getTooltipValue(index: number) {\n  return api.value?.value?.[index] ?? props.min ?? 0\n}\n\nfunction getTooltipText(index: number) {\n  const value = getTooltipValue(index)\n  return props.tooltipContent ? props.tooltipContent(value) : `${value}`\n}\n</script>\n\n<template>\n  <div\n    v-bind=\"rootProps\"\n    data-slot=\"slider\"\n    :class=\"cn(sliderRootVariants(), props.class)\"\n  >\n    <div\n      v-bind=\"controlProps\"\n      data-slot=\"slider-control\"\n      :class=\"\n        cn(\n          'relative flex w-full touch-none items-center select-none data-[orientation=vertical]:h-full data-[orientation=vertical]:min-h-44 data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col',\n          controlProps.class\n        )\n      \"\n    >\n      <div\n        v-bind=\"trackProps\"\n        data-slot=\"slider-track\"\n        :class=\"cn(sliderTrackVariants(), trackProps.class)\"\n      >\n        <div\n          v-bind=\"rangeProps\"\n          data-slot=\"slider-range\"\n          :class=\"cn(sliderRangeVariants(), rangeProps.class)\"\n        />\n      </div>\n      <template v-for=\"(thumbProps, index) in thumbPropsList\" :key=\"index\">\n        <div\n          v-bind=\"thumbProps\"\n          data-slot=\"slider-thumb\"\n          :class=\"cn(sliderThumbVariants(), thumbProps.class)\"\n        >\n          <span\n            v-if=\"props.showTooltip\"\n            :class=\"\n              cn(\n                'bg-foreground text-background pointer-events-none absolute z-10 inline-flex min-w-6 items-center justify-center rounded px-1.5 py-0.5 text-[11px] leading-none font-medium whitespace-nowrap shadow-sm',\n                isVertical\n                  ? 'top-1/2 left-full ml-2 -translate-y-1/2'\n                  : '-top-8 left-1/2 -translate-x-1/2'\n              )\n            \"\n          >\n            {{ getTooltipText(index) }}\n          </span>\n        </div>\n        <input v-bind=\"hiddenInputPropsList[index] ?? {}\" />\n      </template>\n    </div>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/ui/slider/use-slider.ts",
          "target": "components/ui/slider/use-slider.ts",
          "type": "registry:ui",
          "content": "import * as React from 'react'\nimport type { SliderProps as CoreSliderProps } from '@timui/core'\nimport { createTimEvent, sliderConnect, sliderMachine } from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/react'\n\nexport interface UseSliderProps extends Omit<CoreSliderProps, 'id'> {\n  id?: string\n}\n\nexport function useSlider(props: UseSliderProps) {\n  const generatedId = React.useId()\n  const sliderId = props.id ?? generatedId\n  const {\n    id: _id,\n    onValueChange,\n    onValueChangeEnd,\n    showTooltip: _showTooltip,\n    tooltipContent: _tooltipContent,\n    min,\n    max,\n    step,\n    ...machineProps\n  } = props\n  void _id\n  void _showTooltip\n  void _tooltipContent\n\n  const service = useMachine(sliderMachine, {\n    ...machineProps,\n    id: sliderId,\n    min: min ?? 0,\n    max: max ?? 100,\n    step: step ?? 1,\n    onValueChange(details) {\n      const event = createTimEvent('change', sliderId, {\n        value: details.value,\n      }) as never as Parameters<NonNullable<CoreSliderProps['onValueChange']>>[0]\n      onValueChange?.(event)\n    },\n    onValueChangeEnd(details) {\n      const event = createTimEvent('change-end', sliderId, {\n        value: details.value,\n      }) as never as Parameters<NonNullable<CoreSliderProps['onValueChangeEnd']>>[0]\n      onValueChangeEnd?.(event)\n    },\n  })\n\n  const api = React.useMemo(() => sliderConnect(service, normalizeProps), [service])\n\n  return api\n}\n"
        },
        {
          "path": "registry/default/vue/slider/slider.vue",
          "target": "components/ui/slider/slider.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport type { AssertNoExtraKeys, SliderVueProps } from '@timui/core'\nimport {\n  cn,\n  sliderRangeVariants,\n  sliderRootVariants,\n  sliderThumbVariants,\n  sliderTrackVariants,\n} from '@timui/core'\nimport type { HTMLAttributes } from 'vue'\n\nimport { useSlider } from './use-slider'\n\ntype SliderProps = SliderVueProps & { class?: HTMLAttributes['class'] }\ntype _SliderPropsGuard = AssertNoExtraKeys<SliderProps, SliderProps>\n\nconst props = defineProps<SliderProps>()\n\nconst emit = defineEmits(['update:modelValue', 'change', 'commit'])\n\nconst api = useSlider(props, emit)\nconst rootProps = computed(() => api.value?.getRootProps?.() ?? {})\nconst controlProps = computed(() => api.value?.getControlProps?.() ?? {})\nconst trackProps = computed(() => api.value?.getTrackProps?.() ?? {})\nconst rangeProps = computed(() => api.value?.getRangeProps?.() ?? {})\n\nconst getThumbProps = (index: number) =>\n  api.value?.getThumbProps?.({ index }) ?? {}\nconst getHiddenInputProps = (index: number) =>\n  api.value?.getHiddenInputProps?.({ index }) ?? {}\n\nconst thumbPropsList = computed(() =>\n  (api.value?.value ?? []).map((_, index) => getThumbProps(index))\n)\nconst hiddenInputPropsList = computed(() =>\n  (api.value?.value ?? []).map((_, index) => getHiddenInputProps(index))\n)\nconst isVertical = computed(() => (props.orientation ?? 'horizontal') === 'vertical')\n\nfunction getTooltipValue(index: number) {\n  return api.value?.value?.[index] ?? props.min ?? 0\n}\n\nfunction getTooltipText(index: number) {\n  const value = getTooltipValue(index)\n  return props.tooltipContent ? props.tooltipContent(value) : `${value}`\n}\n</script>\n\n<template>\n  <div\n    v-bind=\"rootProps\"\n    data-slot=\"slider\"\n    :class=\"cn(sliderRootVariants(), props.class)\"\n  >\n    <div\n      v-bind=\"controlProps\"\n      data-slot=\"slider-control\"\n      :class=\"\n        cn(\n          'relative flex w-full touch-none items-center select-none data-[orientation=vertical]:h-full data-[orientation=vertical]:min-h-44 data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col',\n          controlProps.class\n        )\n      \"\n    >\n      <div\n        v-bind=\"trackProps\"\n        data-slot=\"slider-track\"\n        :class=\"cn(sliderTrackVariants(), trackProps.class)\"\n      >\n        <div\n          v-bind=\"rangeProps\"\n          data-slot=\"slider-range\"\n          :class=\"cn(sliderRangeVariants(), rangeProps.class)\"\n        />\n      </div>\n      <template v-for=\"(thumbProps, index) in thumbPropsList\" :key=\"index\">\n        <div\n          v-bind=\"thumbProps\"\n          data-slot=\"slider-thumb\"\n          :class=\"cn(sliderThumbVariants(), thumbProps.class)\"\n        >\n          <span\n            v-if=\"props.showTooltip\"\n            :class=\"\n              cn(\n                'bg-foreground text-background pointer-events-none absolute z-10 inline-flex min-w-6 items-center justify-center rounded px-1.5 py-0.5 text-[11px] leading-none font-medium whitespace-nowrap shadow-sm',\n                isVertical\n                  ? 'top-1/2 left-full ml-2 -translate-y-1/2'\n                  : '-top-8 left-1/2 -translate-x-1/2'\n              )\n            \"\n          >\n            {{ getTooltipText(index) }}\n          </span>\n        </div>\n        <input v-bind=\"hiddenInputPropsList[index] ?? {}\" />\n      </template>\n    </div>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/slider/use-slider.ts",
          "target": "components/ui/slider/use-slider.ts",
          "type": "registry:component",
          "content": "import { sliderConnect, sliderMachine } from '@timui/core'\nimport type { SliderVueProps } from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/vue'\nimport { computed, useId } from 'vue'\n\ntype SliderEmits = {\n  (event: 'update:modelValue', value: number[]): void\n  (event: 'change', value: number[]): void\n  (event: 'commit', value: number[]): void\n}\n\nexport function useSlider(props: SliderVueProps, emit: SliderEmits) {\n  const generatedId = useId()\n\n  const machineProps = computed(() => {\n    const controlledValue = props.modelValue ?? props.value\n    return {\n      id: props.id ?? generatedId,\n      ids: props.ids,\n      dir: props.dir,\n      'aria-label': props['aria-label'],\n      'aria-labelledby': props['aria-labelledby'],\n      name: props.name,\n      form: props.form,\n      value: controlledValue,\n      defaultValue:\n        props.modelValue === undefined && props.value === undefined ? props.defaultValue : undefined,\n      min: props.min ?? 0,\n      max: props.max ?? 100,\n      step: props.step ?? 1,\n      onValueChange(details: { value: number[] }) {\n        props.onValueChange?.(details.value)\n        emit('update:modelValue', details.value)\n        emit('change', details.value)\n      },\n      onValueChangeEnd(details: { value: number[] }) {\n        props.onValueChangeEnd?.(details.value)\n        emit('commit', details.value)\n      },\n      onFocusChange: props.onFocusChange,\n      getAriaValueText: props.getAriaValueText,\n      disabled: props.disabled,\n      readOnly: props.readOnly,\n      invalid: props.invalid,\n      minStepsBetweenThumbs: props.minStepsBetweenThumbs,\n      orientation: props.orientation,\n      origin: props.origin,\n      thumbAlignment: props.thumbAlignment,\n      thumbSize: props.thumbSize,\n      thumbCollisionBehavior: props.thumbCollisionBehavior,\n    }\n  })\n\n  const service = useMachine(sliderMachine, machineProps)\n  const api = computed(() => sliderConnect(service, normalizeProps))\n\n  return api\n}\n"
        },
        {
          "path": "registry/default/html/slider.html",
          "target": "components/ui/slider.html",
          "type": "registry:component",
          "content": "<div class=\"relative flex w-full touch-none items-center select-none data-[disabled]:opacity-50 data-[orientation&#x3D;vertical]:h-full data-[orientation&#x3D;vertical]:min-h-44 data-[orientation&#x3D;vertical]:w-auto data-[orientation&#x3D;vertical]:flex-col\">\n    <span class=\"relative h-2 w-full overflow-hidden rounded-full bg-secondary\">\n        <span class=\"absolute h-full bg-primary\" style=\"left: 0%; width: 50%;\"></span>\n    </span>\n    <span\n        class=\"mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n        style=\"left: 50%; transform: translateX(-50%);\"></span>\n</div>"
        },
        {
          "path": "registry/default/weapp/slider.wxml",
          "target": "components/ui/slider.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{rootClass}}\">\n  <slider\n    min=\"{{min}}\"\n    max=\"{{max}}\"\n    value=\"{{value}}\"\n    step=\"{{step}}\"\n    disabled=\"{{disabled}}\"\n    show-value=\"{{showValue}}\"\n    activeColor=\"{{activeColor}}\"\n    backgroundColor=\"{{backgroundColor}}\"\n    block-size=\"{{blockSize}}\"\n    block-color=\"{{blockColor}}\"\n    name=\"{{name}}\"\n    bindchange=\"onSliderChange\"\n    bindchanging=\"onSliderChanging\"\n  />\n</view>\n"
        },
        {
          "path": "registry/default/weapp/slider.wxss",
          "target": "components/ui/slider.wxss",
          "type": "registry:component",
          "content": "/* packages/weapp/src/slider/slider.wxss */\n"
        },
        {
          "path": "registry/default/weapp/slider.ts",
          "target": "components/ui/slider.ts",
          "type": "registry:component",
          "content": "import { emitTimEvent, resolveClasses, sliderRootVariants } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    id: { type: String, value: 'slider' },\n    value: { type: Number, value: 0 },\n    min: { type: Number, value: 0 },\n    max: { type: Number, value: 100 },\n    step: { type: Number, value: 1 },\n    disabled: { type: Boolean, value: false },\n    showValue: { type: Boolean, value: false },\n    activeColor: { type: String, value: '#1aad19' },\n    backgroundColor: { type: String, value: '#e9e9e9' },\n    blockSize: { type: Number, value: 28 },\n    blockColor: { type: String, value: '#ffffff' },\n    name: { type: String, value: '' },\n    extClass: { type: String, value: '' },\n  },\n\n  data: {\n    rootClass: '',\n  },\n\n  lifetimes: {\n    attached() {\n      this.updateClassName()\n    },\n  },\n\n  observers: {\n    extClass: function () {\n      this.updateClassName()\n    },\n  },\n\n  methods: {\n    updateClassName() {\n      const rootClass = resolveClasses(sliderRootVariants(), this.properties.extClass)\n      this.setData({ rootClass })\n    },\n\n    onSliderChange(e: WechatMiniprogram.CustomEvent) {\n      emitTimEvent(this, 'change-end', 'change-end', this.properties.id || 'slider', {\n        value: [Number(e.detail.value ?? 0)],\n      })\n    },\n\n    onSliderChanging(e: WechatMiniprogram.CustomEvent) {\n      this.triggerEvent('changing', { value: e.detail.value })\n      emitTimEvent(this, 'change', 'change', this.properties.id || 'slider', {\n        value: [Number(e.detail.value ?? 0)],\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/slider.json",
          "target": "components/ui/slider.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        }
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@zag-js/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@zag-js/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "sonner",
      "type": "registry:ui",
      "dependencies": [
        "sonner",
        "next-themes"
      ],
      "optionalPeerDependencies": [
        "next-themes",
        "sonner"
      ],
      "files": [
        {
          "path": "registry/default/ui/sonner.tsx",
          "type": "registry:ui",
          "target": "components/ui/sonner.tsx",
          "content": "'use client'\nimport { useTheme } from 'next-themes'\nimport { Toaster as Sonner, ToasterProps } from 'sonner'\n\nconst SonnerToaster = ({ ...props }: ToasterProps) => {\n  const { theme = 'system' } = useTheme()\n\n  return (\n    <Sonner\n      theme={theme as ToasterProps['theme']}\n      className=\"toaster group\"\n      style={\n        {\n          '--normal-bg': 'var(--popover)',\n          '--normal-text': 'var(--popover-foreground)',\n          '--normal-border': 'var(--border)',\n        } as React.CSSProperties\n      }\n      toastOptions={{\n        classNames: {\n          description: 'text-muted-foreground!',\n        },\n      }}\n      {...props}\n    />\n  )\n}\n\nexport { SonnerToaster }\n"
        },
        {
          "path": "registry/default/vue/sonner.vue",
          "target": "components/ui/sonner.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Toaster as Sonner, type ToasterProps } from \"vue-sonner\";\n\nconst props = defineProps<ToasterProps>();\n</script>\n\n<template>\n  <Sonner\n    class=\"toaster group\"\n    v-bind=\"props\"\n    :toast-options=\"{\n      classes: {\n        toast:\n          'group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg',\n        description: 'group-[.toast]:text-muted-foreground',\n        actionButton:\n          'group-[.toast]:bg-primary group-[.toast]:text-primary-foreground',\n        cancelButton:\n          'group-[.toast]:bg-muted group-[.toast]:text-muted-foreground',\n      },\n    }\"\n  />\n</template>\n"
        }
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue"
        ],
        "dependenciesByFramework": {
          "react": {
            "optionalPeerDependencies": [
              "next-themes",
              "sonner"
            ]
          },
          "vue": {
            "optionalPeerDependencies": [
              "vue-sonner"
            ]
          }
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "stepper",
      "type": "registry:ui",
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/ui/stepper.tsx",
          "type": "registry:ui",
          "target": "components/ui/stepper.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport { createContext, useContext } from 'react'\nimport type { AssertNoExtraKeys, StepperProps as CoreStepperProps } from '@timui/core'\nimport {\n  cn,\n  createTimEvent,\n  stepperConnect,\n  stepperDescriptionVariants,\n  stepperIndicatorCheckVariants,\n  stepperIndicatorLabelVariants,\n  stepperIndicatorLoaderVariants,\n  stepperIndicatorVariants,\n  stepperItemVariants,\n  stepperMachine,\n  stepperSeparatorVariants,\n  stepperTitleVariants,\n  stepperTriggerVariants,\n  stepperVariants,\n} from '@timui/core'\nimport type { Machine as ZagMachine, MachineSchema as ZagMachineSchema } from '@zag-js/core'\nimport type { Machine as NumberInputMachine } from '@zag-js/number-input'\nimport { mergeProps, normalizeProps, useMachine } from '@zag-js/react'\nimport { CheckIcon, LoaderCircleIcon } from 'lucide-react'\n\nimport { Slot } from './slot'\n\n// Types\ntype StepperContextValue = {\n  api: ReturnType<typeof stepperConnect>\n  activeStep: number\n  setActiveStep: (step: number) => void\n  orientation: 'horizontal' | 'vertical'\n}\n\ntype StepItemContextValue = {\n  step: number\n  state: StepState\n  isDisabled: boolean\n  isLoading: boolean\n}\n\ntype StepState = 'active' | 'completed' | 'inactive' | 'loading'\ntype InferMachineSchema<T> = T extends ZagMachine<infer S> ? S : ZagMachineSchema\ntype NumberInputSchema = InferMachineSchema<NumberInputMachine>\n\n// Contexts\nconst StepperContext = createContext<StepperContextValue | undefined>(undefined)\nconst StepItemContext = createContext<StepItemContextValue | undefined>(undefined)\n\nconst useStepper = () => {\n  const context = useContext(StepperContext)\n  if (!context) {\n    throw new Error('useStepper must be used within a Stepper')\n  }\n  return context\n}\n\nconst useStepItem = () => {\n  const context = useContext(StepItemContext)\n  if (!context) {\n    throw new Error('useStepItem must be used within a StepperItem')\n  }\n  return context\n}\n\n// Components\ntype StepperProps = CoreStepperProps & React.HTMLAttributes<HTMLDivElement>\ntype _StepperPropsGuard = AssertNoExtraKeys<\n  StepperProps,\n  CoreStepperProps & React.HTMLAttributes<HTMLDivElement>\n>\n\nfunction Stepper({\n  defaultValue = '0',\n  value,\n  onValueChange,\n  orientation = 'horizontal',\n  className,\n  ...props\n}: StepperProps) {\n  const generatedId = React.useId()\n  const stepperId = props.id ?? generatedId\n  const normalizedValue = typeof value === 'number' ? String(value) : value\n  const normalizedDefaultValue =\n    typeof defaultValue === 'number' ? String(defaultValue) : defaultValue\n\n  const service = useMachine<NumberInputSchema>(stepperMachine, {\n    id: stepperId,\n    value: normalizedValue,\n    defaultValue: normalizedDefaultValue,\n    onValueChange(details: { value: string; valueAsNumber: number }) {\n      onValueChange?.(\n        createTimEvent('change', stepperId, {\n          value: details.value,\n          valueAsNumber: details.valueAsNumber,\n        }) as never as Parameters<NonNullable<CoreStepperProps['onValueChange']>>[0]\n      )\n    },\n  })\n\n  const api = React.useMemo(() => stepperConnect(service, normalizeProps), [service])\n\n  const currentStep = Number.isFinite(api.valueAsNumber) ? api.valueAsNumber : 0\n  const setActiveStep = React.useCallback(\n    (step: number) => {\n      api.setValue(step)\n    },\n    [api]\n  )\n\n  return (\n    <StepperContext.Provider\n      value={{\n        api,\n        activeStep: currentStep,\n        setActiveStep,\n        orientation,\n      }}\n    >\n      <div\n        data-slot=\"stepper\"\n        className={cn(stepperVariants(), className)}\n        data-orientation={orientation}\n        {...(mergeProps(api.getRootProps(), props) as React.HTMLAttributes<HTMLDivElement>)}\n      />\n    </StepperContext.Provider>\n  )\n}\n\n// StepperItem\ninterface StepperItemProps extends React.HTMLAttributes<HTMLDivElement> {\n  step: number\n  completed?: boolean\n  disabled?: boolean\n  loading?: boolean\n}\n\nfunction StepperItem({\n  step,\n  completed = false,\n  disabled = false,\n  loading = false,\n  className,\n  children,\n  ...props\n}: StepperItemProps) {\n  const { activeStep } = useStepper()\n\n  const state: StepState =\n    completed || step < activeStep ? 'completed' : activeStep === step ? 'active' : 'inactive'\n\n  const isLoading = loading && step === activeStep\n\n  return (\n    <StepItemContext.Provider value={{ step, state, isDisabled: disabled, isLoading }}>\n      <div\n        data-slot=\"stepper-item\"\n        className={cn(stepperItemVariants(), className)}\n        data-state={state}\n        {...(isLoading ? { 'data-loading': true } : {})}\n        {...props}\n      >\n        {children}\n      </div>\n    </StepItemContext.Provider>\n  )\n}\n\n// StepperTrigger\ninterface StepperTriggerProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n  asChild?: boolean\n}\n\nfunction StepperTrigger({ asChild = false, className, children, ...props }: StepperTriggerProps) {\n  const { setActiveStep } = useStepper()\n  const { step, isDisabled } = useStepItem()\n\n  if (asChild) {\n    const Comp = asChild ? Slot : 'span'\n    return (\n      <Comp data-slot=\"stepper-trigger\" className={className}>\n        {children}\n      </Comp>\n    )\n  }\n\n  return (\n    <button\n      data-slot=\"stepper-trigger\"\n      className={cn(stepperTriggerVariants(), className)}\n      onClick={() => setActiveStep(step)}\n      disabled={isDisabled}\n      {...props}\n    >\n      {children}\n    </button>\n  )\n}\n\n// StepperIndicator\ninterface StepperIndicatorProps extends React.HTMLAttributes<HTMLDivElement> {\n  asChild?: boolean\n}\n\nfunction StepperIndicator({\n  asChild = false,\n  className,\n  children,\n  ...props\n}: StepperIndicatorProps) {\n  const { state, step, isLoading } = useStepItem()\n\n  return (\n    <span\n      data-slot=\"stepper-indicator\"\n      className={cn(stepperIndicatorVariants(), className)}\n      data-state={state}\n      {...props}\n    >\n      {asChild ? (\n        children\n      ) : (\n        <>\n          <span className={stepperIndicatorLabelVariants()}>{step}</span>\n          <CheckIcon className={stepperIndicatorCheckVariants()} size={16} aria-hidden=\"true\" />\n          {isLoading && (\n            <span className={stepperIndicatorLoaderVariants()}>\n              <LoaderCircleIcon className=\"animate-spin\" size={14} aria-hidden=\"true\" />\n            </span>\n          )}\n        </>\n      )}\n    </span>\n  )\n}\n\n// StepperTitle\nfunction StepperTitle({ className, ...props }: React.HTMLAttributes<HTMLHeadingElement>) {\n  return (\n    <h3 data-slot=\"stepper-title\" className={cn(stepperTitleVariants(), className)} {...props} />\n  )\n}\n\n// StepperDescription\nfunction StepperDescription({ className, ...props }: React.HTMLAttributes<HTMLParagraphElement>) {\n  return (\n    <p\n      data-slot=\"stepper-description\"\n      className={cn(stepperDescriptionVariants(), className)}\n      {...props}\n    />\n  )\n}\n\n// StepperSeparator\nfunction StepperSeparator({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n  return (\n    <div\n      data-slot=\"stepper-separator\"\n      className={cn(stepperSeparatorVariants(), className)}\n      {...props}\n    />\n  )\n}\n\nexport {\n  Stepper,\n  StepperDescription,\n  StepperIndicator,\n  StepperItem,\n  StepperSeparator,\n  StepperTitle,\n  StepperTrigger,\n}\n"
        },
        {
          "path": "registry/default/vue/stepper/stepper-description.vue",
          "target": "components/ui/stepper/stepper-description.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, stepperDescriptionVariants } from '@timui/core'\nimport type { HTMLAttributes } from 'vue'\n\nconst props = defineProps<{\n  class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n  <p\n    data-slot=\"stepper-description\"\n    :class=\"cn(stepperDescriptionVariants(), props.class)\"\n  >\n    <slot />\n  </p>\n</template>\n"
        },
        {
          "path": "registry/default/vue/stepper/stepper-indicator.vue",
          "target": "components/ui/stepper/stepper-indicator.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport {\n  cn,\n  stepperIndicatorCheckVariants,\n  stepperIndicatorLabelVariants,\n  stepperIndicatorLoaderVariants,\n  stepperIndicatorVariants,\n} from '@timui/core'\nimport { useStepItem } from './stepper.vue'\nimport { CheckIcon, LoaderCircleIcon } from 'lucide-vue-next'\nimport type { HTMLAttributes } from 'vue'\nimport { Primitive, type PrimitiveProps } from '../../primitive'\n\nconst props = withDefaults(\n  defineProps<\n    PrimitiveProps & {\n      class?: HTMLAttributes['class']\n    }\n  >(),\n  {\n    as: 'span',\n  }\n)\n\nconst { state, step, isLoading } = useStepItem()\n</script>\n\n<template>\n  <Primitive\n    data-slot=\"stepper-indicator\"\n    :as=\"as\"\n    :as-child=\"asChild\"\n    :class=\"\n      cn(\n        stepperIndicatorVariants(),\n        props.class\n      )\n    \"\n    :data-state=\"state\"\n  >\n    <slot>\n        <span :class=\"stepperIndicatorLabelVariants()\">\n          {{ step }}\n        </span>\n        <CheckIcon\n          :class=\"stepperIndicatorCheckVariants()\"\n          :size=\"16\"\n          aria-hidden=\"true\"\n        />\n        <span v-if=\"isLoading\" :class=\"stepperIndicatorLoaderVariants()\">\n          <LoaderCircleIcon class=\"animate-spin\" :size=\"14\" aria-hidden=\"true\" />\n        </span>\n    </slot>\n  </Primitive>\n</template>\n"
        },
        {
          "path": "registry/default/vue/stepper/stepper-item.vue",
          "target": "components/ui/stepper/stepper-item.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, provide, toRef } from 'vue'\nimport { cn, stepperItemVariants } from '@timui/core'\nimport { useStepper, StepItemContextKey } from './stepper.vue'\nimport type { HTMLAttributes } from 'vue'\n\nconst props = withDefaults(\n  defineProps<{\n    step: number\n    completed?: boolean\n    disabled?: boolean\n    loading?: boolean\n    class?: HTMLAttributes['class']\n  }>(),\n  {\n    completed: false,\n    disabled: false,\n    loading: false,\n  }\n)\n\nconst { activeStep } = useStepper()\n\nconst state = computed(() => {\n  if (props.completed || props.step < activeStep.value) return 'completed'\n  if (activeStep.value === props.step) return 'active'\n  return 'inactive'\n})\n\nconst isLoading = computed(() => props.loading && props.step === activeStep.value)\n\nprovide(StepItemContextKey, {\n  step: props.step,\n  state: state,\n  isDisabled: toRef(props, 'disabled'),\n  isLoading: isLoading,\n})\n</script>\n\n<template>\n  <div\n    data-slot=\"stepper-item\"\n    :class=\"cn(stepperItemVariants(), props.class)\"\n    :data-state=\"state\"\n    :data-loading=\"isLoading ? true : undefined\"\n  >\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/stepper/stepper-separator.vue",
          "target": "components/ui/stepper/stepper-separator.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, stepperSeparatorVariants } from '@timui/core'\nimport type { HTMLAttributes } from 'vue'\n\nconst props = defineProps<{\n  class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n  <div\n    data-slot=\"stepper-separator\"\n    :class=\"cn(stepperSeparatorVariants(), props.class)\"\n  />\n</template>\n"
        },
        {
          "path": "registry/default/vue/stepper/stepper-title.vue",
          "target": "components/ui/stepper/stepper-title.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, stepperTitleVariants } from '@timui/core'\nimport type { HTMLAttributes } from 'vue'\n\nconst props = defineProps<{\n  class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n  <h3 data-slot=\"stepper-title\" :class=\"cn(stepperTitleVariants(), props.class)\">\n    <slot />\n  </h3>\n</template>\n"
        },
        {
          "path": "registry/default/vue/stepper/stepper-trigger.vue",
          "target": "components/ui/stepper/stepper-trigger.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, stepperTriggerVariants } from '@timui/core'\nimport { useStepper, useStepItem } from './stepper.vue'\nimport type { HTMLAttributes } from 'vue'\nimport { Primitive, type PrimitiveProps } from '../../primitive'\n\nconst props = withDefaults(\n  defineProps<\n    PrimitiveProps & {\n      class?: HTMLAttributes['class']\n    }\n  >(),\n  {\n    as: 'button',\n  }\n)\n\nconst { setActiveStep } = useStepper()\nconst { step, isDisabled } = useStepItem()\n</script>\n\n<template>\n  <Primitive\n    data-slot=\"stepper-trigger\"\n    :as=\"as\"\n    :as-child=\"asChild\"\n    :class=\"\n      cn(\n        stepperTriggerVariants(),\n        props.class\n      )\n    \"\n    :disabled=\"isDisabled\"\n    @click=\"setActiveStep(step)\"\n  >\n    <slot />\n  </Primitive>\n</template>\n"
        },
        {
          "path": "registry/default/vue/stepper/stepper.vue",
          "target": "components/ui/stepper/stepper.vue",
          "type": "registry:component",
          "content": "<script lang=\"ts\">\nimport { type InjectionKey, type Ref, type ComputedRef, inject } from 'vue'\nimport type { StepperApi } from '@timui/core'\n\nexport type StepperContextValue = {\n  api: ComputedRef<StepperApi | null>\n  activeStep: Ref<number>\n  setActiveStep: (step: number) => void\n  orientation: Ref<'horizontal' | 'vertical'>\n}\n\nexport type StepItemContextValue = {\n  step: number\n  state: Ref<'active' | 'completed' | 'inactive' | 'loading'>\n  isDisabled: Ref<boolean>\n  isLoading: Ref<boolean>\n}\n\nexport const StepperContextKey = Symbol('StepperContext') as InjectionKey<StepperContextValue>\nexport const StepItemContextKey = Symbol('StepItemContext') as InjectionKey<StepItemContextValue>\n\nexport const useStepper = () => {\n  const context = inject(StepperContextKey)\n  if (!context) {\n    throw new Error('useStepper must be used within a Stepper')\n  }\n  return context\n}\n\nexport const useStepItem = () => {\n  const context = inject(StepItemContextKey)\n  if (!context) {\n    throw new Error('useStepItem must be used within a StepperItem')\n  }\n  return context\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, provide, toRef, watch, useId } from 'vue'\nimport { normalizeProps, useMachine } from '@zag-js/vue'\nimport type { Machine as NumberInputMachine } from '@zag-js/number-input'\nimport type { Machine as ZagMachine, MachineSchema as ZagMachineSchema } from '@zag-js/core'\nimport { cn, stepperVariants, stepperConnect, stepperMachine } from '@timui/core'\nimport type { HTMLAttributes } from 'vue'\n\ntype InferMachineSchema<T> = T extends ZagMachine<infer S> ? S : ZagMachineSchema\ntype NumberInputSchema = InferMachineSchema<NumberInputMachine>\n\nconst props = withDefaults(\n  defineProps<{\n    id?: string\n    defaultValue?: number\n    modelValue?: number\n    orientation?: 'horizontal' | 'vertical'\n    class?: HTMLAttributes['class']\n  }>(),\n  {\n    defaultValue: 0,\n    orientation: 'horizontal',\n  }\n)\n\nconst emits = defineEmits<{\n  (e: 'update:modelValue', value: number): void\n  (e: 'change', value: number): void\n}>()\nconst generatedId = useId()\n\nconst service = useMachine<NumberInputSchema>(stepperMachine, {\n  id: props.id ?? generatedId,\n  value: props.modelValue !== undefined ? String(props.modelValue) : undefined,\n  defaultValue: props.modelValue === undefined ? String(props.defaultValue) : undefined,\n  onValueChange(details: { value: string; valueAsNumber: number }) {\n    emits('update:modelValue', details.valueAsNumber)\n    emits('change', details.valueAsNumber)\n  },\n})\n\nconst api = computed(() => stepperConnect(service, normalizeProps))\nconst activeStep = computed(() => api.value?.valueAsNumber ?? 0)\n\nwatch(\n  () => props.modelValue,\n  (newVal) => {\n    if (newVal !== undefined && api.value?.valueAsNumber !== newVal) {\n      api.value?.setValue(newVal)\n    }\n  }\n)\n\nconst setActiveStep = (step: number) => {\n  api.value?.setValue(step)\n}\n\nprovide(StepperContextKey, {\n  api,\n  activeStep,\n  setActiveStep,\n  orientation: toRef(props, 'orientation'),\n})\n</script>\n\n<template>\n  <div\n    data-slot=\"stepper\"\n    :class=\"cn(stepperVariants(), props.class)\"\n    :data-orientation=\"orientation\"\n    v-bind=\"api?.getRootProps?.()\"\n  >\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/html/stepper.html",
          "target": "components/ui/stepper.html",
          "type": "registry:component",
          "content": "<ol data-slot=\"stepper\" class=\"flex items-center gap-3\">\n  <li class=\"flex items-center gap-2\">\n    <span class=\"focus-visible:border-ring focus-visible:ring-ring/50 inline-flex items-center gap-3 rounded-full outline-none focus-visible:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50\">1</span>\n    <span class=\"text-sm\">Start</span>\n  </li>\n  <li class=\"h-px w-8 bg-border\"></li>\n  <li class=\"flex items-center gap-2\">\n    <span class=\"focus-visible:border-ring focus-visible:ring-ring/50 inline-flex items-center gap-3 rounded-full outline-none focus-visible:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50\">2</span>\n    <span class=\"text-muted-foreground text-sm\">Review</span>\n  </li>\n</ol>"
        },
        {
          "path": "registry/default/weapp/stepper.wxml",
          "target": "components/ui/stepper.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\" data-disabled=\"{{disabled}}\">\n  <!-- Decrement Button -->\n  <view \n    class=\"stepper-decrement\"\n    bindtap=\"onDecrementTap\"\n    data-disabled=\"{{api.isAtMin || disabled}}\"\n  >\n    <text>−</text>\n  </view>\n\n  <!-- Input -->\n  <input \n    class=\"stepper-input\"\n    type=\"digit\"\n    value=\"{{api.value}}\"\n    disabled=\"{{disabled || readOnly}}\"\n    bindinput=\"onInput\"\n  />\n\n  <!-- Increment Button -->\n  <view \n    class=\"stepper-increment\"\n    bindtap=\"onIncrementTap\"\n    data-disabled=\"{{api.isAtMax || disabled}}\"\n  >\n    <text>+</text>\n  </view>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/stepper.wxss",
          "target": "components/ui/stepper.wxss",
          "type": "registry:component",
          "content": "/* weapp component styles */\n"
        },
        {
          "path": "registry/default/weapp/stepper.ts",
          "target": "components/ui/stepper.ts",
          "type": "registry:component",
          "content": "import { emitTimEvent } from '../utils'\nimport { setupStepperMachine } from './use-stepper'\n\ntype WeappStepperApi = {\n  decrement?: () => void\n  increment?: () => void\n  setValue?: (value: string | number) => void\n}\n\ntype WeappService = {\n  setContext: (context: Record<string, object>) => void\n}\n\ntype StepperInputEvent = WechatMiniprogram.CustomEvent<{\n  value: string\n}>\n\ntype WeappStepperInternal =\n  WechatMiniprogram.Component.InstanceMethods<WechatMiniprogram.IAnyObject> & {\n    _service?: WeappService\n    _cleanup?: () => void\n    _send?: (event: object) => void\n    data: {\n      api: WeappStepperApi\n    }\n    properties: {\n      value: string\n      min: number\n      max: number\n      step: number\n      disabled: boolean\n      readOnly: boolean\n      allowMouseWheel: boolean\n      clampValueOnBlur: boolean\n      id: string\n      extClass: string\n    }\n  }\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    value: { type: String, value: '0' },\n    min: { type: Number, value: Number.MIN_SAFE_INTEGER },\n    max: { type: Number, value: Number.MAX_SAFE_INTEGER },\n    step: { type: Number, value: 1 },\n    disabled: { type: Boolean, value: false },\n    readOnly: { type: Boolean, value: false },\n    allowMouseWheel: { type: Boolean, value: false },\n    clampValueOnBlur: { type: Boolean, value: true },\n    id: { type: String, value: 'stepper' },\n    extClass: { type: String, value: '' },\n  },\n\n  data: {\n    api: {} as WeappStepperApi,\n    className: '',\n  },\n\n  lifetimes: {\n    attached() {\n      const self = this as WeappStepperInternal\n      const { service, cleanup, send } = setupStepperMachine(this, {\n        id: this.properties.id,\n        value: this.properties.value,\n        min: this.properties.min,\n        max: this.properties.max,\n        step: this.properties.step,\n        disabled: this.properties.disabled,\n        readOnly: this.properties.readOnly,\n        allowMouseWheel: this.properties.allowMouseWheel,\n        clampValueOnBlur: this.properties.clampValueOnBlur,\n        onValueChange: (details) => {\n          emitTimEvent(this, 'change', 'change', this.properties.id || 'stepper', {\n            value: details.value,\n          })\n        },\n      })\n\n      self._service = service as WeappService\n      self._cleanup = cleanup\n      self._send = send as (event: object) => void\n    },\n    detached() {\n      const self = this as WeappStepperInternal\n      self._cleanup?.()\n    },\n  },\n\n  observers: {\n    state: function (state) {\n      const self = this as WeappStepperInternal\n      if (!state || !self._send) return\n      const { connect } = setupStepperMachine(this, { id: this.properties.id })\n      const api = connect(state, self._send) as WeappStepperApi\n      this.setData({ api, className: this.properties.extClass })\n    },\n\n    value: function (val) {\n      const self = this as WeappStepperInternal\n      if (self._service) {\n        self._service.setContext({ value: val })\n      }\n    },\n  },\n\n  methods: {\n    onDecrementTap() {\n      const self = this as WeappStepperInternal\n      self.data.api.decrement?.()\n    },\n    onIncrementTap() {\n      const self = this as WeappStepperInternal\n      self.data.api.increment?.()\n    },\n    onInput(e: StepperInputEvent) {\n      const self = this as WeappStepperInternal\n      const value = e.detail.value\n      self.data.api.setValue?.(value)\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/stepper.json",
          "target": "components/ui/stepper.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        }
      ],
      "dependencies": [
        "@timui/core",
        "@zag-js/core",
        "@zag-js/number-input",
        "@zag-js/react"
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@zag-js/core",
              "@zag-js/number-input",
              "@zag-js/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@zag-js/core",
              "@zag-js/number-input",
              "@zag-js/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "aliases": [
          "number-input"
        ]
      }
    },
    {
      "name": "switch",
      "type": "registry:ui",
      "dependencies": [
        "@timui/core",
        "@zag-js/react"
      ],
      "registryDependencies": [
        "use-machine"
      ],
      "files": [
        {
          "path": "registry/default/ui/switch.tsx",
          "type": "registry:ui",
          "target": "components/ui/switch.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport type { SwitchProps as CoreSwitchProps } from '@timui/core'\nimport {\n  cn,\n  createTimEvent,\n  switchConnect,\n  switchMachine,\n  switchRootVariants,\n  switchThumbVariants,\n  switchVariants,\n} from '@timui/core'\nimport { mergeProps } from '@zag-js/react'\n\nimport { useSwitch } from './switch/use-switch'\n\ntype SwitchProps = CoreSwitchProps &\n  Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, keyof CoreSwitchProps>\n\nconst Switch = React.forwardRef<HTMLButtonElement, SwitchProps>(\n  (\n    {\n      className,\n      checked,\n      defaultChecked,\n      required,\n      onCheckedChange,\n      value = 'on',\n      disabled,\n      name,\n      id,\n      ...props\n    },\n    ref\n  ) => {\n    const api = useSwitch({\n      id,\n      checked,\n      defaultChecked,\n      required,\n      onCheckedChange,\n      value: value ?? 'on',\n      disabled,\n      name,\n    })\n    const rootProps = api.getRootProps()\n    const controlProps = api.getControlProps()\n    const thumbProps = api.getThumbProps()\n    const hiddenInputProps = api.getHiddenInputProps()\n    const mergedControlProps = mergeProps(controlProps, props)\n    const { className: controlClassName, ...controlRest } = mergedControlProps\n\n    return (\n      <label\n        {...rootProps}\n        data-slot=\"switch-root\"\n        className={cn(switchRootVariants(), rootProps.className)}\n      >\n        <button\n          {...controlRest}\n          ref={ref}\n          type=\"button\"\n          data-slot=\"switch\"\n          className={cn(switchVariants(), controlClassName, className)}\n        >\n          <span\n            {...thumbProps}\n            data-slot=\"switch-thumb\"\n            className={cn(switchThumbVariants(), thumbProps.className)}\n          />\n        </button>\n        <input {...hiddenInputProps} />\n      </label>\n    )\n  }\n)\nSwitch.displayName = 'Switch'\n\nexport { Switch }\n"
        },
        {
          "path": "registry/default/vue/switch.vue",
          "type": "registry:ui",
          "target": "components/ui/switch.vue",
          "content": "<script setup lang=\"ts\">\nimport { computed, type HTMLAttributes } from 'vue'\nimport { normalizeProps, useMachine } from '@zag-js/vue'\nimport type { AssertNoExtraKeys, SwitchVueProps } from '@timui/core'\nimport { switchConnect, switchMachine } from '@timui/core'\nimport { cn, switchRootVariants, switchThumbVariants, switchVariants } from '@timui/core'\n\nimport { useSwitch } from './use-switch'\n\ntype SwitchProps = SwitchVueProps & { class?: HTMLAttributes['class'] }\ntype _SwitchPropsGuard = AssertNoExtraKeys<SwitchProps, SwitchProps>\n\nconst props = defineProps<SwitchProps>()\n\nconst emit = defineEmits(['update:modelValue', 'change'])\n\nconst api = useSwitch(props, emit)\nconst rootProps = computed(() => api.value?.getRootProps?.() ?? {})\nconst controlProps = computed(() => api.value?.getControlProps?.() ?? {})\nconst thumbProps = computed(() => api.value?.getThumbProps?.() ?? {})\nconst hiddenInputProps = computed(() => api.value?.getHiddenInputProps?.() ?? {})\n</script>\n\n<template>\n  <label\n    v-bind=\"rootProps\"\n    data-slot=\"switch-root\"\n    :class=\"cn(switchRootVariants(), rootProps.class)\"\n  >\n    <button\n      v-bind=\"controlProps\"\n      type=\"button\"\n      data-slot=\"switch\"\n      :class=\"cn(switchVariants(), controlProps.class, props.class)\"\n    >\n      <span\n        v-bind=\"thumbProps\"\n        data-slot=\"switch-thumb\"\n        :class=\"cn(switchThumbVariants(), thumbProps.class)\"\n      />\n    </button>\n    <input v-bind=\"hiddenInputProps\" />\n  </label>\n</template>\n"
        },
        {
          "path": "registry/default/ui/switch/use-switch.ts",
          "target": "components/ui/switch/use-switch.ts",
          "type": "registry:ui",
          "content": "import * as React from 'react'\nimport type { SwitchProps as CoreSwitchProps } from '@timui/core'\nimport { createTimEvent, switchConnect, switchMachine } from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/react'\n\nexport interface UseSwitchProps extends Omit<CoreSwitchProps, 'id'> {\n  id?: string\n}\n\nexport function useSwitch(props: UseSwitchProps) {\n  const generatedId = React.useId()\n  const switchId = props.id ?? generatedId\n\n  const service = useMachine(switchMachine, {\n    id: switchId,\n    checked: props.checked,\n    defaultChecked: props.defaultChecked,\n    disabled: props.disabled,\n    required: props.required,\n    name: props.name,\n    value: props.value ?? 'on',\n    onCheckedChange(details) {\n      props.onCheckedChange?.(createTimEvent('change', switchId, { checked: details.checked }))\n    },\n  })\n\n  const api = React.useMemo(() => switchConnect(service, normalizeProps), [service])\n\n  return api\n}\n"
        },
        {
          "path": "registry/default/vue/switch/switch.vue",
          "target": "components/ui/switch/switch.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, type HTMLAttributes } from 'vue'\nimport { normalizeProps, useMachine } from '@zag-js/vue'\nimport type { AssertNoExtraKeys, SwitchVueProps } from '@timui/core'\nimport { switchConnect, switchMachine } from '@timui/core'\nimport { cn, switchRootVariants, switchThumbVariants, switchVariants } from '@timui/core'\n\nimport { useSwitch } from './use-switch'\n\ntype SwitchProps = SwitchVueProps & { class?: HTMLAttributes['class'] }\ntype _SwitchPropsGuard = AssertNoExtraKeys<SwitchProps, SwitchProps>\n\nconst props = defineProps<SwitchProps>()\n\nconst emit = defineEmits(['update:modelValue', 'change'])\n\nconst api = useSwitch(props, emit)\nconst rootProps = computed(() => api.value?.getRootProps?.() ?? {})\nconst controlProps = computed(() => api.value?.getControlProps?.() ?? {})\nconst thumbProps = computed(() => api.value?.getThumbProps?.() ?? {})\nconst hiddenInputProps = computed(() => api.value?.getHiddenInputProps?.() ?? {})\n</script>\n\n<template>\n  <label\n    v-bind=\"rootProps\"\n    data-slot=\"switch-root\"\n    :class=\"cn(switchRootVariants(), rootProps.class)\"\n  >\n    <button\n      v-bind=\"controlProps\"\n      type=\"button\"\n      data-slot=\"switch\"\n      :class=\"cn(switchVariants(), controlProps.class, props.class)\"\n    >\n      <span\n        v-bind=\"thumbProps\"\n        data-slot=\"switch-thumb\"\n        :class=\"cn(switchThumbVariants(), thumbProps.class)\"\n      />\n    </button>\n    <input v-bind=\"hiddenInputProps\" />\n  </label>\n</template>\n"
        },
        {
          "path": "registry/default/vue/switch/use-switch.ts",
          "target": "components/ui/switch/use-switch.ts",
          "type": "registry:component",
          "content": "import { switchConnect, switchMachine } from '@timui/core'\nimport type { SwitchVueProps } from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/vue'\nimport { computed, useId } from 'vue'\n\ntype SwitchEmits = {\n  (event: 'update:modelValue', value: boolean): void\n  (event: 'change', value: boolean): void\n}\n\nexport function useSwitch(props: SwitchVueProps, emit: SwitchEmits) {\n  const generatedId = useId()\n\n  const machineProps = computed(() => ({\n    id: props.id ?? generatedId,\n    checked: props.modelValue ?? props.checked,\n    defaultChecked:\n      props.modelValue === undefined && props.checked === undefined\n        ? props.defaultChecked\n        : undefined,\n    disabled: props.disabled,\n    required: props.required,\n    name: props.name,\n    value: props.value ?? 'on',\n    onCheckedChange(details: { checked: boolean }) {\n      props.onCheckedChange?.(details.checked)\n      emit('update:modelValue', details.checked)\n      emit('change', details.checked)\n    },\n  }))\n\n  const service = useMachine(switchMachine, machineProps)\n  const api = computed(() => switchConnect(service, normalizeProps))\n\n  return api\n}\n"
        },
        {
          "path": "registry/default/html/switch.html",
          "target": "components/ui/switch.html",
          "type": "registry:component",
          "content": "<div data-timui-root data-timui-init=\"auto\">\n  <label data-slot=\"switch-root\" class=\"inline-flex items-center\">\n      <button type=\"button\" role=\"switch\" data-slot=\"switch\" data-state=\"unchecked\" aria-checked=\"false\" class=\"peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state&#x3D;checked]:bg-primary data-[state&#x3D;unchecked]:bg-input\">\n          <span data-slot=\"switch-thumb\" data-state=\"unchecked\" class=\"pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state&#x3D;checked]:translate-x-5 data-[state&#x3D;unchecked]:translate-x-0\"></span>\n      </button>\n      <input type=\"checkbox\"\n          style=\"border: 0px; clip: rect(0px, 0px, 0px, 0px); clip-path: inset(50%); height: 1px; margin: -1px; overflow: hidden; padding: 0px; position: absolute; width: 1px; white-space: nowrap; word-wrap: normal;\" />\n  </label>\n</div>\n<script type=\"module\">\n  import { autoInitHtmlRuntime } from '@timui/html'\n  autoInitHtmlRuntime({ components: ['switch'] })\n</script>"
        },
        {
          "path": "registry/default/weapp/switch.wxml",
          "target": "components/ui/switch.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\">\n  <switch\n    checked=\"{{checked}}\"\n    disabled=\"{{disabled}}\"\n    color=\"{{color}}\"\n    name=\"{{name}}\"\n    type=\"switch\"\n    bindchange=\"onSwitchChange\"\n  />\n</view>\n"
        },
        {
          "path": "registry/default/weapp/switch.wxss",
          "target": "components/ui/switch.wxss",
          "type": "registry:component",
          "content": "/* Styles handled by Tailwind CSS */\n"
        },
        {
          "path": "registry/default/weapp/switch.ts",
          "target": "components/ui/switch.ts",
          "type": "registry:component",
          "content": "import { emitTimEvent, resolveClasses, switchVariants } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    checked: { type: Boolean, value: false },\n    disabled: { type: Boolean, value: false },\n    color: { type: String, value: '#1aad19' },\n    name: { type: String, value: '' },\n    id: { type: String, value: 'switch' },\n    extClass: { type: String, value: '' },\n  },\n\n  data: {\n    className: '',\n  },\n\n  lifetimes: {\n    attached() {\n      this.updateClassName()\n    },\n  },\n\n  observers: {\n    extClass: function () {\n      this.updateClassName()\n    },\n  },\n\n  methods: {\n    updateClassName() {\n      const className = resolveClasses(switchVariants({ className: this.properties.extClass }))\n      this.setData({ className })\n    },\n\n    onSwitchChange(e: WechatMiniprogram.CustomEvent) {\n      const checked = !!e.detail.value\n      this.triggerEvent('input', { value: checked })\n      emitTimEvent(this, 'change', 'change', this.properties.id || 'switch', {\n        checked,\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/switch.json",
          "target": "components/ui/switch.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        }
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@zag-js/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@zag-js/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "table",
      "type": "registry:ui",
      "files": [
        {
          "path": "registry/default/ui/table.tsx",
          "type": "registry:ui",
          "target": "components/ui/table.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport {\n  cn,\n  tableBodyVariants,\n  tableCaptionVariants,\n  tableCellVariants,\n  tableFooterVariants,\n  tableHeaderVariants,\n  tableHeadVariants,\n  tableRowVariants,\n  tableVariants,\n} from '@timui/core'\n\nfunction Table({ className, ...props }: React.ComponentProps<'table'>) {\n  return (\n    <div className=\"relative w-full overflow-auto\">\n      <table data-slot=\"table\" className={cn(tableVariants(), className)} {...props} />\n    </div>\n  )\n}\n\nfunction TableHeader({ className, ...props }: React.ComponentProps<'thead'>) {\n  return (\n    <thead data-slot=\"table-header\" className={cn(tableHeaderVariants(), className)} {...props} />\n  )\n}\n\nfunction TableBody({ className, ...props }: React.ComponentProps<'tbody'>) {\n  return <tbody data-slot=\"table-body\" className={cn(tableBodyVariants(), className)} {...props} />\n}\n\nfunction TableFooter({ className, ...props }: React.ComponentProps<'tfoot'>) {\n  return (\n    <tfoot data-slot=\"table-footer\" className={cn(tableFooterVariants(), className)} {...props} />\n  )\n}\n\nfunction TableRow({ className, ...props }: React.ComponentProps<'tr'>) {\n  return <tr data-slot=\"table-row\" className={cn(tableRowVariants(), className)} {...props} />\n}\n\nfunction TableHead({ className, ...props }: React.ComponentProps<'th'>) {\n  return <th data-slot=\"table-head\" className={cn(tableHeadVariants(), className)} {...props} />\n}\n\nfunction TableCell({ className, ...props }: React.ComponentProps<'td'>) {\n  return <td data-slot=\"table-cell\" className={cn(tableCellVariants(), className)} {...props} />\n}\n\nfunction TableCaption({ className, ...props }: React.ComponentProps<'caption'>) {\n  return (\n    <caption\n      data-slot=\"table-caption\"\n      className={cn(tableCaptionVariants(), className)}\n      {...props}\n    />\n  )\n}\n\nexport { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow }\n"
        },
        {
          "path": "registry/default/vue/table.vue",
          "type": "registry:ui",
          "target": "components/ui/table.vue",
          "content": "<script setup lang=\"ts\">\nimport { cn, tableVariants } from \"@timui/core\";\nimport { type HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{\n  class?: HTMLAttributes[\"class\"];\n}>();\n</script>\n\n<template>\n  <div class=\"relative w-full overflow-auto\">\n    <table data-slot=\"table\" :class=\"cn(tableVariants(), props.class)\">\n      <slot />\n    </table>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/table/index.ts",
          "target": "components/ui/table/index.ts",
          "type": "registry:component",
          "content": "export { default as Table } from './table.vue'\nexport { default as TableHeader } from './table-header.vue'\nexport { default as TableBody } from './table-body.vue'\nexport { default as TableFooter } from './table-footer.vue'\nexport { default as TableHead } from './table-head.vue'\nexport { default as TableRow } from './table-row.vue'\nexport { default as TableCell } from './table-cell.vue'\nexport { default as TableCaption } from './table-caption.vue'\n"
        },
        {
          "path": "registry/default/vue/table/table-body.vue",
          "target": "components/ui/table/table-body.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, tableBodyVariants } from \"@timui/core\";\nimport { type HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{\n  class?: HTMLAttributes[\"class\"];\n}>();\n</script>\n\n<template>\n  <tbody data-slot=\"table-body\" :class=\"cn(tableBodyVariants(), props.class)\">\n    <slot />\n  </tbody>\n</template>\n"
        },
        {
          "path": "registry/default/vue/table/table-caption.vue",
          "target": "components/ui/table/table-caption.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, tableCaptionVariants } from \"@timui/core\";\nimport { type HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{\n  class?: HTMLAttributes[\"class\"];\n}>();\n</script>\n\n<template>\n  <caption data-slot=\"table-caption\" :class=\"cn(tableCaptionVariants(), props.class)\">\n    <slot />\n  </caption>\n</template>\n"
        },
        {
          "path": "registry/default/vue/table/table-cell.vue",
          "target": "components/ui/table/table-cell.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, tableCellVariants } from \"@timui/core\";\nimport { type HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{\n  class?: HTMLAttributes[\"class\"];\n}>();\n</script>\n\n<template>\n  <td data-slot=\"table-cell\" :class=\"cn(tableCellVariants(), props.class)\">\n    <slot />\n  </td>\n</template>\n"
        },
        {
          "path": "registry/default/vue/table/table-footer.vue",
          "target": "components/ui/table/table-footer.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, tableFooterVariants } from \"@timui/core\";\nimport { type HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{\n  class?: HTMLAttributes[\"class\"];\n}>();\n</script>\n\n<template>\n  <tfoot data-slot=\"table-footer\" :class=\"cn(tableFooterVariants(), props.class)\">\n    <slot />\n  </tfoot>\n</template>\n"
        },
        {
          "path": "registry/default/vue/table/table-head.vue",
          "target": "components/ui/table/table-head.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, tableHeadVariants } from \"@timui/core\";\nimport { type HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{\n  class?: HTMLAttributes[\"class\"];\n}>();\n</script>\n\n<template>\n  <th data-slot=\"table-head\" :class=\"cn(tableHeadVariants(), props.class)\">\n    <slot />\n  </th>\n</template>\n"
        },
        {
          "path": "registry/default/vue/table/table-header.vue",
          "target": "components/ui/table/table-header.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, tableHeaderVariants } from \"@timui/core\";\nimport { type HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{\n  class?: HTMLAttributes[\"class\"];\n}>();\n</script>\n\n<template>\n  <thead data-slot=\"table-header\" :class=\"cn(tableHeaderVariants(), props.class)\">\n    <slot />\n  </thead>\n</template>\n"
        },
        {
          "path": "registry/default/vue/table/table-row.vue",
          "target": "components/ui/table/table-row.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, tableRowVariants } from \"@timui/core\";\nimport { type HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{\n  class?: HTMLAttributes[\"class\"];\n}>();\n</script>\n\n<template>\n  <tr data-slot=\"table-row\" :class=\"cn(tableRowVariants(), props.class)\">\n    <slot />\n  </tr>\n</template>\n"
        },
        {
          "path": "registry/default/vue/table/table.vue",
          "target": "components/ui/table/table.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, tableVariants } from \"@timui/core\";\nimport { type HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{\n  class?: HTMLAttributes[\"class\"];\n}>();\n</script>\n\n<template>\n  <div class=\"relative w-full overflow-auto\">\n    <table data-slot=\"table\" :class=\"cn(tableVariants(), props.class)\">\n      <slot />\n    </table>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/html/table.html",
          "target": "components/ui/table.html",
          "type": "registry:component",
          "content": "<div class=\"relative w-full overflow-auto\">\n    <table data-slot=\"table\" class=\"w-full caption-bottom text-sm\">\n        <thead data-slot=\"table-header\" class=\"[&amp;_tr]:border-b\">\n            <tr data-slot=\"table-row\" class=\"border-b transition-colors hover:bg-muted/50 data-[state&#x3D;selected]:bg-muted\">\n                <th data-slot=\"table-head\" class=\"h-12 px-4 text-left align-middle font-medium text-muted-foreground [&amp;:has([role&#x3D;checkbox])]:pr-0\">\n                    Header\n                </th>\n            </tr>\n        </thead>\n        <tbody data-slot=\"table-body\" class=\"[&amp;_tr:last-child]:border-0\">\n            <tr data-slot=\"table-row\" class=\"border-b transition-colors hover:bg-muted/50 data-[state&#x3D;selected]:bg-muted\">\n                <td data-slot=\"table-cell\" class=\"p-4 align-middle [&amp;:has([role&#x3D;checkbox])]:pr-0\">\n                    Cell\n                </td>\n            </tr>\n        </tbody>\n    </table>\n</div>"
        },
        {
          "path": "registry/default/weapp/table.wxml",
          "target": "components/ui/table.wxml",
          "type": "registry:component",
          "content": "<view class=\"relative w-full overflow-auto\">\n  <view class=\"{{className}}\">\n    <slot></slot>\n  </view>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/table.wxss",
          "target": "components/ui/table.wxss",
          "type": "registry:component",
          "content": "/* packages/weapp/src/table/table.wxss */\n"
        },
        {
          "path": "registry/default/weapp/table.ts",
          "target": "components/ui/table.ts",
          "type": "registry:component",
          "content": "import { tableVariants } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: { type: String, value: '' },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass) {\n      this.setData({\n        className: tableVariants({ className: extClass }),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/table.json",
          "target": "components/ui/table.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/table-body/table-body.wxml",
          "target": "components/ui/table-body/table-body.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/table-body/table-body.wxss",
          "target": "components/ui/table-body/table-body.wxss",
          "type": "registry:component",
          "content": "/* packages/weapp/src/table-body/table-body.wxss */\n"
        },
        {
          "path": "registry/default/weapp/table-body/table-body.json",
          "target": "components/ui/table-body/table-body.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/table-body/table-body.ts",
          "target": "components/ui/table-body/table-body.ts",
          "type": "registry:component",
          "content": "import { tableBodyVariants } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: { type: String, value: '' },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass) {\n      this.setData({\n        className: tableBodyVariants({ className: extClass }),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/table-cell/table-cell.wxml",
          "target": "components/ui/table-cell/table-cell.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}} flex items-center\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/table-cell/table-cell.wxss",
          "target": "components/ui/table-cell/table-cell.wxss",
          "type": "registry:component",
          "content": "/* packages/weapp/src/table-cell/table-cell.wxss */\n"
        },
        {
          "path": "registry/default/weapp/table-cell/table-cell.json",
          "target": "components/ui/table-cell/table-cell.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/table-cell/table-cell.ts",
          "target": "components/ui/table-cell/table-cell.ts",
          "type": "registry:component",
          "content": "import { tableCellVariants } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: { type: String, value: '' },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass) {\n      this.setData({\n        className: tableCellVariants({ className: extClass }),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/table-head/table-head.wxml",
          "target": "components/ui/table-head/table-head.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}} flex items-center\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/table-head/table-head.wxss",
          "target": "components/ui/table-head/table-head.wxss",
          "type": "registry:component",
          "content": "/* packages/weapp/src/table-head/table-head.wxss */\n"
        },
        {
          "path": "registry/default/weapp/table-head/table-head.json",
          "target": "components/ui/table-head/table-head.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/table-head/table-head.ts",
          "target": "components/ui/table-head/table-head.ts",
          "type": "registry:component",
          "content": "import { tableHeadVariants } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: { type: String, value: '' },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass) {\n      this.setData({\n        className: tableHeadVariants({ className: extClass }),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/table-header/table-header.wxml",
          "target": "components/ui/table-header/table-header.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}} border-b\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/table-header/table-header.wxss",
          "target": "components/ui/table-header/table-header.wxss",
          "type": "registry:component",
          "content": "/* packages/weapp/src/table-header/table-header.wxss */\n"
        },
        {
          "path": "registry/default/weapp/table-header/table-header.json",
          "target": "components/ui/table-header/table-header.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/table-header/table-header.ts",
          "target": "components/ui/table-header/table-header.ts",
          "type": "registry:component",
          "content": "import { tableHeaderVariants } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: { type: String, value: '' },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass) {\n      this.setData({\n        className: tableHeaderVariants({ className: extClass }),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/table-row/table-row.wxml",
          "target": "components/ui/table-row/table-row.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}} grid grid-cols-4\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/table-row/table-row.wxss",
          "target": "components/ui/table-row/table-row.wxss",
          "type": "registry:component",
          "content": "/* packages/weapp/src/table-row/table-row.wxss */\n"
        },
        {
          "path": "registry/default/weapp/table-row/table-row.json",
          "target": "components/ui/table-row/table-row.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/table-row/table-row.ts",
          "target": "components/ui/table-row/table-row.ts",
          "type": "registry:component",
          "content": "import { tableRowVariants } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: { type: String, value: '' },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass) {\n      this.setData({\n        className: tableRowVariants({ className: extClass }),\n      })\n    },\n  },\n})\n"
        }
      ],
      "dependencies": [
        "@timui/core"
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "tabs",
      "type": "registry:ui",
      "dependencies": [
        "@timui/core",
        "@zag-js/react"
      ],
      "registryDependencies": [
        "use-machine"
      ],
      "files": [
        {
          "path": "registry/default/ui/tabs.tsx",
          "type": "registry:ui",
          "target": "components/ui/tabs.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport { cn, tabsContentVariants, tabsListVariants, tabsTriggerVariants } from '@timui/core'\nimport { mergeProps } from '@zag-js/react'\n\nimport { Slot } from './slot'\nimport { useTabs, type UseTabsProps } from './tabs/use-tabs'\nimport { TabsProvider, useTabsContext } from './tabs/use-tabs-context'\n\nconst Tabs = React.forwardRef<\n  HTMLDivElement,\n  React.HTMLAttributes<HTMLDivElement> & {\n    value?: string\n    defaultValue?: string\n    onValueChange?: (value: string) => void\n    onFocusChange?: (value: string) => void\n    orientation?: 'horizontal' | 'vertical'\n    activationMode?: 'manual' | 'automatic'\n    loopFocus?: boolean\n    composite?: boolean\n    deselectable?: boolean\n    id?: string\n  }\n>(\n  (\n    {\n      className,\n      value,\n      defaultValue,\n      onValueChange,\n      onFocusChange,\n      orientation,\n      activationMode,\n      loopFocus,\n      composite,\n      deselectable,\n      id,\n      ...props\n    },\n    ref\n  ) => {\n    const api = useTabs({\n      value,\n      defaultValue,\n      onValueChange,\n      onFocusChange,\n      orientation,\n      activationMode,\n      loopFocus,\n      composite,\n      deselectable,\n      id,\n    })\n    const rootProps = api.getRootProps()\n    const mergedProps = mergeProps(rootProps, props) as React.HTMLAttributes<HTMLDivElement>\n    const { className: mergedClassName, ...restProps } = mergedProps\n\n    return (\n      <TabsProvider value={api}>\n        <div ref={ref} data-slot=\"tabs\" className={cn(className, mergedClassName)} {...restProps} />\n      </TabsProvider>\n    )\n  }\n)\nTabs.displayName = 'Tabs'\n\nconst TabsList = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, ...props }, ref) => {\n    const api = useTabsContext()\n    const listProps = api.getListProps()\n    const mergedProps = mergeProps(listProps, props) as React.HTMLAttributes<HTMLDivElement>\n    const { className: mergedClassName, ...restProps } = mergedProps\n    return (\n      <div\n        ref={ref}\n        data-slot=\"tabs-list\"\n        className={cn(tabsListVariants(), className, mergedClassName)}\n        {...restProps}\n      />\n    )\n  }\n)\nTabsList.displayName = 'TabsList'\n\nconst TabsTrigger = React.forwardRef<\n  HTMLButtonElement,\n  React.ButtonHTMLAttributes<HTMLButtonElement> & { value: string; asChild?: boolean }\n>(({ className, value, asChild = false, ...props }, ref) => {\n  const api = useTabsContext()\n  const Comp = asChild ? Slot : 'button'\n  const triggerProps = api.getTriggerProps({ value, disabled: props.disabled })\n  const mergedProps = mergeProps(\n    triggerProps,\n    props\n  ) as React.ButtonHTMLAttributes<HTMLButtonElement>\n  const { className: mergedClassName, type: mergedType, ...restProps } = mergedProps\n  const finalType = asChild ? mergedType : (mergedType ?? 'button')\n\n  return (\n    <Comp\n      ref={ref}\n      data-slot=\"tabs-trigger\"\n      type={finalType}\n      className={cn(tabsTriggerVariants(), className, mergedClassName)}\n      {...restProps}\n    />\n  )\n})\nTabsTrigger.displayName = 'TabsTrigger'\n\nconst TabsContent = React.forwardRef<\n  HTMLDivElement,\n  React.HTMLAttributes<HTMLDivElement> & { value: string }\n>(({ className, value, ...props }, ref) => {\n  const api = useTabsContext()\n  const isSelected = api.value === value\n\n  if (!isSelected) return null\n\n  const contentProps = api.getContentProps({ value })\n  const mergedProps = mergeProps(contentProps, props) as React.HTMLAttributes<HTMLDivElement>\n  const { className: mergedClassName, ...restProps } = mergedProps\n\n  return (\n    <div\n      ref={ref}\n      data-slot=\"tabs-content\"\n      role=\"tabpanel\"\n      data-state={isSelected ? 'active' : 'inactive'}\n      className={cn(tabsContentVariants(), className, mergedClassName)}\n      {...restProps}\n    />\n  )\n})\nTabsContent.displayName = 'TabsContent'\n\nexport { Tabs, TabsList, TabsTrigger, TabsContent }\n"
        },
        {
          "path": "registry/default/vue/tabs.vue",
          "type": "registry:ui",
          "target": "components/ui/tabs.vue",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes } from \"vue\";\nimport { cn } from \"@timui/core\";\nimport { useTabs } from \"./use-tabs\";\nimport { provideTabsContext } from \"./use-tabs-context\";\n\nconst props = defineProps<{\n  modelValue?: string;\n  value?: string;\n  defaultValue?: string;\n  id?: string;\n  orientation?: \"horizontal\" | \"vertical\";\n  activationMode?: \"manual\" | \"automatic\";\n  loopFocus?: boolean;\n  composite?: boolean;\n  deselectable?: boolean;\n  onValueChange?: (value: string) => void;\n  onFocusChange?: (value: string) => void;\n  class?: HTMLAttributes[\"class\"];\n}>();\n\nconst emit = defineEmits([\"update:modelValue\", \"change\", \"focusChange\"]);\n\nconst api = useTabs(props, emit);\nprovideTabsContext(api);\n</script>\n\n<template>\n  <div v-bind=\"api.getRootProps()\" data-slot=\"tabs\" :class=\"cn(props.class)\">\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/ui/tabs/use-tabs-context.tsx",
          "target": "components/ui/tabs/use-tabs-context.tsx",
          "type": "registry:ui",
          "content": "import * as React from 'react'\n\nimport type { useTabs } from './use-tabs'\n\nexport type UseTabsReturn = ReturnType<typeof useTabs>\n\nconst TabsContext = React.createContext<UseTabsReturn | null>(null)\n\nexport function TabsProvider({\n  children,\n  value,\n}: {\n  children: React.ReactNode\n  value: UseTabsReturn\n}) {\n  return <TabsContext.Provider value={value}>{children}</TabsContext.Provider>\n}\n\nexport function useTabsContext() {\n  const context = React.useContext(TabsContext)\n  if (!context) {\n    throw new Error('useTabsContext must be used within a TabsProvider')\n  }\n  return context\n}\n"
        },
        {
          "path": "registry/default/ui/tabs/use-tabs.ts",
          "target": "components/ui/tabs/use-tabs.ts",
          "type": "registry:ui",
          "content": "import * as React from 'react'\nimport { tabsConnect, tabsMachine } from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/react'\n\nexport interface UseTabsProps {\n  value?: string\n  defaultValue?: string\n  onValueChange?: (value: string) => void\n  onFocusChange?: (value: string) => void\n  orientation?: 'horizontal' | 'vertical'\n  activationMode?: 'manual' | 'automatic'\n  loopFocus?: boolean\n  composite?: boolean\n  deselectable?: boolean\n  id?: string\n}\n\nexport function useTabs(props: UseTabsProps) {\n  const generatedId = React.useId()\n  const service = useMachine(tabsMachine, {\n    id: props.id ?? generatedId,\n    value: props.value,\n    defaultValue: props.defaultValue,\n    orientation: props.orientation,\n    activationMode: props.activationMode,\n    loopFocus: props.loopFocus,\n    composite: props.composite,\n    deselectable: props.deselectable,\n    onValueChange: (details) => props.onValueChange?.(details.value),\n    onFocusChange: (details) => props.onFocusChange?.(details.focusedValue),\n  })\n  const api = React.useMemo(() => tabsConnect(service, normalizeProps), [service])\n\n  return api\n}\n"
        },
        {
          "path": "registry/default/vue/tabs/tabs-content.vue",
          "target": "components/ui/tabs/tabs-content.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, inject } from \"vue\";\nimport { cn, tabsContentVariants } from \"@timui/core\";\nimport type { HTMLAttributes } from \"vue\";\nimport { useTabsContext } from \"./use-tabs-context\";\n\nconst props = defineProps<{ value: string; class?: HTMLAttributes[\"class\"] }>();\nconst api = useTabsContext();\nconst isSelected = computed(() => api.value.value === props.value);\nconst contentProps = computed(() =>\n  api.value.getContentProps?.({ value: props.value }) ?? {},\n);\n</script>\n\n<template>\n  <div\n    v-if=\"isSelected\"\n    v-bind=\"contentProps\"\n    data-slot=\"tabs-content\"\n    :data-state=\"isSelected ? 'active' : 'inactive'\"\n    :class=\"\n      cn(tabsContentVariants(), props.class)\n    \"\n  >\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/tabs/tabs-list.vue",
          "target": "components/ui/tabs/tabs-list.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, inject, type HTMLAttributes } from \"vue\";\nimport { cn, tabsListVariants } from \"@timui/core\";\nimport { useTabsContext } from \"./use-tabs-context\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\nconst api = useTabsContext();\nconst listProps = computed(() => api.value.getListProps?.() ?? {});\n</script>\n\n<template>\n  <div\n    v-bind=\"listProps\"\n    data-slot=\"tabs-list\"\n    :class=\"\n      cn(tabsListVariants(), props.class)\n    \"\n  >\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/tabs/tabs-trigger.vue",
          "target": "components/ui/tabs/tabs-trigger.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, inject, type Component, type HTMLAttributes } from \"vue\";\nimport { cn, tabsTriggerVariants } from \"@timui/core\";\nimport { Primitive } from '../../primitive';\nimport { useTabsContext } from \"./use-tabs-context\";\n\nconst props = defineProps<{\n  value: string;\n  as?: string | Component;\n  asChild?: boolean;\n  disabled?: boolean;\n  class?: HTMLAttributes[\"class\"];\n}>();\n\nconst api = useTabsContext();\nconst triggerProps = computed(() =>\n  api.value.getTriggerProps?.({ value: props.value, disabled: props.disabled }) ?? {},\n);\nconst isSelected = computed(() => api.value.value === props.value);\n</script>\n\n<template>\n  <Primitive\n    :as=\"props.as || 'button'\"\n    :as-child=\"props.asChild\"\n    :type=\"props.asChild ? undefined : 'button'\"\n    v-bind=\"triggerProps\"\n    data-slot=\"tabs-trigger\"\n    :data-state=\"isSelected ? 'active' : 'inactive'\"\n    :class=\"\n      cn(tabsTriggerVariants(), props.class)\n    \"\n  >\n    <slot />\n  </Primitive>\n</template>\n"
        },
        {
          "path": "registry/default/vue/tabs/tabs.vue",
          "target": "components/ui/tabs/tabs.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes } from \"vue\";\nimport { cn } from \"@timui/core\";\nimport { useTabs } from \"./use-tabs\";\nimport { provideTabsContext } from \"./use-tabs-context\";\n\nconst props = defineProps<{\n  modelValue?: string;\n  value?: string;\n  defaultValue?: string;\n  id?: string;\n  orientation?: \"horizontal\" | \"vertical\";\n  activationMode?: \"manual\" | \"automatic\";\n  loopFocus?: boolean;\n  composite?: boolean;\n  deselectable?: boolean;\n  onValueChange?: (value: string) => void;\n  onFocusChange?: (value: string) => void;\n  class?: HTMLAttributes[\"class\"];\n}>();\n\nconst emit = defineEmits([\"update:modelValue\", \"change\", \"focusChange\"]);\n\nconst api = useTabs(props, emit);\nprovideTabsContext(api);\n</script>\n\n<template>\n  <div v-bind=\"api.getRootProps()\" data-slot=\"tabs\" :class=\"cn(props.class)\">\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/tabs/use-tabs-context.ts",
          "target": "components/ui/tabs/use-tabs-context.ts",
          "type": "registry:component",
          "content": "import { inject, provide } from 'vue'\n\nimport type { useTabs } from './use-tabs'\n\nexport type UseTabsReturn = ReturnType<typeof useTabs>\n\nexport const TabsContextKey = Symbol('tabsContext')\n\nexport function provideTabsContext(context: UseTabsReturn) {\n  provide(TabsContextKey, context)\n}\n\nexport function useTabsContext() {\n  const context = inject<UseTabsReturn>(TabsContextKey)\n  if (!context) {\n    throw new Error('useTabsContext must be used within a Tabs root component')\n  }\n  return context\n}\n"
        },
        {
          "path": "registry/default/vue/tabs/use-tabs.ts",
          "target": "components/ui/tabs/use-tabs.ts",
          "type": "registry:component",
          "content": "import { tabsConnect, tabsMachine } from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/vue'\nimport { computed, useId } from 'vue'\n\nexport interface UseTabsProps {\n  modelValue?: string\n  value?: string\n  defaultValue?: string\n  id?: string\n  orientation?: 'horizontal' | 'vertical'\n  activationMode?: 'manual' | 'automatic'\n  loopFocus?: boolean\n  composite?: boolean\n  deselectable?: boolean\n  onValueChange?: (value: string) => void\n  onFocusChange?: (value: string) => void\n}\n\nexport interface UseTabsEmits {\n  (e: 'update:modelValue', value: string): void\n  (e: 'change', value: string): void\n  (e: 'focusChange', value: string): void\n}\n\nexport function useTabs(props: UseTabsProps, emit: UseTabsEmits) {\n  const generatedId = useId()\n\n  const machineProps = computed(() => {\n    const value = props.value ?? props.modelValue\n    return {\n      id: props.id ?? generatedId,\n      value,\n      defaultValue: value === undefined ? props.defaultValue : undefined,\n      orientation: props.orientation,\n      activationMode: props.activationMode,\n      loopFocus: props.loopFocus,\n      composite: props.composite,\n      deselectable: props.deselectable,\n      onValueChange(details: { value: string }) {\n        props.onValueChange?.(details.value)\n        emit('update:modelValue', details.value)\n        emit('change', details.value)\n      },\n      onFocusChange(details: { focusedValue: string }) {\n        props.onFocusChange?.(details.focusedValue)\n        emit('focusChange', details.focusedValue)\n      },\n    }\n  })\n\n  const service = useMachine(tabsMachine, machineProps)\n  const api = computed(() => tabsConnect(service, normalizeProps))\n\n  return api\n}\n"
        },
        {
          "path": "registry/default/html/tabs.html",
          "target": "components/ui/tabs.html",
          "type": "registry:component",
          "content": "<div data-timui-root data-timui-init=\"auto\">\n  <div data-slot=\"tabs\" data-orientation=\"horizontal\" class=\"w-full\">\n      <div data-slot=\"tabs-list\" class=\"inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground\">\n          <button data-slot=\"tabs-trigger\" data-state=\"active\" class=\"inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state&#x3D;active]:bg-background data-[state&#x3D;active]:text-foreground data-[state&#x3D;active]:shadow-sm\">Tab 1</button>\n          <button data-slot=\"tabs-trigger\" data-state=\"inactive\" class=\"inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state&#x3D;active]:bg-background data-[state&#x3D;active]:text-foreground data-[state&#x3D;active]:shadow-sm\">Tab 2</button>\n      </div>\n      <div data-slot=\"tabs-content\" data-state=\"active\" class=\"mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\">\n          Content 1\n      </div>\n      <div data-slot=\"tabs-content\" hidden data-state=\"inactive\" class=\"mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\">\n          Content 2\n      </div>\n  </div>\n</div>\n<script type=\"module\">\n  import { autoInitHtmlRuntime } from '@timui/html'\n  autoInitHtmlRuntime({ components: ['tabs'] })\n</script>"
        },
        {
          "path": "registry/default/weapp/tabs.wxml",
          "target": "components/ui/tabs.wxml",
          "type": "registry:component",
          "content": "<view class=\"tabs {{className}}\">\n  <view class=\"tabs-list flex items-center justify-center rounded-md bg-muted p-1 text-muted-foreground\">\n    <block wx:for=\"{{tabs}}\" wx:key=\"value\">\n      <view\n        class=\"tab-trigger inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all disabled:pointer-events-none disabled:opacity-50 {{activeValue === item.value ? 'bg-background text-foreground shadow-sm' : ''}}\"\n        style=\"min-height: 88rpx;\"\n        bindtap=\"handleTabClick\"\n        data-value=\"{{item.value}}\"\n      >\n        {{item.label}}\n      </view>\n    </block>\n  </view>\n  <view class=\"tabs-content mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\">\n    <slot></slot>\n  </view>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/tabs.wxss",
          "target": "components/ui/tabs.wxss",
          "type": "registry:component",
          "content": "/* Support utility classes if global styles are imported, otherwise basic fallback */\n.flex { display: flex; }\n.items-center { align-items: center; }\n.justify-center { justify-content: center; }\n.rounded-md { border-radius: 6px; }\n.rounded-sm { border-radius: 4px; }\n.bg-muted { background-color: #f4f4f5; }\n.text-muted-foreground { color: #71717a; }\n.p-1 { padding: 4px; }\n.mt-2 { margin-top: 8px; }\n.px-3 { padding-left: 12px; padding-right: 12px; }\n.py-1\\\\.5 { padding-top: 6px; padding-bottom: 6px; }\n.text-sm { font-size: 14px; }\n.font-medium { font-weight: 500; }\n.bg-background { background-color: #ffffff; }\n.text-foreground { color: #09090b; }\n.shadow-sm { box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); }\n"
        },
        {
          "path": "registry/default/weapp/tabs.ts",
          "target": "components/ui/tabs.ts",
          "type": "registry:component",
          "content": "import { setupTabsMachine } from './use-tabs'\n\ntype MachineEvent =\n  | string\n  | {\n      type: string\n      [key: string]: string | number | boolean | string[] | number[] | null | undefined\n    }\n\ntype TabsOrientation = 'horizontal' | 'vertical'\ntype TabsActivationMode = 'manual' | 'automatic'\n\ntype WeappTabsApi = Record<string, never>\ntype MachineSend = (event: MachineEvent) => void\n\ntype WeappService = {\n  setContext: (context: {\n    value?: string\n    orientation?: TabsOrientation\n    activationMode?: TabsActivationMode\n  }) => void\n}\n\ntype WeappTabsInternal = WechatMiniprogram.Component.InstanceMethods<WeappTabsApi> & {\n  _service?: WeappService\n  _cleanup?: () => void\n  _send?: (event: MachineEvent) => void\n  _connect?: (state: object, send: MachineSend) => WeappTabsApi\n  data: {\n    api: WeappTabsApi\n    activeValue?: string\n  }\n  properties: {\n    value: string\n    orientation: string\n    activationMode: string\n    id: string\n    extClass: string\n  }\n}\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    value: { type: String, value: '' },\n    orientation: { type: String, value: 'horizontal' },\n    activationMode: { type: String, value: 'automatic' },\n    id: { type: String, value: 'tabs' },\n    extClass: { type: String, value: '' },\n  },\n\n  data: {\n    api: {} as WeappTabsApi,\n    className: '',\n    activeValue: '',\n  },\n\n  lifetimes: {\n    attached() {\n      const self = this as WeappTabsInternal\n      const { controller, connect } = setupTabsMachine(self)\n\n      self._service = controller.service as WeappService\n      self._cleanup = controller.start()\n      self._send = controller.send as MachineSend\n      self._connect = connect\n    },\n    detached() {\n      const self = this as WeappTabsInternal\n      self._cleanup?.()\n    },\n  },\n\n  observers: {\n    state: function (state) {\n      const self = this as WeappTabsInternal\n      if (!state || !self._send || !self._connect) return\n      const api = self._connect(state, self._send) as WeappTabsApi\n      this.setData({ api, className: this.properties.extClass })\n    },\n\n    value: function (val) {\n      const self = this as WeappTabsInternal\n      if (self._service) {\n        self._service.setContext({ value: val })\n      }\n      if (typeof val === 'string' && val.length > 0) {\n        this.setData({ activeValue: val })\n      }\n    },\n  },\n\n  methods: {\n    handleTabClick(event: WechatMiniprogram.TouchEvent) {\n      const value = (event.currentTarget?.dataset?.value as string) || ''\n      if (!value) return\n      this.setData({ activeValue: value })\n      this._send?.({ type: 'VALUE.SET', value })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/tabs.json",
          "target": "components/ui/tabs.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        }
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@zag-js/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@zag-js/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "textarea",
      "type": "registry:ui",
      "files": [
        {
          "path": "registry/default/ui/textarea.tsx",
          "type": "registry:ui",
          "target": "components/ui/textarea.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport type { TextareaProps as CoreTextareaProps } from '@timui/core'\nimport { cn, createTimEvent, textareaVariants } from '@timui/core'\n\ntype TextareaProps = CoreTextareaProps &\n  Omit<React.ComponentProps<'textarea'>, keyof CoreTextareaProps>\n\nfunction Textarea({ className, id, onValueChange, onChange, ...props }: TextareaProps) {\n  const generatedId = React.useId()\n  const textareaId = id ?? generatedId\n  const handleChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {\n    onChange?.(event)\n    onValueChange?.(createTimEvent('change', textareaId, { value: event.target.value }))\n  }\n\n  return (\n    <textarea\n      data-slot=\"textarea\"\n      className={cn(textareaVariants(), className)}\n      onChange={handleChange}\n      {...props}\n    />\n  )\n}\nTextarea.displayName = 'Textarea'\n\nexport { Textarea }\n"
        },
        {
          "path": "registry/default/vue/textarea.vue",
          "type": "registry:ui",
          "target": "components/ui/textarea.vue",
          "content": "<script setup lang=\"ts\">\nimport type { AssertNoExtraKeys, TextareaVueProps, TextInputValueChangeEvent } from \"@timui/core\";\nimport { cn, textareaVariants, createTimEvent } from \"@timui/core\";\nimport { computed, type HTMLAttributes, useId } from \"vue\";\n\ntype TextareaProps = TextareaVueProps & { class?: HTMLAttributes[\"class\"] };\ntype _TextareaPropsGuard = AssertNoExtraKeys<\n  TextareaProps,\n  TextareaVueProps & { class?: HTMLAttributes[\"class\"] }\n>;\n\nconst props = defineProps<TextareaProps>();\n\nconst emits = defineEmits<{\n  (e: \"update:modelValue\", payload: string | number): void;\n  (e: \"valueChange\", event: TextInputValueChangeEvent): void;\n}>();\n\nconst modelValue = computed({\n  get: () => props.modelValue,\n  set: (value) => {\n    emits(\"update:modelValue\", value as string | number);\n  },\n});\n\nconst generatedId = useId()\nconst textareaId = computed(() => props.id ?? generatedId)\n\nconst handleChange = (event: Event) => {\n  const target = event.target as HTMLTextAreaElement\n  if (props.onValueChange) {\n    props.onValueChange(createTimEvent('change', textareaId.value, { value: target.value }))\n  }\n  emits('valueChange', createTimEvent('change', textareaId.value, { value: target.value }))\n}\n</script>\n\n<template>\n  <textarea\n    v-model=\"modelValue\"\n    data-slot=\"textarea\"\n    :id=\"textareaId\"\n    :class=\"cn(textareaVariants(), props.class)\"\n    @input=\"handleChange\"\n  />\n</template>\n"
        },
        {
          "path": "registry/default/vue/textarea/textarea.vue",
          "target": "components/ui/textarea/textarea.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport type { AssertNoExtraKeys, TextareaVueProps, TextInputValueChangeEvent } from \"@timui/core\";\nimport { cn, textareaVariants, createTimEvent } from \"@timui/core\";\nimport { computed, type HTMLAttributes, useId } from \"vue\";\n\ntype TextareaProps = TextareaVueProps & { class?: HTMLAttributes[\"class\"] };\ntype _TextareaPropsGuard = AssertNoExtraKeys<\n  TextareaProps,\n  TextareaVueProps & { class?: HTMLAttributes[\"class\"] }\n>;\n\nconst props = defineProps<TextareaProps>();\n\nconst emits = defineEmits<{\n  (e: \"update:modelValue\", payload: string | number): void;\n  (e: \"valueChange\", event: TextInputValueChangeEvent): void;\n}>();\n\nconst modelValue = computed({\n  get: () => props.modelValue,\n  set: (value) => {\n    emits(\"update:modelValue\", value as string | number);\n  },\n});\n\nconst generatedId = useId()\nconst textareaId = computed(() => props.id ?? generatedId)\n\nconst handleChange = (event: Event) => {\n  const target = event.target as HTMLTextAreaElement\n  if (props.onValueChange) {\n    props.onValueChange(createTimEvent('change', textareaId.value, { value: target.value }))\n  }\n  emits('valueChange', createTimEvent('change', textareaId.value, { value: target.value }))\n}\n</script>\n\n<template>\n  <textarea\n    v-model=\"modelValue\"\n    data-slot=\"textarea\"\n    :id=\"textareaId\"\n    :class=\"cn(textareaVariants(), props.class)\"\n    @input=\"handleChange\"\n  />\n</template>\n"
        },
        {
          "path": "registry/default/html/textarea.html",
          "target": "components/ui/textarea.html",
          "type": "registry:component",
          "content": "<textarea data-slot=\"textarea\" class=\"border-input placeholder:text-muted-foreground/70 focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive flex min-h-19.5 w-full rounded-md border bg-transparent px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50\"\n    placeholder=\"Type your message here.\"></textarea>"
        },
        {
          "path": "registry/default/weapp/textarea.wxml",
          "target": "components/ui/textarea.wxml",
          "type": "registry:component",
          "content": "<textarea \n  class=\"{{className}}\"\n  value=\"{{value}}\"\n  placeholder=\"{{placeholder}}\"\n  disabled=\"{{disabled}}\"\n  maxlength=\"{{maxlength}}\"\n  auto-height=\"{{autoHeight}}\"\n  focus=\"{{focus}}\"\n  adjust-position=\"{{true}}\"\n  cursor-spacing=\"{{16}}\"\n  bindinput=\"onInput\"\n  bindfocus=\"onFocus\"\n  bindblur=\"onBlur\"\n  bindconfirm=\"onConfirm\"\n/>\n"
        },
        {
          "path": "registry/default/weapp/textarea.wxss",
          "target": "components/ui/textarea.wxss",
          "type": "registry:component",
          "content": "/* packages/weapp/src/textarea/textarea.wxss */\n"
        },
        {
          "path": "registry/default/weapp/textarea.ts",
          "target": "components/ui/textarea.ts",
          "type": "registry:component",
          "content": "import { emitTimEvent, textareaVariants } from '../utils'\n\ntype WeappTextareaDetail = {\n  value: string\n}\n\ntype WeappTextareaEvent = WechatMiniprogram.CustomEvent<WeappTextareaDetail>\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    value: { type: String, value: '' },\n    placeholder: { type: String, value: '' },\n    disabled: { type: Boolean, value: false },\n    maxlength: { type: Number, value: -1 },\n    autoHeight: { type: Boolean, value: false },\n    focus: { type: Boolean, value: false },\n    id: { type: String, value: 'textarea' },\n    extClass: { type: String, value: '' },\n  },\n\n  data: {\n    className: '',\n  },\n\n  lifetimes: {\n    attached() {\n      this.updateClassName()\n    },\n  },\n\n  observers: {\n    extClass: function () {\n      this.updateClassName()\n    },\n  },\n\n  methods: {\n    updateClassName() {\n      // Use core package's textareaVariants for consistent styling\n      const { baseClass } = textareaVariants({\n        className: this.properties.extClass,\n      })\n\n      this.setData({ className: baseClass })\n    },\n\n    onInput(e: WeappTextareaEvent) {\n      this.setData({ value: e.detail.value })\n      this.triggerEvent('input', e.detail)\n      emitTimEvent(this, 'change', 'change', this.properties.id || 'textarea', {\n        value: e.detail.value,\n      })\n    },\n    onFocus(e: WeappTextareaEvent) {\n      this.triggerEvent('focus', e.detail)\n    },\n    onBlur(e: WeappTextareaEvent) {\n      this.triggerEvent('blur', e.detail)\n    },\n    onConfirm(e: WeappTextareaEvent) {\n      this.triggerEvent('confirm', e.detail)\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/textarea.json",
          "target": "components/ui/textarea.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        }
      ],
      "dependencies": [
        "@timui/core"
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "tags-input",
      "type": "registry:ui",
      "dependencies": [
        "@timui/core",
        "@zag-js/react"
      ],
      "registryDependencies": [
        "use-machine"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/ui/tags-input.tsx",
          "type": "registry:ui",
          "target": "components/ui/tags-input.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport {\n  cn,\n  createTimEvent,\n  tagsInputClearVariants,\n  tagsInputConnect,\n  tagsInputControlVariants,\n  tagsInputInputVariants,\n  tagsInputItemDeleteVariants,\n  tagsInputItemSelectedVariants,\n  tagsInputItemVariants,\n  tagsInputMachine,\n  tagsInputRootVariants,\n  type TagsInputProps as CoreTagsInputProps,\n  type TagsInputApi,\n  type TagsInputValueChangeDetails,\n} from '@timui/core'\nimport { XIcon } from 'lucide-react'\n\nimport { useTagsInput } from './tags-input/use-tags-input'\nimport { TagsInputProvider, useTagsInputContext } from './tags-input/use-tags-input-context'\n\n// Context is imported from ./tags-input/use-tags-input-context\n\ntype TagsInputProps = CoreTagsInputProps & {\n  className?: string\n  children?: React.ReactNode\n  onValueChangeDetails?: (details: TagsInputValueChangeDetails) => void\n}\n\nfunction TagsInput({\n  className,\n  children,\n  onValueChange,\n  onValueChangeDetails,\n  ...props\n}: TagsInputProps) {\n  const api = useTagsInput({\n    onValueChange,\n    onValueChangeDetails,\n    ...props,\n  })\n\n  return (\n    <TagsInputProvider value={api}>\n      <div {...api.getRootProps()} className={cn(tagsInputRootVariants(), className)}>\n        {children}\n      </div>\n    </TagsInputProvider>\n  )\n}\n\nfunction TagsInputControl({ className, children, ...props }: React.ComponentProps<'div'>) {\n  const api = useTagsInputContext()\n  return (\n    <div\n      {...api.getControlProps()}\n      className={cn(tagsInputControlVariants(), className)}\n      {...props}\n    >\n      {children}\n    </div>\n  )\n}\n\nfunction TagsInputInput({ className, ...props }: React.ComponentProps<'input'>) {\n  const api = useTagsInputContext()\n  return (\n    <input\n      {...api.getInputProps()}\n      className={cn(tagsInputInputVariants(), className)}\n      {...props}\n    />\n  )\n}\n\nfunction TagsInputItem({\n  index,\n  value,\n  className,\n  children,\n}: {\n  index: string | number\n  value: string\n  className?: string\n  children?: React.ReactNode\n}) {\n  const api = useTagsInputContext()\n  const itemState = api.getItemState({ index, value })\n  const isSelected =\n    'selected' in itemState && typeof itemState.selected === 'boolean' ? itemState.selected : false\n\n  return (\n    <div\n      {...api.getItemProps({ index, value })}\n      className={cn(\n        tagsInputItemVariants(),\n        isSelected ? tagsInputItemSelectedVariants() : '',\n        className\n      )}\n    >\n      <span className=\"leading-none\">{children ?? value}</span>\n      <button\n        {...api.getItemDeleteTriggerProps({ index, value })}\n        className={tagsInputItemDeleteVariants()}\n        type=\"button\"\n        aria-label=\"Remove tag\"\n      >\n        <XIcon className=\"h-3 w-3\" />\n      </button>\n      <input {...api.getItemInputProps({ index, value })} />\n    </div>\n  )\n}\n\nfunction TagsInputClearTrigger({ className, children, ...props }: React.ComponentProps<'button'>) {\n  const api = useTagsInputContext()\n  return (\n    <button\n      {...api.getClearTriggerProps()}\n      className={cn(tagsInputClearVariants(), className)}\n      {...props}\n    >\n      {children || 'Clear'}\n    </button>\n  )\n}\n\nexport { TagsInput, TagsInputControl, TagsInputInput, TagsInputItem, TagsInputClearTrigger }\n"
        },
        {
          "path": "registry/default/ui/tags-input/use-tags-input-context.ts",
          "target": "components/ui/tags-input/use-tags-input-context.ts",
          "type": "registry:ui",
          "content": "import * as React from 'react'\nimport type { TagsInputApi } from '@timui/core'\n\nexport type TagsInputContextValue = TagsInputApi\n\nconst TagsInputContext = React.createContext<TagsInputContextValue | null>(null)\n\nexport const TagsInputProvider: React.Provider<TagsInputContextValue | null> =\n  TagsInputContext.Provider\n\nexport function useTagsInputContext(): TagsInputContextValue {\n  const context = React.useContext(TagsInputContext)\n  if (!context) {\n    throw new Error('TagsInput components must be used within `<TagsInputProvider />`')\n  }\n  return context\n}\n"
        },
        {
          "path": "registry/default/ui/tags-input/use-tags-input.ts",
          "target": "components/ui/tags-input/use-tags-input.ts",
          "type": "registry:ui",
          "content": "import * as React from 'react'\nimport {\n  createTimEvent,\n  tagsInputConnect,\n  tagsInputMachine,\n  type TagsInputProps as CoreTagsInputProps,\n  type TagsInputApi,\n  type TagsInputValueChangeDetails,\n} from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/react'\n\nexport type UseTagsInputProps = CoreTagsInputProps & {\n  onValueChangeDetails?: (details: TagsInputValueChangeDetails) => void\n}\n\nexport function useTagsInput({\n  onValueChange,\n  onValueChangeDetails,\n  ...props\n}: UseTagsInputProps): TagsInputApi {\n  const generatedId = React.useId()\n  const tagsInputId = props.id ?? generatedId\n\n  const service = useMachine(tagsInputMachine, {\n    ...props,\n    id: tagsInputId,\n    onValueChange(details) {\n      onValueChangeDetails?.(details)\n      onValueChange?.(createTimEvent('change', tagsInputId, { value: details.value }))\n    },\n  })\n\n  return React.useMemo(() => {\n    return Array.isArray(service)\n      ? (\n          tagsInputConnect as never as (\n            state: never,\n            send: never,\n            props: typeof normalizeProps\n          ) => TagsInputApi\n        )(service[0] as never, service[1] as never, normalizeProps)\n      : tagsInputConnect(service as never, normalizeProps)\n  }, [service])\n}\n"
        },
        {
          "path": "registry/default/vue/tags-input/index.ts",
          "target": "components/ui/tags-input/index.ts",
          "type": "registry:component",
          "content": "export { default } from './tags-input.vue'\nexport { default as TagsInputClearTrigger } from './tags-input-clear-trigger.vue'\nexport { default as TagsInputControl } from './tags-input-control.vue'\nexport { default as TagsInputInput } from './tags-input-input.vue'\nexport { default as TagsInputItem } from './tags-input-item.vue'\nexport { default as TagsInput } from './tags-input.vue'\n"
        },
        {
          "path": "registry/default/vue/tags-input/tags-input-clear-trigger.vue",
          "target": "components/ui/tags-input/tags-input-clear-trigger.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { cn, tagsInputClearVariants } from \"@timui/core\";\nimport { useTagsInputContext } from \"./use-tags-input-context\";\nimport type { HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\nconst api = useTagsInputContext();\nconst clearProps = computed(() => api.value.getClearTriggerProps?.() ?? {});\n</script>\n\n<template>\n  <button v-bind=\"clearProps\" type=\"button\" data-slot=\"tags-input-clear\" :class=\"cn(tagsInputClearVariants(), props.class)\">\n    <slot>Clear</slot>\n  </button>\n</template>\n"
        },
        {
          "path": "registry/default/vue/tags-input/tags-input-control.vue",
          "target": "components/ui/tags-input/tags-input-control.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { cn, tagsInputControlVariants } from \"@timui/core\";\nimport { useTagsInputContext } from \"./use-tags-input-context\";\nimport type { HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\nconst api = useTagsInputContext();\nconst controlProps = computed(() => api.value.getControlProps?.() ?? {});\n</script>\n\n<template>\n  <div v-bind=\"controlProps\" data-slot=\"tags-input-control\" :class=\"cn(tagsInputControlVariants(), props.class)\">\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/tags-input/tags-input-input.vue",
          "target": "components/ui/tags-input/tags-input-input.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { cn, tagsInputInputVariants } from \"@timui/core\";\nimport { useTagsInputContext } from \"./use-tags-input-context\";\nimport type { HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\nconst api = useTagsInputContext();\nconst inputProps = computed(() => api.value.getInputProps?.() ?? {});\n</script>\n\n<template>\n  <input v-bind=\"inputProps\" data-slot=\"tags-input-input\" :class=\"cn(tagsInputInputVariants(), props.class)\" />\n</template>\n"
        },
        {
          "path": "registry/default/vue/tags-input/tags-input-item.vue",
          "target": "components/ui/tags-input/tags-input-item.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, provide } from \"vue\";\nimport { cn, tagsInputItemDeleteVariants, tagsInputItemSelectedVariants, tagsInputItemVariants } from \"@timui/core\";\nimport { useTagsInputContext } from \"./use-tags-input-context\";\nimport { XIcon } from \"lucide-vue-next\";\nimport type { HTMLAttributes } from \"vue\";\n\nexport type TagsInputItemContext = {\n  getRemoveTriggerProps: () => Record<string, string | number | boolean | undefined>;\n};\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"]; value: string; index: string | number }>();\n\nconst api = useTagsInputContext();\nconst itemProps = computed(() => api.value.getItemProps?.({ value: props.value, index: props.index, disabled: false }) ?? {});\nconst itemState = computed(() => api.value.getItemState?.({ value: props.value, index: props.index }));\nconst itemInputProps = computed(() => api.value.getItemInputProps?.({ value: props.value, index: props.index, disabled: false }) ?? {});\nconst deleteProps = computed(() => api.value.getItemDeleteTriggerProps?.({ value: props.value, index: props.index, disabled: false }) ?? {});\n\nconst itemContext = computed<TagsInputItemContext>(() => {\n  return {\n    getRemoveTriggerProps: () => api.value.getItemDeleteTriggerProps?.({ value: props.value, index: props.index, disabled: false }) ?? {},\n  };\n});\nprovide(\"tags-input-item\", itemContext);\n</script>\n\n<template>\n  <div\n    v-bind=\"itemProps\"\n    data-slot=\"tags-input-item\"\n    :class=\"\n      cn(\n        tagsInputItemVariants(),\n        tagsInputItemSelectedVariants(),\n        props.class\n      )\n    \"\n    :data-disabled=\"itemState?.disabled ? '' : undefined\"\n  >\n    <span class=\"leading-none\">\n      <slot>{{ props.value }}</slot>\n    </span>\n    <button\n      v-bind=\"deleteProps\"\n      type=\"button\"\n      data-slot=\"tags-input-item-delete\"\n      :class=\"tagsInputItemDeleteVariants()\"\n      aria-label=\"Remove tag\"\n    >\n      <XIcon class=\"w-4 h-4\" />\n    </button>\n    <input v-bind=\"itemInputProps\" />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/tags-input/tags-input.vue",
          "target": "components/ui/tags-input/tags-input.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { useId } from \"vue\";\nimport type {\n  AssertNoExtraKeys,\n  TagsInputVueProps as CoreTagsInputProps,\n  TagsInputValueChangeDetails,\n} from \"@timui/core\";\nimport { cn, tagsInputRootVariants } from \"@timui/core\";\nimport { useTagsInput } from \"./use-tags-input\";\nimport { provideTagsInputContext } from \"./use-tags-input-context\";\n\ntype TagsInputProps = CoreTagsInputProps & {\n  class?: string;\n};\ntype _TagsInputPropsGuard = AssertNoExtraKeys<TagsInputProps, CoreTagsInputProps & { class?: string }>;\n\nconst props = defineProps<TagsInputProps>();\nconst emit = defineEmits<{\n  (event: \"update:modelValue\", value: string[]): void;\n  (event: \"change\", value: string[]): void;\n  (event: \"valueChange\", details: TagsInputValueChangeDetails): void;\n}>();\n\nconst generatedId = useId();\nconst api = useTagsInput(\n  {\n    ...props,\n    id: props.id ?? generatedId,\n  },\n  emit\n);\n\nprovideTagsInputContext(api);\n</script>\n\n<template>\n  <div v-bind=\"api.getRootProps()\" data-slot=\"tags-input\" :class=\"cn(tagsInputRootVariants(), props.class)\">\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/tags-input/use-tags-input-context.ts",
          "target": "components/ui/tags-input/use-tags-input-context.ts",
          "type": "registry:component",
          "content": "import type { TagsInputApi } from '@timui/core'\nimport { inject, provide, type ComputedRef } from 'vue'\n\nexport const TagsInputContextKey = Symbol('TagsInputContext')\n\nexport function provideTagsInputContext(api: ComputedRef<TagsInputApi>) {\n  provide(TagsInputContextKey, api)\n}\n\nexport function useTagsInputContext(): ComputedRef<TagsInputApi> {\n  const context = inject<ComputedRef<TagsInputApi>>(TagsInputContextKey)\n  if (!context) {\n    throw new Error('useTagsInputContext must be used within a TagsInputProvider')\n  }\n  return context\n}\n"
        },
        {
          "path": "registry/default/vue/tags-input/use-tags-input.ts",
          "target": "components/ui/tags-input/use-tags-input.ts",
          "type": "registry:component",
          "content": "import {\n  tagsInputConnect,\n  tagsInputMachine,\n  type TagsInputApi,\n  type TagsInputValueChangeDetails,\n  type TagsInputVueProps,\n} from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/vue'\nimport { computed, useId, watch } from 'vue'\n\nexport type UseTagsInputProps = TagsInputVueProps\n\ntype TagsInputEmits = {\n  (event: 'update:modelValue', value: string[]): void\n  (event: 'change', value: string[]): void\n  (event: 'valueChange', details: TagsInputValueChangeDetails): void\n}\n\nconst isSameStringArray = (a: string[], b: string[]) => {\n  if (a.length !== b.length) return false\n  return a.every((item, index) => item === b[index])\n}\n\nexport function useTagsInput(props: UseTagsInputProps, emit?: TagsInputEmits) {\n  const generatedId = useId()\n  const currentValue = computed(() => props.modelValue ?? props.value)\n\n  const machineProps = computed(() => {\n    const {\n      modelValue: _modelValue,\n      value: _value,\n      defaultValue,\n      inputValue,\n      defaultInputValue,\n      onValueChange,\n      onInputValueChange,\n      ...rest\n    } = props\n\n    return {\n      ...rest,\n      id: props.id ?? generatedId,\n      value: currentValue.value,\n      defaultValue: currentValue.value === undefined ? defaultValue : undefined,\n      inputValue,\n      defaultInputValue: inputValue === undefined ? defaultInputValue : undefined,\n      onValueChange(details: TagsInputValueChangeDetails) {\n        onValueChange?.(details.value)\n        emit?.('valueChange', details)\n        emit?.('update:modelValue', details.value)\n        emit?.('change', details.value)\n      },\n      onInputValueChange(details: { inputValue: string }) {\n        onInputValueChange?.(details.inputValue)\n      },\n    }\n  })\n\n  const service = useMachine(tagsInputMachine, machineProps)\n  const api = computed(() => tagsInputConnect(service, normalizeProps))\n\n  watch(\n    () => currentValue.value,\n    (val) => {\n      if (!val) return\n      if (!isSameStringArray(val, api.value?.value ?? [])) {\n        api.value?.setValue(val)\n      }\n    }\n  )\n\n  return api\n}\n"
        },
        {
          "path": "registry/default/html/tags-input.html",
          "target": "components/ui/tags-input.html",
          "type": "registry:component",
          "content": "<div data-slot=\"tags-input\" class=\"w-full\">\n  <span class=\"rounded-md bg-muted px-2 py-1 text-xs\">ui</span>\n  <span class=\"rounded-md bg-muted px-2 py-1 text-xs\">multi-end</span>\n  <input class=\"min-w-24 flex-1 border-0 bg-transparent text-sm outline-none\" placeholder=\"Add tag...\" />\n</div>"
        },
        {
          "path": "registry/default/weapp/tags-input.wxml",
          "target": "components/ui/tags-input.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\" data-disabled=\"{{disabled}}\">\n  <!-- Tags List -->\n  <view class=\"tags-list\">\n    <view \n      wx:for=\"{{api.value}}\" \n      wx:key=\"index\"\n      class=\"tag-item\"\n      data-index=\"{{index}}\"\n    >\n      <text class=\"tag-text\">{{item}}</text>\n      <view \n        class=\"tag-delete\" \n        data-index=\"{{index}}\"\n        bindtap=\"onDeleteTag\"\n      >×</view>\n    </view>\n\n    <!-- Input -->\n    <input \n      wx:if=\"{{!api.isAtMax}}\"\n      class=\"tags-input\"\n      type=\"text\"\n      value=\"{{inputValue}}\"\n      placeholder=\"{{placeholder}}\"\n      disabled=\"{{disabled || readOnly}}\"\n      bindinput=\"onInput\"\n      bindconfirm=\"onConfirm\"\n    />\n  </view>\n\n  <!-- Max Indicator -->\n  <text wx:if=\"{{max < 999}}\" class=\"tags-count\">\n    {{api.value.length}} / {{max}}\n  </text>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/tags-input.wxss",
          "target": "components/ui/tags-input.wxss",
          "type": "registry:component",
          "content": "/* weapp component styles */\n"
        },
        {
          "path": "registry/default/weapp/tags-input.ts",
          "target": "components/ui/tags-input.ts",
          "type": "registry:component",
          "content": "import { emitTimEvent } from '../utils'\nimport { setupTagsInputMachine } from './use-tags-input'\n\ntype WeappTagsInputApi = {\n  addValue?: (value: string) => void\n  deleteValue?: (index: number) => void\n}\n\ntype WeappService = {\n  setContext: (context: Record<string, object>) => void\n}\n\ntype InputEvent = WechatMiniprogram.CustomEvent<{\n  value: string\n}>\n\ntype DeleteTagEvent = WechatMiniprogram.BaseEvent & {\n  currentTarget: {\n    dataset: {\n      index?: number\n    }\n  }\n}\n\ntype WeappTagsInputInternal =\n  WechatMiniprogram.Component.InstanceMethods<WechatMiniprogram.IAnyObject> & {\n    _service?: WeappService\n    _cleanup?: () => void\n    _send?: (event: object) => void\n    data: {\n      api: WeappTagsInputApi\n      inputValue: string\n    }\n    properties: {\n      value: string[]\n      max: number\n      disabled: boolean\n      readOnly: boolean\n      allowOverflow: boolean\n      placeholder: string\n      id: string\n      extClass: string\n    }\n  }\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    value: { type: Array, value: [] },\n    max: { type: Number, value: Number.MAX_SAFE_INTEGER },\n    disabled: { type: Boolean, value: false },\n    readOnly: { type: Boolean, value: false },\n    allowOverflow: { type: Boolean, value: false },\n    placeholder: { type: String, value: '添加标签...' },\n    id: { type: String, value: 'tags-input' },\n    extClass: { type: String, value: '' },\n  },\n\n  data: {\n    api: {} as WeappTagsInputApi,\n    className: '',\n    inputValue: '',\n  },\n\n  lifetimes: {\n    attached() {\n      const self = this as WeappTagsInputInternal\n      const { service, cleanup, send } = setupTagsInputMachine(this, {\n        id: this.properties.id,\n        value: this.properties.value,\n        max: this.properties.max,\n        disabled: this.properties.disabled,\n        readOnly: this.properties.readOnly,\n        allowOverflow: this.properties.allowOverflow,\n        onValueChange: (details) => {\n          emitTimEvent(this, 'change', 'change', this.properties.id || 'tags-input', {\n            value: details.value,\n          })\n        },\n      })\n\n      self._service = service as WeappService\n      self._cleanup = cleanup\n      self._send = send as (event: object) => void\n    },\n    detached() {\n      const self = this as WeappTagsInputInternal\n      self._cleanup?.()\n    },\n  },\n\n  observers: {\n    state: function (state) {\n      const self = this as WeappTagsInputInternal\n      if (!state || !self._send) return\n      const { connect } = setupTagsInputMachine(this, { id: this.properties.id })\n      const api = connect(state, self._send) as WeappTagsInputApi\n      this.setData({ api, className: this.properties.extClass })\n    },\n  },\n\n  methods: {\n    onInput(e: InputEvent) {\n      this.setData({ inputValue: e.detail.value })\n    },\n    onConfirm(e: InputEvent) {\n      const self = this as WeappTagsInputInternal\n      const value = e.detail.value.trim()\n      if (value && self.data.api.addValue) {\n        self.data.api.addValue(value)\n        this.setData({ inputValue: '' })\n      }\n    },\n    onDeleteTag(e: DeleteTagEvent) {\n      const self = this as WeappTagsInputInternal\n      const index = e.currentTarget.dataset.index\n      if (typeof index === 'number') {\n        self.data.api.deleteValue?.(index)\n      }\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/tags-input.json",
          "target": "components/ui/tags-input.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        }
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@zag-js/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@zag-js/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "timeline",
      "type": "registry:ui",
      "dependencies": [
        "@timui/core"
      ],
      "files": [
        {
          "path": "registry/default/ui/timeline.tsx",
          "type": "registry:ui",
          "target": "components/ui/timeline.tsx",
          "content": "'use client'\nimport * as React from 'react'\nimport type { AssertNoExtraKeys, TimelineProps as CoreTimelineProps } from '@timui/core'\nimport {\n  cn,\n  timelineContentVariants,\n  timelineDateVariants,\n  timelineHeaderVariants,\n  timelineIndicatorVariants,\n  timelineItemVariants,\n  timelineSeparatorVariants,\n  timelineTitleVariants,\n  timelineVariants,\n} from '@timui/core'\n\nimport { Slot } from './slot'\n\n// Types\ntype TimelineContextValue = {\n  activeStep: number\n}\n\n// Context\nconst TimelineContext = React.createContext<TimelineContextValue | undefined>(undefined)\n\nconst useTimeline = () => {\n  const context = React.useContext(TimelineContext)\n  if (!context) {\n    throw new Error('useTimeline must be used within a Timeline')\n  }\n  return context\n}\n\n// Components\ntype TimelineProps = CoreTimelineProps & React.HTMLAttributes<HTMLDivElement>\ntype _TimelinePropsGuard = AssertNoExtraKeys<\n  TimelineProps,\n  CoreTimelineProps & React.HTMLAttributes<HTMLDivElement>\n>\n\nfunction Timeline({\n  defaultValue = 1,\n  value,\n  orientation = 'vertical',\n  className,\n  ...props\n}: TimelineProps) {\n  const currentStep = value ?? defaultValue\n\n  return (\n    <TimelineContext.Provider value={{ activeStep: currentStep }}>\n      <div\n        data-slot=\"timeline\"\n        className={cn(timelineVariants(), className)}\n        data-orientation={orientation}\n        {...props}\n      />\n    </TimelineContext.Provider>\n  )\n}\n\n// TimelineContent\nfunction TimelineContent({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n  return (\n    <div\n      data-slot=\"timeline-content\"\n      className={cn(timelineContentVariants(), className)}\n      {...props}\n    />\n  )\n}\n\n// TimelineDate\ninterface TimelineDateProps extends React.HTMLAttributes<HTMLTimeElement> {\n  asChild?: boolean\n}\n\nfunction TimelineDate({ asChild = false, className, ...props }: TimelineDateProps) {\n  const Comp = asChild ? Slot : 'time'\n\n  return (\n    <Comp data-slot=\"timeline-date\" className={cn(timelineDateVariants(), className)} {...props} />\n  )\n}\n\n// TimelineHeader\nfunction TimelineHeader({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n  return (\n    <div\n      data-slot=\"timeline-header\"\n      className={cn(timelineHeaderVariants(), className)}\n      {...props}\n    />\n  )\n}\n\n// TimelineIndicator\ninterface TimelineIndicatorProps extends React.HTMLAttributes<HTMLDivElement> {\n  asChild?: boolean\n}\n\nfunction TimelineIndicator({\n  asChild = false,\n  className,\n  children,\n  ...props\n}: TimelineIndicatorProps) {\n  return (\n    <div\n      data-slot=\"timeline-indicator\"\n      className={cn(timelineIndicatorVariants(), className)}\n      aria-hidden=\"true\"\n      {...props}\n    >\n      {children}\n    </div>\n  )\n}\n\n// TimelineItem\ninterface TimelineItemProps extends React.HTMLAttributes<HTMLDivElement> {\n  step: number\n}\n\nfunction TimelineItem({ step, className, ...props }: TimelineItemProps) {\n  const { activeStep } = useTimeline()\n\n  return (\n    <div\n      data-slot=\"timeline-item\"\n      className={cn(timelineItemVariants(), className)}\n      data-completed={step <= activeStep || undefined}\n      {...props}\n    />\n  )\n}\n\n// TimelineSeparator\nfunction TimelineSeparator({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n  return (\n    <div\n      data-slot=\"timeline-separator\"\n      className={cn(timelineSeparatorVariants(), className)}\n      aria-hidden=\"true\"\n      {...props}\n    />\n  )\n}\n\n// TimelineTitle\nfunction TimelineTitle({ className, ...props }: React.HTMLAttributes<HTMLHeadingElement>) {\n  return (\n    <h3 data-slot=\"timeline-title\" className={cn(timelineTitleVariants(), className)} {...props} />\n  )\n}\n\nexport {\n  Timeline,\n  TimelineContent,\n  TimelineDate,\n  TimelineHeader,\n  TimelineIndicator,\n  TimelineItem,\n  TimelineSeparator,\n  TimelineTitle,\n}\n"
        },
        {
          "path": "registry/default/vue/timeline/timeline-content.vue",
          "target": "components/ui/timeline/timeline-content.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes } from \"vue\";\nimport { cn, timelineContentVariants } from '@timui/core';\n\nconst props = defineProps<{\n  class?: HTMLAttributes[\"class\"];\n}>();\n</script>\n\n<template>\n  <div\n    data-slot=\"timeline-content\"\n    :class=\"cn(timelineContentVariants(), props.class)\"\n  >\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/timeline/timeline-context.ts",
          "target": "components/ui/timeline/timeline-context.ts",
          "type": "registry:component",
          "content": "import { createContext } from 'radix-vue'\nimport type { Ref } from 'vue'\n\nexport interface TimelineContextValue {\n  activeStep: Ref<number>\n  setActiveStep: (step: number) => void\n  orientation: Ref<'horizontal' | 'vertical'>\n}\n\nexport const [injectTimelineContext, provideTimelineContext] =\n  createContext<TimelineContextValue>('Timeline')\n"
        },
        {
          "path": "registry/default/vue/timeline/timeline-date.vue",
          "target": "components/ui/timeline/timeline-date.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes } from \"vue\";\nimport { Primitive, type PrimitiveProps } from '../../primitive';\nimport { cn, timelineDateVariants } from '@timui/core';\n\nconst props = withDefaults(\n  defineProps<PrimitiveProps & { class?: HTMLAttributes[\"class\"] }>(),\n  {\n    as: \"time\",\n  }\n);\n</script>\n\n<template>\n  <Primitive\n    data-slot=\"timeline-date\"\n    :as=\"as\"\n    :as-child=\"asChild\"\n    :class=\"cn(timelineDateVariants(), props.class)\"\n  >\n    <slot />\n  </Primitive>\n</template>\n"
        },
        {
          "path": "registry/default/vue/timeline/timeline-header.vue",
          "target": "components/ui/timeline/timeline-header.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes } from \"vue\";\nimport { cn, timelineHeaderVariants } from '@timui/core';\n\nconst props = defineProps<{\n  class?: HTMLAttributes[\"class\"];\n}>();\n</script>\n\n<template>\n  <div data-slot=\"timeline-header\" :class=\"cn(timelineHeaderVariants(), props.class)\">\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/timeline/timeline-indicator.vue",
          "target": "components/ui/timeline/timeline-indicator.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes } from \"vue\";\nimport { Primitive, type PrimitiveProps } from '../../primitive';\nimport { cn, timelineIndicatorVariants } from '@timui/core';\n\nconst props = defineProps<PrimitiveProps & { class?: HTMLAttributes[\"class\"] }>();\n</script>\n\n<template>\n  <Primitive\n    data-slot=\"timeline-indicator\"\n    :as=\"as\"\n    :as-child=\"asChild\"\n    :class=\"cn(timelineIndicatorVariants(), props.class)\"\n    aria-hidden=\"true\"\n  >\n    <slot />\n  </Primitive>\n</template>\n"
        },
        {
          "path": "registry/default/vue/timeline/timeline-item.vue",
          "target": "components/ui/timeline/timeline-item.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes } from \"vue\";\nimport { cn, timelineItemVariants } from '@timui/core';\nimport { injectTimelineContext } from \"./timeline-context\";\n\nconst props = defineProps<{\n  step: number;\n  class?: HTMLAttributes[\"class\"];\n}>();\n\nconst context = injectTimelineContext();\n\nif (!context) {\n  throw new Error(\"TimelineItem must be used within a Timeline\");\n}\n</script>\n\n<template>\n  <div\n    data-slot=\"timeline-item\"\n    :class=\"cn(timelineItemVariants(), props.class)\"\n    :data-completed=\"props.step <= context.activeStep.value ? '' : undefined\"\n  >\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/timeline/timeline-separator.vue",
          "target": "components/ui/timeline/timeline-separator.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes } from \"vue\";\nimport { cn, timelineSeparatorVariants } from '@timui/core';\n\nconst props = defineProps<{\n  class?: HTMLAttributes[\"class\"];\n}>();\n</script>\n\n<template>\n  <div\n    data-slot=\"timeline-separator\"\n    :class=\"cn(timelineSeparatorVariants(), props.class)\"\n    aria-hidden=\"true\"\n  />\n</template>\n"
        },
        {
          "path": "registry/default/vue/timeline/timeline-title.vue",
          "target": "components/ui/timeline/timeline-title.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes } from \"vue\";\nimport { cn, timelineTitleVariants } from '@timui/core';\n\nconst props = defineProps<{\n  class?: HTMLAttributes[\"class\"];\n}>();\n</script>\n\n<template>\n  <h3 data-slot=\"timeline-title\" :class=\"cn(timelineTitleVariants(), props.class)\">\n    <slot />\n  </h3>\n</template>\n"
        },
        {
          "path": "registry/default/vue/timeline/timeline.vue",
          "target": "components/ui/timeline/timeline.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed, ref, toRef } from \"vue\";\nimport { cn, timelineVariants } from '@timui/core';\nimport { provideTimelineContext } from \"./timeline-context\";\n\nconst props = withDefaults(\n  defineProps<{\n    class?: HTMLAttributes[\"class\"];\n    defaultValue?: number;\n    modelValue?: number;\n    orientation?: \"horizontal\" | \"vertical\";\n  }>(),\n  {\n    defaultValue: 1,\n    orientation: \"vertical\",\n  }\n);\n\nconst emits = defineEmits<{\n  (e: \"update:modelValue\", payload: number): void;\n}>();\n\nconst internalStep = ref(props.defaultValue);\nconst step = computed({\n  get: () => props.modelValue ?? internalStep.value,\n  set: (v) => {\n    internalStep.value = v;\n    emits(\"update:modelValue\", v);\n  },\n});\n\nprovideTimelineContext({\n  activeStep: step,\n  setActiveStep: (v: number) => {\n    step.value = v;\n  },\n  orientation: toRef(props, \"orientation\"),\n});\n</script>\n\n<template>\n  <div\n    data-slot=\"timeline\"\n    :class=\"cn(timelineVariants(), props.class)\"\n    :data-orientation=\"orientation\"\n  >\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/html/timeline.html",
          "target": "components/ui/timeline.html",
          "type": "registry:component",
          "content": "<ol data-slot=\"timeline\" class=\"space-y-4\">\n  <li class=\"flex gap-3\">\n    <span class=\"mt-1 inline-block h-2 w-2 rounded-full bg-primary\"></span>\n    <div>\n      <p class=\"text-sm font-medium\">Design Contract</p>\n      <p class=\"text-xs text-muted-foreground\">Define schema and variants.</p>\n    </div>\n  </li>\n  <li class=\"flex gap-3\">\n    <span class=\"mt-1 inline-block h-2 w-2 rounded-full bg-primary\"></span>\n    <div>\n      <p class=\"text-sm font-medium\">Multi-end Adapter</p>\n      <p class=\"text-xs text-muted-foreground\">Implement React/Vue/WeApp/HTML.</p>\n    </div>\n  </li>\n</ol>"
        },
        {
          "path": "registry/default/weapp/timeline.wxml",
          "target": "components/ui/timeline.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}} timeline\">\n  <view \n    wx:for=\"{{items}}\" \n    wx:key=\"index\"\n    class=\"timeline-item\"\n    data-last=\"{{index === items.length - 1}}\"\n  >\n    <!-- Dot -->\n    <view class=\"timeline-dot\" data-type=\"{{item.type || 'default'}}\"></view>\n    \n    <!-- Line -->\n    <view \n      wx:if=\"{{index < items.length - 1}}\"\n      class=\"timeline-line\"\n    ></view>\n\n    <!-- Content -->\n    <view class=\"timeline-content\">\n      <view class=\"timeline-title\">{{item.title}}</view>\n      <view wx:if=\"{{item.description}}\" class=\"timeline-description\">\n        {{item.description}}\n      </view>\n      <view wx:if=\"{{item.time}}\" class=\"timeline-time\">\n        {{item.time}}\n      </view>\n    </view>\n  </view>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/timeline.wxss",
          "target": "components/ui/timeline.wxss",
          "type": "registry:component",
          "content": "/* weapp component styles */\n"
        },
        {
          "path": "registry/default/weapp/timeline.ts",
          "target": "components/ui/timeline.ts",
          "type": "registry:component",
          "content": "import { timelineVariants } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    items: { type: Array, value: [] },\n    orientation: { type: String, value: 'vertical' },\n    extClass: { type: String, value: '' },\n  },\n\n  data: {\n    className: '',\n  },\n\n  lifetimes: {\n    attached() {\n      this.updateClassName()\n    },\n  },\n\n  observers: {\n    'orientation, extClass': function () {\n      this.updateClassName()\n    },\n  },\n\n  methods: {\n    updateClassName() {\n      // Use core package's timelineVariants for consistent styling\n      const { baseClass } = timelineVariants({\n        className: this.properties.extClass,\n      })\n\n      this.setData({ className: baseClass })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/timeline.json",
          "target": "components/ui/timeline.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        }
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core"
            ],
            "optionalPeerDependencies": [
              "radix-vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "toast",
      "type": "registry:ui",
      "dependencies": [
        "@timui/core"
      ],
      "registryDependencies": [
        "use-toast"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/ui/toast.tsx",
          "type": "registry:ui",
          "target": "components/ui/toast.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport {\n  cn,\n  toastActionVariants,\n  toastCloseVariants,\n  toastDescriptionVariants,\n  toastTitleVariants,\n  toastVariants,\n  toastViewportVariants,\n  type ToastVariants,\n} from '@timui/core'\nimport { XIcon } from 'lucide-react'\n\nimport { Slot } from './slot'\n\n// Simple Context\nconst ToastContext = React.createContext<{\n  close: () => void\n} | null>(null)\n\ntype ToastProviderProps = {\n  children: React.ReactNode\n  swipeDirection?: 'left' | 'right' | 'up' | 'down'\n}\n\nconst ToastProvider = ({ children, swipeDirection: _swipeDirection }: ToastProviderProps) => {\n  void _swipeDirection\n  return <>{children}</>\n}\n\nfunction ToastViewport({ className, ...props }: React.HTMLAttributes<HTMLOListElement>) {\n  return <ol className={cn(toastViewportVariants(), className)} {...props} />\n}\n\nconst Toast = React.forwardRef<\n  HTMLLIElement,\n  React.HTMLAttributes<HTMLLIElement> &\n    ToastVariants & {\n      open?: boolean\n      onOpenChange?: (open: boolean) => void\n      onPause?: () => void\n      onResume?: () => void\n    }\n>(\n  (\n    { className, variant, open, onOpenChange, onPause: _onPause, onResume: _onResume, ...props },\n    ref\n  ) => {\n    void _onPause\n    void _onResume\n\n    const handleClose = () => {\n      onOpenChange?.(false)\n    }\n\n    // Animation state handling using simple data attributes\n    // In a real implementation without Radix, we need 'mounting' logic or keeping it mounted until animation ends.\n    // 'use-toast' handles removing from array after delay.\n    // So we just render 'open' style or 'closed' style.\n\n    if (open === false) return null // Or animate out?\n    // Radix stays mounted for animation.\n\n    return (\n      <ToastContext.Provider value={{ close: handleClose }}>\n        <li\n          ref={ref}\n          data-state={open ? 'open' : 'closed'}\n          className={cn(toastVariants({ variant }), className)}\n          {...props}\n        />\n      </ToastContext.Provider>\n    )\n  }\n)\nToast.displayName = 'Toast'\n\ntype ToastActionProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {\n  altText?: string\n  asChild?: boolean\n}\n\nconst ToastAction = React.forwardRef<HTMLButtonElement, ToastActionProps>(\n  ({ className, altText: _altText, asChild, ...props }, ref) => {\n    void _altText\n    const sharedProps = {\n      className: cn(toastActionVariants(), className),\n      ...props,\n    }\n\n    if (asChild) {\n      return <Slot ref={ref as React.Ref<HTMLElement>} {...sharedProps} />\n    }\n\n    return <button ref={ref} {...sharedProps} />\n  }\n)\nToastAction.displayName = 'ToastAction'\n\ntype ToastCloseProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {\n  asChild?: boolean\n}\n\nconst ToastClose = React.forwardRef<HTMLButtonElement, ToastCloseProps>(\n  ({ className, onClick, asChild, children, ...props }, ref) => {\n    const context = React.useContext(ToastContext)\n\n    const sharedProps = {\n      className: cn(toastCloseVariants(), className),\n      onClick: (e: React.MouseEvent<HTMLButtonElement>) => {\n        context?.close()\n        onClick?.(e)\n      },\n      'toast-close': '',\n      ...props,\n    }\n\n    if (asChild) {\n      return (\n        <Slot ref={ref as React.Ref<HTMLElement>} {...sharedProps}>\n          {children}\n        </Slot>\n      )\n    }\n\n    return (\n      <button ref={ref} {...sharedProps}>\n        {children ?? <XIcon className=\"h-4 w-4\" />}\n      </button>\n    )\n  }\n)\nToastClose.displayName = 'ToastClose'\n\nconst ToastTitle = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, ...props }, ref) => (\n    <div ref={ref} className={cn(toastTitleVariants(), className)} {...props} />\n  )\n)\nToastTitle.displayName = 'ToastTitle'\n\nconst ToastDescription = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, ...props }, ref) => (\n    <div ref={ref} className={cn(toastDescriptionVariants(), className)} {...props} />\n  )\n)\nToastDescription.displayName = 'ToastDescription'\n\ntype ToastProps = React.ComponentPropsWithoutRef<typeof Toast>\ntype ToastActionElement = React.ReactElement<typeof ToastAction>\n\nexport {\n  ToastProvider,\n  ToastViewport,\n  Toast,\n  ToastTitle,\n  ToastDescription,\n  ToastClose,\n  ToastAction,\n  type ToastProps,\n  type ToastActionElement,\n}\n"
        },
        {
          "path": "registry/default/hooks/use-toast.ts",
          "type": "registry:hook",
          "target": "components/ui/toast/use-toast.ts",
          "content": "'use client'\n\n// Inspired by react-hot-toast library\nimport * as React from 'react'\n\nimport type { ToastActionElement, ToastProps } from '../components/ui/toast'\n\nconst TOAST_LIMIT = 1\nconst TOAST_REMOVE_DELAY = 1000000\n\ntype ToasterToast = ToastProps & {\n  id: string\n  title?: React.ReactNode\n  description?: React.ReactNode\n  action?: ToastActionElement\n}\n\nconst actionTypes = {\n  ADD_TOAST: 'ADD_TOAST',\n  UPDATE_TOAST: 'UPDATE_TOAST',\n  DISMISS_TOAST: 'DISMISS_TOAST',\n  REMOVE_TOAST: 'REMOVE_TOAST',\n} as const\n\nlet count = 0\n\nfunction genId() {\n  count = (count + 1) % Number.MAX_SAFE_INTEGER\n  return count.toString()\n}\n\ntype ActionType = typeof actionTypes\n\ntype Action =\n  | {\n      type: ActionType['ADD_TOAST']\n      toast: ToasterToast\n    }\n  | {\n      type: ActionType['UPDATE_TOAST']\n      toast: Partial<ToasterToast>\n    }\n  | {\n      type: ActionType['DISMISS_TOAST']\n      toastId?: ToasterToast['id']\n    }\n  | {\n      type: ActionType['REMOVE_TOAST']\n      toastId?: ToasterToast['id']\n    }\n\ninterface State {\n  toasts: ToasterToast[]\n}\n\nconst toastTimeouts = new Map<string, ReturnType<typeof setTimeout>>()\n\nconst addToRemoveQueue = (toastId: string) => {\n  if (toastTimeouts.has(toastId)) {\n    return\n  }\n\n  const timeout = setTimeout(() => {\n    toastTimeouts.delete(toastId)\n    dispatch({\n      type: 'REMOVE_TOAST',\n      toastId: toastId,\n    })\n  }, TOAST_REMOVE_DELAY)\n\n  toastTimeouts.set(toastId, timeout)\n}\n\nexport const reducer = (state: State, action: Action): State => {\n  switch (action.type) {\n    case 'ADD_TOAST':\n      return {\n        ...state,\n        toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT),\n      }\n\n    case 'UPDATE_TOAST':\n      return {\n        ...state,\n        toasts: state.toasts.map((t) => (t.id === action.toast.id ? { ...t, ...action.toast } : t)),\n      }\n\n    case 'DISMISS_TOAST': {\n      const { toastId } = action\n\n      // ! Side effects ! - This could be extracted into a dismissToast() action,\n      // but I'll keep it here for simplicity\n      if (toastId) {\n        addToRemoveQueue(toastId)\n      } else {\n        state.toasts.forEach((toast) => {\n          addToRemoveQueue(toast.id)\n        })\n      }\n\n      return {\n        ...state,\n        toasts: state.toasts.map((t) =>\n          t.id === toastId || toastId === undefined\n            ? {\n                ...t,\n                open: false,\n              }\n            : t\n        ),\n      }\n    }\n    case 'REMOVE_TOAST':\n      if (action.toastId === undefined) {\n        return {\n          ...state,\n          toasts: [],\n        }\n      }\n      return {\n        ...state,\n        toasts: state.toasts.filter((t) => t.id !== action.toastId),\n      }\n  }\n}\n\nconst listeners: Array<(state: State) => void> = []\n\nlet memoryState: State = { toasts: [] }\n\nfunction dispatch(action: Action) {\n  memoryState = reducer(memoryState, action)\n  listeners.forEach((listener) => {\n    listener(memoryState)\n  })\n}\n\ntype Toast = Omit<ToasterToast, 'id'>\n\nfunction toast({ ...props }: Toast) {\n  const id = genId()\n\n  const update = (props: ToasterToast) =>\n    dispatch({\n      type: 'UPDATE_TOAST',\n      toast: { ...props, id },\n    })\n  const dismiss = () => dispatch({ type: 'DISMISS_TOAST', toastId: id })\n\n  dispatch({\n    type: 'ADD_TOAST',\n    toast: {\n      ...props,\n      id,\n      open: true,\n      onOpenChange: (open) => {\n        if (!open) dismiss()\n      },\n    },\n  })\n\n  return {\n    id: id,\n    dismiss,\n    update,\n  }\n}\n\nfunction useToast() {\n  const [state, setState] = React.useState<State>(memoryState)\n\n  React.useEffect(() => {\n    listeners.push(setState)\n    return () => {\n      const index = listeners.indexOf(setState)\n      if (index > -1) {\n        listeners.splice(index, 1)\n      }\n    }\n  }, [state])\n\n  return {\n    ...state,\n    toast,\n    dismiss: (toastId?: string) => dispatch({ type: 'DISMISS_TOAST', toastId }),\n  }\n}\n\nexport { toast, useToast }\n"
        },
        {
          "path": "registry/default/ui/toaster.tsx",
          "type": "registry:ui",
          "target": "components/ui/toaster.tsx",
          "content": "'use client'\n\nimport { useToast } from '../hooks/use-toast'\nimport {\n  Toast,\n  ToastClose,\n  ToastDescription,\n  ToastProvider,\n  ToastTitle,\n  ToastViewport,\n} from './toast'\n\nexport function Toaster() {\n  const { toasts } = useToast()\n\n  return (\n    <ToastProvider>\n      {toasts.map(function ({ id, title, description, action, ...props }) {\n        return (\n          <Toast key={id} {...props}>\n            <div className=\"flex w-full justify-between gap-2\">\n              <div className=\"flex flex-col gap-3\">\n                <div className=\"space-y-1\">\n                  {title && <ToastTitle>{title}</ToastTitle>}\n                  {description && <ToastDescription>{description}</ToastDescription>}\n                </div>\n                <div>{action}</div>\n              </div>\n              <div>\n                <ToastClose />\n              </div>\n            </div>\n          </Toast>\n        )\n      })}\n      <ToastViewport />\n    </ToastProvider>\n  )\n}\n"
        },
        {
          "path": "registry/default/vue/toast/index.ts",
          "target": "components/ui/toast/index.ts",
          "type": "registry:component",
          "content": "export { default } from './toast.vue'\nexport { default as ToastAction } from './toast-action.vue'\nexport { default as ToastClose } from './toast-close.vue'\nexport { default as ToastDescription } from './toast-description.vue'\nexport { default as ToastProvider } from './toast-provider.vue'\nexport { default as ToastTitle } from './toast-title.vue'\nexport { default as ToastViewport } from './toast-viewport.vue'\nexport { default as Toast } from './toast.vue'\n"
        },
        {
          "path": "registry/default/vue/toast/toast-action.vue",
          "target": "components/ui/toast/toast-action.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, toastActionVariants } from \"@timui/core\";\nimport type { HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\n</script>\n\n<template>\n  <button\n    :class=\"\n      cn(\n        toastActionVariants(),\n        props.class\n      )\n    \"\n  >\n    <slot />\n  </button>\n</template>\n"
        },
        {
          "path": "registry/default/vue/toast/toast-close.vue",
          "target": "components/ui/toast/toast-close.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { inject } from \"vue\";\nimport { XIcon } from \"lucide-vue-next\";\nimport { cn, toastCloseVariants } from \"@timui/core\";\nimport type { HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\nconst toast = inject(\"toast\") as { close?: () => void } | null;\n</script>\n\n<template>\n  <button\n    :class=\"\n      cn(\n        toastCloseVariants(),\n        props.class\n      )\n    \"\n    @click=\"toast?.close?.()\"\n  >\n    <XIcon class=\"h-4 w-4\" />\n  </button>\n</template>\n"
        },
        {
          "path": "registry/default/vue/toast/toast-description.vue",
          "target": "components/ui/toast/toast-description.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, toastDescriptionVariants } from \"@timui/core\";\nimport type { HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\n</script>\n\n<template>\n  <div :class=\"cn(toastDescriptionVariants(), props.class)\">\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/toast/toast-provider.vue",
          "target": "components/ui/toast/toast-provider.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\n</script>\n\n<template>\n  <slot />\n</template>\n"
        },
        {
          "path": "registry/default/vue/toast/toast-title.vue",
          "target": "components/ui/toast/toast-title.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, toastTitleVariants } from \"@timui/core\";\nimport type { HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\n</script>\n\n<template>\n  <div :class=\"cn(toastTitleVariants(), props.class)\">\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/toast/toast-viewport.vue",
          "target": "components/ui/toast/toast-viewport.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, toastViewportVariants } from \"@timui/core\";\nimport type { HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\n</script>\n\n<template>\n  <ol\n    :class=\"\n      cn(\n        toastViewportVariants(),\n        props.class\n      )\n    \"\n  >\n    <slot />\n  </ol>\n</template>\n"
        },
        {
          "path": "registry/default/vue/toast/toast.vue",
          "target": "components/ui/toast/toast.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, toastVariants, type ToastVariants } from \"@timui/core\";\nimport { computed, provide, type HTMLAttributes } from \"vue\";\n\nconst props = withDefaults(\n  defineProps<{\n    open?: boolean;\n    class?: HTMLAttributes[\"class\"];\n    variant?: ToastVariants[\"variant\"];\n    onOpenChange?: (open: boolean) => void;\n    onPause?: () => void;\n    onResume?: () => void;\n  }>(),\n  {\n    variant: \"default\",\n  }\n);\n\nconst emit = defineEmits([\"update:open\", \"openChange\", \"pause\", \"resume\"]);\n\nconst computedClass = computed(() => cn(toastVariants({ variant: props.variant }), props.class));\n\nconst close = () => {\n  props.onOpenChange?.(false);\n  emit(\"update:open\", false);\n  emit(\"openChange\", false);\n};\n\nconst handlePause = () => {\n  props.onPause?.();\n  emit(\"pause\");\n};\n\nconst handleResume = () => {\n  props.onResume?.();\n  emit(\"resume\");\n};\n\nprovide(\"toast\", { close });\n</script>\n\n<template>\n  <li\n    v-if=\"props.open !== false\"\n    :data-state=\"props.open ? 'open' : 'closed'\"\n    :class=\"computedClass\"\n    @mouseenter=\"handlePause\"\n    @mouseleave=\"handleResume\"\n    @focusin=\"handlePause\"\n    @focusout=\"handleResume\"\n  >\n    <slot />\n  </li>\n</template>\n"
        },
        {
          "path": "registry/default/html/toast.html",
          "target": "components/ui/toast.html",
          "type": "registry:component",
          "content": "<div data-timui-root data-timui-init=\"auto\">\n  <div role=\"status\" aria-live=\"polite\" data-slot=\"toast\" data-state=\"open\"\n      class=\"group pointer-events-auto relative flex w-full items-center justify-between space-x-2 overflow-hidden rounded-md border p-4 pr-6 shadow-lg transition-all border bg-background text-foreground\">\n      <div class=\"grid gap-1\">\n          <div data-slot=\"toast-title\" class=\"text-sm font-semibold [&amp;+div]:text-xs\">Toast Title</div>\n          <div data-slot=\"toast-description\" class=\"text-sm opacity-90\">Toast message goes here.</div>\n      </div>\n      <button data-slot=\"toast-close\"\n          class=\"absolute top-1 right-1 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-1 group-hover:opacity-100\">\n          <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\"\n              stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n              <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n              <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n          </svg>\n      </button>\n  </div>\n</div>\n<script type=\"module\">\n  import { autoInitHtmlRuntime } from '@timui/html'\n  autoInitHtmlRuntime({ components: ['toast'] })\n</script>"
        },
        {
          "path": "registry/default/weapp/toast.wxml",
          "target": "components/ui/toast.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{toastClass}}\" role=\"status\">\n  <view class=\"flex-1\">\n    <view wx:if=\"{{title}}\" class=\"{{titleClass}}\">{{title}}</view>\n    <view wx:if=\"{{description}}\" class=\"{{descriptionClass}}\">{{description}}</view>\n  </view>\n  <view wx:if=\"{{showClose}}\" class=\"{{closeClass}}\" bindtap=\"onCloseTap\">\n    <text>×</text>\n  </view>\n</view>\n\n"
        },
        {
          "path": "registry/default/weapp/toast.wxss",
          "target": "components/ui/toast.wxss",
          "type": "registry:component",
          "content": "/* Toast specific styles */\n\n/* Toast 底部安全区适配（iPhone X+ Home Indicator） */\n.toast-safe-area {\n  padding-bottom: constant(safe-area-inset-bottom); /* iOS < 11.2 */\n  padding-bottom: env(safe-area-inset-bottom);\n}\n"
        },
        {
          "path": "registry/default/weapp/toast.ts",
          "target": "components/ui/toast.ts",
          "type": "registry:component",
          "content": "import {\n  emitTimEvent,\n  resolveClasses,\n  toastCloseVariants,\n  toastDescriptionVariants,\n  toastTitleVariants,\n  toastVariants,\n} from '../utils'\nimport {\n  createWeappBaseProps,\n  createWeappOptions,\n  WEAPP_EXTERNAL_CLASSES,\n} from '../utils/component'\nimport { setupToastMachine } from './use-toast'\n\ntype MachineEvent =\n  | string\n  | {\n      type: string\n      [key: string]: string | number | boolean | string[] | number[] | null | undefined\n    }\n\ntype ToastVariant = 'info' | 'success' | 'warning' | 'error'\ntype ToastStatus = 'visible' | 'dismissing' | 'unmounted'\n\ntype WeappToastApi = {\n  dismiss?: () => void\n}\n\ntype WeappService = {\n  setContext: (context: { type?: ToastVariant; duration?: number }) => void\n}\n\ntype ToastStatusDetails = {\n  status: ToastStatus\n}\n\ntype WeappToastInternal =\n  WechatMiniprogram.Component.InstanceMethods<WechatMiniprogram.IAnyObject> & {\n    _service?: WeappService\n    _cleanup?: () => void\n    _send?: (event: MachineEvent) => void\n    _connect?: (state: object, send: (event: MachineEvent) => void) => WeappToastApi\n    data: {\n      api: WeappToastApi\n    }\n    properties: {\n      type: string\n      duration: number\n      title: string\n      description: string\n      showClose: boolean\n      id: string\n      extClass: string\n    }\n  }\n\nfunction toToastVariant(value: string): ToastVariant {\n  if (value === 'success' || value === 'warning' || value === 'error') return value\n  return 'info'\n}\n\nComponent({\n  options: createWeappOptions({ pureData: true }),\n\n  externalClasses: WEAPP_EXTERNAL_CLASSES,\n\n  properties: {\n    type: { type: String, value: 'info' },\n    duration: { type: Number, value: 3000 },\n    title: { type: String, value: '' },\n    description: { type: String, value: '' },\n    showClose: { type: Boolean, value: true },\n    ...createWeappBaseProps('toast'),\n  },\n\n  data: {\n    api: {} as WeappToastApi,\n    toastClass: '',\n    titleClass: '',\n    descriptionClass: '',\n    closeClass: '',\n  },\n\n  lifetimes: {\n    attached() {\n      const self = this as WeappToastInternal\n      const variant = toToastVariant(this.properties.type)\n      const { service, cleanup, send, connect } = setupToastMachine(this, {\n        id: this.properties.id,\n        type: variant,\n        duration: this.properties.duration,\n        onStatusChange: (details: ToastStatusDetails) => {\n          if (details.status === 'unmounted') {\n            this.triggerEvent('close')\n            emitTimEvent(\n              this,\n              'statuschange',\n              'toast.statusChange',\n              this.properties.id || 'toast',\n              { status: details.status }\n            )\n          }\n        },\n      })\n\n      self._service = service as WeappService\n      self._cleanup = cleanup\n      self._send = send as (event: MachineEvent) => void\n      self._connect = connect\n    },\n    detached() {\n      const self = this as WeappToastInternal\n      self._cleanup?.()\n    },\n  },\n\n  observers: {\n    state: function (state) {\n      const self = this as WeappToastInternal\n      if (!state || !self._send || !self._connect) return\n      const api = self._connect(state, self._send) as WeappToastApi\n\n      const toastClass = resolveClasses(\n        toastVariants({ variant: toToastVariant(this.properties.type) }),\n        self.properties.extClass\n      )\n      const titleClass = resolveClasses(toastTitleVariants())\n      const descriptionClass = resolveClasses(toastDescriptionVariants())\n      const closeClass = resolveClasses(toastCloseVariants())\n\n      this.setData({ api, toastClass, titleClass, descriptionClass, closeClass })\n    },\n  },\n\n  methods: {\n    onCloseTap() {\n      const self = this as WeappToastInternal\n      self.data.api.dismiss?.()\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/toast.json",
          "target": "components/ui/toast.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        }
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "toggle",
      "type": "registry:ui",
      "dependencies": [
        "@timui/core",
        "@zag-js/react"
      ],
      "registryDependencies": [
        "use-machine"
      ],
      "files": [
        {
          "path": "registry/default/ui/toggle.tsx",
          "type": "registry:ui",
          "target": "components/ui/toggle.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport { cn, toggleVariants, type ToggleVariants } from '@timui/core'\nimport { mergeProps } from '@zag-js/react'\n\nimport { useToggle } from './toggle/use-toggle'\n\nconst Toggle = React.forwardRef<\n  HTMLButtonElement,\n  React.ButtonHTMLAttributes<HTMLButtonElement> &\n    ToggleVariants & {\n      pressed?: boolean\n      defaultPressed?: boolean\n      onPressedChange?: (pressed: boolean) => void\n    }\n>(({ className, pressed, defaultPressed, onPressedChange, variant, size, ...props }, ref) => {\n  const api = useToggle({\n    pressed,\n    defaultPressed,\n    disabled: props.disabled,\n    onPressedChange,\n  })\n  const rootProps = api.getRootProps()\n  const mergedProps = mergeProps(rootProps, props)\n  const { className: mergedClassName, ...restProps } = mergedProps\n\n  return (\n    <button\n      ref={ref}\n      data-slot=\"toggle\"\n      data-state={api.pressed ? 'on' : 'off'}\n      aria-pressed={api.pressed}\n      type=\"button\"\n      className={cn(toggleVariants({ variant, size, className }), mergedClassName)}\n      {...restProps}\n    />\n  )\n})\nToggle.displayName = 'Toggle'\n\nexport { Toggle }\n"
        },
        {
          "path": "registry/default/ui/toggle/use-toggle.ts",
          "target": "components/ui/toggle/use-toggle.ts",
          "type": "registry:ui",
          "content": "import * as React from 'react'\nimport { toggleConnect, toggleMachine } from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/react'\n\nexport interface UseToggleProps {\n  pressed?: boolean\n  defaultPressed?: boolean\n  onPressedChange?: (pressed: boolean) => void\n  disabled?: boolean\n}\n\nexport function useToggle(props: UseToggleProps) {\n  const service = useMachine(toggleMachine, {\n    pressed: props.pressed,\n    defaultPressed: props.defaultPressed,\n    disabled: props.disabled,\n    onPressedChange: props.onPressedChange,\n  })\n\n  return React.useMemo(() => toggleConnect(service, normalizeProps), [service])\n}\n"
        },
        {
          "path": "registry/default/vue/toggle/toggle-group-item.vue",
          "target": "components/ui/toggle/toggle-group-item.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn } from '@timui/core'\nimport { inject, computed, type HTMLAttributes } from 'vue'\nimport { toggleVariants } from '@timui/core'\nimport { ToggleGroupContextKey, type ToggleGroupContextValue } from './use-toggle-group-context'\n\nconst context = inject<ToggleGroupContextValue>(ToggleGroupContextKey)\n\nconst props = withDefaults(\n  defineProps<{\n    value: string\n    class?: HTMLAttributes['class']\n    variant?: ToggleGroupContextValue['variant']\n    size?: ToggleGroupContextValue['size']\n    disabled?: boolean\n  }>(),\n  {\n    variant: 'default',\n    size: 'default',\n  },\n)\n\nconst itemState = computed(() =>\n  context?.api.value.getItemState?.({ value: props.value, disabled: props.disabled }) ?? {\n    pressed: false,\n    disabled: false,\n  },\n)\nconst itemProps = computed(() =>\n  context?.api.value.getItemProps?.({ value: props.value, disabled: props.disabled }) ?? {},\n)\nconst resolvedVariant = computed(() => context?.variant || props.variant)\nconst resolvedSize = computed(() => context?.size || props.size)\n</script>\n\n<template>\n  <button\n    v-bind=\"itemProps\"\n    data-slot=\"toggle-group-item\"\n    type=\"button\"\n    :data-state=\"itemState.pressed ? 'on' : 'off'\"\n    :class=\"cn(toggleVariants({ variant: resolvedVariant, size: resolvedSize }), props.class)\"\n  >\n    <slot />\n  </button>\n</template>\n"
        },
        {
          "path": "registry/default/vue/toggle/toggle-group.vue",
          "target": "components/ui/toggle/toggle-group.vue",
          "type": "registry:component",
          "content": "<script lang=\"ts\">\nimport { type ToggleVariants } from '@timui/core'\n</script>\n\n<script setup lang=\"ts\">\nimport { cn, toggleGroupVariants } from '@timui/core'\nimport { computed, type HTMLAttributes } from 'vue'\nimport { provideToggleGroupContext, type ToggleGroupContextValue } from './use-toggle-group-context'\nimport { useToggleGroup } from './use-toggle-group'\n\nconst props = withDefaults(\n  defineProps<{\n    id?: string\n    class?: HTMLAttributes['class']\n    variant?: ToggleGroupContextValue['variant']\n    size?: ToggleGroupContextValue['size']\n    type?: 'single' | 'multiple'\n    modelValue?: string | string[]\n    value?: string | string[]\n    defaultValue?: string | string[]\n    disabled?: boolean\n    loop?: boolean\n  }>(),\n  {\n    type: 'single',\n    variant: 'default',\n    size: 'default',\n  },\n)\n\nconst emit = defineEmits(['update:modelValue', 'change'])\n\nconst toArray = (value?: string | string[] | null) => {\n  if (value == null) return undefined\n  return Array.isArray(value) ? value : value === '' ? [] : [value]\n}\n\nconst api = useToggleGroup({\n  id: props.id,\n  multiple: props.type === 'multiple',\n  disabled: props.disabled,\n  loop: props.loop,\n  value: toArray(props.value ?? props.modelValue),\n  defaultValue: toArray(props.value ?? props.modelValue) === undefined ? toArray(props.defaultValue) : undefined,\n  onValueChange(value: string[]) {\n    const nextValue = props.type === 'multiple' ? value : value[0] || ''\n    emit('update:modelValue', nextValue)\n    emit('change', nextValue)\n  },\n})\n\nprovideToggleGroupContext({\n  variant: props.variant,\n  size: props.size,\n  api,\n  type: props.type,\n  disabled: props.disabled,\n})\n</script>\n\n<template>\n  <div\n    v-bind=\"api.getRootProps()\"\n    data-slot=\"toggle-group\"\n    :class=\"cn(toggleGroupVariants(), props.class)\"\n    role=\"group\"\n  >\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/toggle/toggle.vue",
          "target": "components/ui/toggle/toggle.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, toggleVariants, type ToggleVariants } from '@timui/core'\nimport { computed, type HTMLAttributes } from 'vue'\nimport { useToggle } from './use-toggle'\n\nconst props = withDefaults(\n  defineProps<{\n    class?: HTMLAttributes['class']\n    variant?: ToggleVariants['variant']\n    size?: ToggleVariants['size']\n    pressed?: boolean\n    modelValue?: boolean\n    defaultPressed?: boolean\n    disabled?: boolean\n    onPressedChange?: (pressed: boolean) => void\n  }>(),\n  {\n    variant: 'default',\n    size: 'default',\n    disabled: false,\n  },\n)\n\nconst emit = defineEmits(['update:pressed', 'update:modelValue', 'pressedChange', 'change'])\n\nconst api = useToggle({\n  pressed: props.pressed ?? props.modelValue,\n  defaultPressed: (props.pressed ?? props.modelValue) === undefined ? props.defaultPressed : undefined,\n  disabled: props.disabled,\n  onPressedChange: (next: boolean) => {\n    props.onPressedChange?.(next)\n    emit('update:pressed', next)\n    emit('update:modelValue', next)\n    emit('pressedChange', next)\n    emit('change', next)\n  },\n})\n\nconst computedClass = computed(() =>\n  cn(toggleVariants({ variant: props.variant, size: props.size }), props.class),\n)\n</script>\n\n<template>\n  <button\n    v-bind=\"api.getRootProps()\"\n    type=\"button\"\n    data-slot=\"toggle\"\n    :data-state=\"api.pressed ? 'on' : 'off'\"\n    :aria-pressed=\"api.pressed\"\n    :class=\"computedClass\"\n  >\n    <slot />\n  </button>\n</template>\n"
        },
        {
          "path": "registry/default/vue/toggle/use-toggle-group-context.ts",
          "target": "components/ui/toggle/use-toggle-group-context.ts",
          "type": "registry:component",
          "content": "import type { ToggleGroupApi, ToggleVariants } from '@timui/core'\nimport { inject, provide, type ComputedRef } from 'vue'\n\nexport type ToggleGroupContextValue = {\n  variant?: ToggleVariants['variant']\n  size?: ToggleVariants['size']\n  api: ComputedRef<ToggleGroupApi>\n  type?: 'single' | 'multiple'\n  disabled?: boolean\n}\n\nexport const ToggleGroupContextKey = Symbol('ToggleGroupContext')\n\nexport function provideToggleGroupContext(context: ToggleGroupContextValue) {\n  provide(ToggleGroupContextKey, context)\n}\n\nexport function useToggleGroupContext() {\n  const context = inject<ToggleGroupContextValue>(ToggleGroupContextKey)\n  if (!context) {\n    throw new Error('useToggleGroupContext must be used within a ToggleGroupProvider')\n  }\n  return context\n}\n"
        },
        {
          "path": "registry/default/vue/toggle/use-toggle-group.ts",
          "target": "components/ui/toggle/use-toggle-group.ts",
          "type": "registry:component",
          "content": "import { toggleGroupConnect, toggleGroupMachine, type ToggleGroupApi } from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/vue'\nimport { computed, type ComputedRef, useId } from 'vue'\n\nexport type UseToggleGroupProps = {\n  id?: string\n  value?: string[]\n  defaultValue?: string[]\n  disabled?: boolean\n  multiple?: boolean\n  loop?: boolean\n  onValueChange?: (value: string[]) => void\n}\n\nexport function useToggleGroup(props: UseToggleGroupProps) {\n  const generatedId = useId()\n\n  const service = useMachine(toggleGroupMachine, {\n    id: props.id ?? generatedId,\n    value: props.value,\n    defaultValue: props.defaultValue,\n    disabled: props.disabled,\n    multiple: props.multiple,\n    loopFocus: props.loop,\n    onValueChange(details) {\n      props.onValueChange?.(details.value)\n    },\n  })\n\n  return computed(() => toggleGroupConnect(service, normalizeProps))\n}\n"
        },
        {
          "path": "registry/default/vue/toggle/use-toggle.ts",
          "target": "components/ui/toggle/use-toggle.ts",
          "type": "registry:component",
          "content": "import { toggleConnect, toggleMachine } from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/vue'\nimport { computed } from 'vue'\n\ntype ToggleProps = {\n  pressed?: boolean\n  defaultPressed?: boolean\n  disabled?: boolean\n  onPressedChange?: (pressed: boolean) => void\n}\n\nexport function useToggle(props: ToggleProps = {}) {\n  const service = useMachine(toggleMachine, {\n    pressed: props.pressed,\n    defaultPressed: props.defaultPressed,\n    disabled: props.disabled,\n    onPressedChange: props.onPressedChange,\n  })\n\n  return computed(() => toggleConnect(service, normalizeProps))\n}\n"
        },
        {
          "path": "registry/default/html/toggle.html",
          "target": "components/ui/toggle.html",
          "type": "registry:component",
          "content": "<div data-timui-root data-timui-init=\"auto\">\n  <button data-slot=\"toggle\" type=\"button\" data-state=\"off\" aria-pressed=\"false\" class=\"inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state&#x3D;on]:bg-accent data-[state&#x3D;on]:text-accent-foreground bg-transparent h-10 px-3\">\n    Toggle\n  </button>\n</div>\n<script type=\"module\">\n  import { autoInitHtmlRuntime } from '@timui/html'\n  autoInitHtmlRuntime({ components: ['toggle'] })\n</script>"
        },
        {
          "path": "registry/default/weapp/toggle.wxml",
          "target": "components/ui/toggle.wxml",
          "type": "registry:component",
          "content": "<view \n  class=\"{{className}}\"\n  bindtap=\"onTap\"\n  data-pressed=\"{{api.pressed}}\"\n  data-disabled=\"{{disabled}}\"\n  role=\"button\"\n  aria-pressed=\"{{api.pressed}}\"\n>\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/toggle.wxss",
          "target": "components/ui/toggle.wxss",
          "type": "registry:component",
          "content": "/* weapp component styles */\n"
        },
        {
          "path": "registry/default/weapp/toggle.ts",
          "target": "components/ui/toggle.ts",
          "type": "registry:component",
          "content": "import { emitTimEvent } from '../utils'\nimport { setupToggleMachine } from './use-toggle'\n\ntype MachineEvent =\n  | string\n  | {\n      type: string\n      [key: string]: string | number | boolean | string[] | number[] | null | undefined\n    }\n\ntype WeappToggleApi = {\n  buttonProps?: {\n    onClick?: () => void\n  }\n}\n\ntype WeappService = {\n  setContext: (context: { pressed?: boolean; disabled?: boolean }) => void\n}\n\ntype WeappToggleInternal =\n  WechatMiniprogram.Component.InstanceMethods<WechatMiniprogram.IAnyObject> & {\n    _service?: WeappService\n    _cleanup?: () => void\n    _send?: (event: MachineEvent) => void\n    data: {\n      api: WeappToggleApi\n    }\n    properties: {\n      pressed: boolean\n      disabled: boolean\n      id: string\n      extClass: string\n    }\n  }\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    pressed: { type: Boolean, value: false },\n    disabled: { type: Boolean, value: false },\n    id: { type: String, value: 'toggle' },\n    extClass: { type: String, value: '' },\n  },\n\n  data: {\n    api: {} as WeappToggleApi,\n    className: '',\n  },\n\n  lifetimes: {\n    attached() {\n      const self = this as WeappToggleInternal\n      const { service, cleanup, send } = setupToggleMachine(this, {\n        id: this.properties.id,\n        pressed: this.properties.pressed,\n        disabled: this.properties.disabled,\n        onPressedChange: (details) => {\n          emitTimEvent(this, 'change', 'change', this.properties.id || 'toggle', {\n            pressed: details.pressed,\n          })\n        },\n      })\n\n      self._service = service as WeappService\n      self._cleanup = cleanup\n      self._send = send as (event: MachineEvent) => void\n    },\n    detached() {\n      const self = this as WeappToggleInternal\n      self._cleanup?.()\n    },\n  },\n\n  observers: {\n    state: function (state) {\n      const self = this as WeappToggleInternal\n      if (!state || !self._send) return\n      const { connect } = setupToggleMachine(this, { id: this.properties.id })\n      const api = connect(state, self._send) as WeappToggleApi\n      this.setData({ api, className: this.properties.extClass })\n    },\n\n    pressed: function (val) {\n      const self = this as WeappToggleInternal\n      if (self._service) {\n        self._service.setContext({ pressed: val })\n      }\n    },\n  },\n\n  methods: {\n    onTap() {\n      const self = this as WeappToggleInternal\n      self.data.api.buttonProps?.onClick?.()\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/toggle.json",
          "target": "components/ui/toggle.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        },
        {
          "path": "registry/default/weapp/toggle-group/toggle-group.wxml",
          "target": "components/ui/toggle-group/toggle-group.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\" role=\"group\">\n  <slot></slot>\n</view>\n\n<!-- 使用示例：\n<toggle-group value=\"{{selectedValues}}\" multiple=\"{{true}}\" bind:change=\"handleChange\">\n  <view \n    class=\"toggle-item\" \n    data-value=\"option1\"\n    data-pressed=\"{{api.value.includes('option1')}}\"\n    bindtap=\"onItemTap\"\n  >\n    选项 1\n  </view>\n  <view \n    class=\"toggle-item\" \n    data-value=\"option2\"\n    data-pressed=\"{{api.value.includes('option2')}}\"\n    bindtap=\"onItemTap\"\n  >\n    选项 2\n  </view>\n</toggle-group>\n-->\n"
        },
        {
          "path": "registry/default/weapp/toggle-group/toggle-group.wxss",
          "target": "components/ui/toggle-group/toggle-group.wxss",
          "type": "registry:component",
          "content": "/* weapp component styles */\n"
        },
        {
          "path": "registry/default/weapp/toggle-group/toggle-group.json",
          "target": "components/ui/toggle-group/toggle-group.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        },
        {
          "path": "registry/default/weapp/toggle-group/toggle-group.ts",
          "target": "components/ui/toggle-group/toggle-group.ts",
          "type": "registry:component",
          "content": "import { emitTimEvent } from '../utils'\nimport { setupToggleGroupMachine } from './use-toggle-group'\n\ntype WeappToggleGroupApi = {\n  value?: string[]\n  setValue?: (value: string[]) => void\n}\n\ntype WeappService = {\n  setContext: (context: Record<string, object>) => void\n}\n\ntype ToggleGroupTapEvent = WechatMiniprogram.BaseEvent & {\n  currentTarget: {\n    dataset: {\n      value?: string\n    }\n  }\n}\n\ntype WeappToggleGroupInternal =\n  WechatMiniprogram.Component.InstanceMethods<WechatMiniprogram.IAnyObject> & {\n    _service?: WeappService\n    _cleanup?: () => void\n    _send?: (event: object) => void\n    data: {\n      api: WeappToggleGroupApi\n    }\n    properties: {\n      value: string[]\n      multiple: boolean\n      disabled: boolean\n      loop: boolean\n      id: string\n      extClass: string\n    }\n  }\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    value: { type: Array, value: [] },\n    multiple: { type: Boolean, value: false },\n    disabled: { type: Boolean, value: false },\n    loop: { type: Boolean, value: true },\n    id: { type: String, value: 'toggle-group' },\n    extClass: { type: String, value: '' },\n  },\n\n  data: {\n    api: {} as WeappToggleGroupApi,\n    className: '',\n  },\n\n  lifetimes: {\n    attached() {\n      const self = this as WeappToggleGroupInternal\n      const { service, cleanup, send } = setupToggleGroupMachine(this, {\n        id: this.properties.id,\n        value: this.properties.value,\n        multiple: this.properties.multiple,\n        disabled: this.properties.disabled,\n        loop: this.properties.loop,\n        onValueChange: (details) => {\n          emitTimEvent(this, 'change', 'change', this.properties.id || 'toggle-group', {\n            value: details.value,\n          })\n        },\n      })\n\n      self._service = service as WeappService\n      self._cleanup = cleanup\n      self._send = send as (event: object) => void\n    },\n    detached() {\n      const self = this as WeappToggleGroupInternal\n      self._cleanup?.()\n    },\n  },\n\n  observers: {\n    state: function (state) {\n      const self = this as WeappToggleGroupInternal\n      if (!state || !self._send) return\n      const { connect } = setupToggleGroupMachine(this, { id: this.properties.id })\n      const api = connect(state, self._send) as WeappToggleGroupApi\n      this.setData({ api, className: this.properties.extClass })\n    },\n\n    value: function (val) {\n      const self = this as WeappToggleGroupInternal\n      if (self._service) {\n        self._service.setContext({ value: val })\n      }\n    },\n  },\n\n  methods: {\n    onItemTap(e: ToggleGroupTapEvent) {\n      const self = this as WeappToggleGroupInternal\n      const value = e.currentTarget.dataset.value\n      if (value && self.data.api.setValue) {\n        const currentValue = self.data.api.value || []\n        if (this.properties.multiple) {\n          const newValue = currentValue.includes(value)\n            ? currentValue.filter((v) => v !== value)\n            : [...currentValue, value]\n          self.data.api.setValue(newValue)\n        } else {\n          self.data.api.setValue([value])\n        }\n      }\n    },\n  },\n})\n"
        }
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@zag-js/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@zag-js/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "toggle-group",
      "type": "registry:ui",
      "dependencies": [
        "@timui/core",
        "@zag-js/react"
      ],
      "registryDependencies": [
        "toggle"
      ],
      "files": [
        {
          "path": "registry/default/ui/toggle-group.tsx",
          "type": "registry:ui",
          "target": "components/ui/toggle-group.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport { cn, toggleGroupVariants, toggleVariants, type ToggleVariants } from '@timui/core'\nimport { mergeProps } from '@zag-js/react'\n\nimport { useToggleGroup } from './toggle-group/use-toggle-group'\nimport { ToggleGroupProvider, useToggleGroupContext } from './toggle-group/use-toggle-group-context'\n\n// Context is imported from ./toggle-group/use-toggle-group-context\n\nconst ToggleGroup = React.forwardRef<\n  HTMLDivElement,\n  React.HTMLAttributes<HTMLDivElement> &\n    ToggleVariants & {\n      type: 'single' | 'multiple'\n      value?: string | string[]\n      defaultValue?: string | string[]\n      onValueChange?: (value: string | string[]) => void\n      disabled?: boolean\n      loop?: boolean\n    }\n>(\n  (\n    {\n      className,\n      variant,\n      size,\n      children,\n      id,\n      type,\n      value,\n      defaultValue,\n      onValueChange,\n      disabled,\n      loop,\n      ...props\n    },\n    ref\n  ) => {\n    const api = useToggleGroup({\n      id,\n      multiple: type === 'multiple',\n      value,\n      defaultValue,\n      onValueChange,\n      disabled,\n      loop,\n    })\n    const rootProps = api.getRootProps()\n    const mergedProps = mergeProps(rootProps, props) as React.HTMLAttributes<HTMLDivElement>\n    const { className: mergedClassName, ...restProps } = mergedProps\n\n    return (\n      <ToggleGroupProvider\n        value={{\n          api,\n          size,\n          variant,\n          type,\n          disabled,\n        }}\n      >\n        <div\n          ref={ref}\n          data-slot=\"toggle-group\"\n          role=\"group\"\n          className={cn(toggleGroupVariants(), className, mergedClassName)}\n          {...restProps}\n        >\n          {children}\n        </div>\n      </ToggleGroupProvider>\n    )\n  }\n)\nToggleGroup.displayName = 'ToggleGroup'\n\nconst ToggleGroupItem = React.forwardRef<\n  HTMLButtonElement,\n  React.ButtonHTMLAttributes<HTMLButtonElement> & { value: string }\n>(({ className, children, value, ...props }, ref) => {\n  const context = useToggleGroupContext()\n  const api = context.api\n  const itemState = api?.getItemState?.({ value, disabled: props.disabled }) ?? {\n    pressed: false,\n    disabled: false,\n  }\n  const itemProps = api?.getItemProps?.({ value, disabled: props.disabled }) ?? {}\n  const mergedProps = mergeProps(itemProps, props)\n  const { className: mergedClassName, ...restProps } = mergedProps\n\n  return (\n    <button\n      ref={ref}\n      data-slot=\"toggle-group-item\"\n      type=\"button\"\n      data-state={itemState.pressed ? 'on' : 'off'}\n      className={cn(\n        toggleVariants({ variant: context?.variant, size: context?.size }),\n        className,\n        mergedClassName\n      )}\n      {...restProps}\n    >\n      {children}\n    </button>\n  )\n})\nToggleGroupItem.displayName = 'ToggleGroupItem'\n\nexport { ToggleGroup, ToggleGroupItem }\n"
        },
        {
          "path": "registry/default/ui/toggle-group/use-toggle-group-context.ts",
          "target": "components/ui/toggle-group/use-toggle-group-context.ts",
          "type": "registry:ui",
          "content": "import * as React from 'react'\nimport type { toggleGroupConnect, ToggleVariants } from '@timui/core'\n\nexport interface ToggleGroupContextValue {\n  api: ReturnType<typeof toggleGroupConnect>\n  size?: ToggleVariants['size']\n  variant?: ToggleVariants['variant']\n  type: 'single' | 'multiple'\n  disabled?: boolean\n}\n\nconst ToggleGroupContext = React.createContext<ToggleGroupContextValue | null>(null)\n\nexport const ToggleGroupProvider: React.Provider<ToggleGroupContextValue | null> =\n  ToggleGroupContext.Provider\n\nexport function useToggleGroupContext(): ToggleGroupContextValue {\n  const context = React.useContext(ToggleGroupContext)\n  if (!context) {\n    throw new Error('ToggleGroup components must be used within `<ToggleGroupProvider />`')\n  }\n  return context\n}\n"
        },
        {
          "path": "registry/default/ui/toggle-group/use-toggle-group.ts",
          "target": "components/ui/toggle-group/use-toggle-group.ts",
          "type": "registry:ui",
          "content": "import * as React from 'react'\nimport { toggleGroupConnect, toggleGroupMachine } from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/react'\n\nexport interface UseToggleGroupProps {\n  id?: string\n  multiple?: boolean\n  value?: string | string[]\n  defaultValue?: string | string[]\n  onValueChange?: (value: string | string[]) => void\n  disabled?: boolean\n  loop?: boolean\n}\n\nexport function useToggleGroup(props: UseToggleGroupProps) {\n  const generatedId = React.useId()\n  const toArray = (val?: string | string[] | null) => {\n    if (val == null) return undefined\n    return Array.isArray(val) ? val : val === '' ? [] : [val]\n  }\n\n  const resolvedValue = toArray(props.value)\n  const defaultValueArray = toArray(props.defaultValue)\n\n  const service = useMachine(toggleGroupMachine, {\n    id: props.id ?? generatedId,\n    multiple: props.multiple,\n    value: resolvedValue,\n    defaultValue: resolvedValue === undefined ? defaultValueArray : undefined,\n    disabled: props.disabled,\n    loopFocus: props.loop,\n    onValueChange: (details) => {\n      const nextValue = props.multiple ? details.value : (details.value[0] ?? '')\n      props.onValueChange?.(nextValue)\n    },\n  })\n\n  return React.useMemo(() => toggleGroupConnect(service, normalizeProps), [service])\n}\n"
        },
        {
          "path": "registry/default/vue/toggle-group/toggle-group.vue",
          "target": "components/ui/toggle-group/toggle-group.vue",
          "type": "registry:component",
          "content": "<script lang=\"ts\">\nexport { default } from '../toggle/toggle-group.vue'\n</script>\n"
        },
        {
          "path": "registry/default/html/toggle-group.html",
          "target": "components/ui/toggle-group.html",
          "type": "registry:component",
          "content": "<div data-timui-root data-timui-init=\"auto\">\n  <div data-slot=\"toggle-group\" class=\"inline-flex rounded-md border border-input p-1\">\n    <button type=\"button\" class=\"rounded-sm px-3 py-1.5 text-sm data-[state=on]:bg-primary data-[state=on]:text-primary-foreground\" data-state=\"on\">\n      Left\n    </button>\n    <button type=\"button\" class=\"rounded-sm px-3 py-1.5 text-sm\" data-state=\"off\">Center</button>\n    <button type=\"button\" class=\"rounded-sm px-3 py-1.5 text-sm\" data-state=\"off\">Right</button>\n  </div>\n</div>\n<script type=\"module\">\n  import { autoInitHtmlRuntime } from '@timui/html'\n  autoInitHtmlRuntime({ components: ['toggle-group'] })\n</script>"
        },
        {
          "path": "registry/default/weapp/toggle-group.wxml",
          "target": "components/ui/toggle-group.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\" role=\"group\">\n  <slot></slot>\n</view>\n\n<!-- 使用示例：\n<toggle-group value=\"{{selectedValues}}\" multiple=\"{{true}}\" bind:change=\"handleChange\">\n  <view \n    class=\"toggle-item\" \n    data-value=\"option1\"\n    data-pressed=\"{{api.value.includes('option1')}}\"\n    bindtap=\"onItemTap\"\n  >\n    选项 1\n  </view>\n  <view \n    class=\"toggle-item\" \n    data-value=\"option2\"\n    data-pressed=\"{{api.value.includes('option2')}}\"\n    bindtap=\"onItemTap\"\n  >\n    选项 2\n  </view>\n</toggle-group>\n-->\n"
        },
        {
          "path": "registry/default/weapp/toggle-group.wxss",
          "target": "components/ui/toggle-group.wxss",
          "type": "registry:component",
          "content": "/* weapp component styles */\n"
        },
        {
          "path": "registry/default/weapp/toggle-group.ts",
          "target": "components/ui/toggle-group.ts",
          "type": "registry:component",
          "content": "import { emitTimEvent } from '../utils'\nimport { setupToggleGroupMachine } from './use-toggle-group'\n\ntype WeappToggleGroupApi = {\n  value?: string[]\n  setValue?: (value: string[]) => void\n}\n\ntype WeappService = {\n  setContext: (context: Record<string, object>) => void\n}\n\ntype ToggleGroupTapEvent = WechatMiniprogram.BaseEvent & {\n  currentTarget: {\n    dataset: {\n      value?: string\n    }\n  }\n}\n\ntype WeappToggleGroupInternal =\n  WechatMiniprogram.Component.InstanceMethods<WechatMiniprogram.IAnyObject> & {\n    _service?: WeappService\n    _cleanup?: () => void\n    _send?: (event: object) => void\n    data: {\n      api: WeappToggleGroupApi\n    }\n    properties: {\n      value: string[]\n      multiple: boolean\n      disabled: boolean\n      loop: boolean\n      id: string\n      extClass: string\n    }\n  }\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    value: { type: Array, value: [] },\n    multiple: { type: Boolean, value: false },\n    disabled: { type: Boolean, value: false },\n    loop: { type: Boolean, value: true },\n    id: { type: String, value: 'toggle-group' },\n    extClass: { type: String, value: '' },\n  },\n\n  data: {\n    api: {} as WeappToggleGroupApi,\n    className: '',\n  },\n\n  lifetimes: {\n    attached() {\n      const self = this as WeappToggleGroupInternal\n      const { service, cleanup, send } = setupToggleGroupMachine(this, {\n        id: this.properties.id,\n        value: this.properties.value,\n        multiple: this.properties.multiple,\n        disabled: this.properties.disabled,\n        loop: this.properties.loop,\n        onValueChange: (details) => {\n          emitTimEvent(this, 'change', 'change', this.properties.id || 'toggle-group', {\n            value: details.value,\n          })\n        },\n      })\n\n      self._service = service as WeappService\n      self._cleanup = cleanup\n      self._send = send as (event: object) => void\n    },\n    detached() {\n      const self = this as WeappToggleGroupInternal\n      self._cleanup?.()\n    },\n  },\n\n  observers: {\n    state: function (state) {\n      const self = this as WeappToggleGroupInternal\n      if (!state || !self._send) return\n      const { connect } = setupToggleGroupMachine(this, { id: this.properties.id })\n      const api = connect(state, self._send) as WeappToggleGroupApi\n      this.setData({ api, className: this.properties.extClass })\n    },\n\n    value: function (val) {\n      const self = this as WeappToggleGroupInternal\n      if (self._service) {\n        self._service.setContext({ value: val })\n      }\n    },\n  },\n\n  methods: {\n    onItemTap(e: ToggleGroupTapEvent) {\n      const self = this as WeappToggleGroupInternal\n      const value = e.currentTarget.dataset.value\n      if (value && self.data.api.setValue) {\n        const currentValue = self.data.api.value || []\n        if (this.properties.multiple) {\n          const newValue = currentValue.includes(value)\n            ? currentValue.filter((v) => v !== value)\n            : [...currentValue, value]\n          self.data.api.setValue(newValue)\n        } else {\n          self.data.api.setValue([value])\n        }\n      }\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/toggle-group.json",
          "target": "components/ui/toggle-group.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        }
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@zag-js/react"
            ]
          },
          "vue": {},
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "tooltip",
      "type": "registry:ui",
      "dependencies": [
        "@timui/core",
        "@zag-js/popper",
        "@zag-js/react"
      ],
      "registryDependencies": [
        "use-machine"
      ],
      "files": [
        {
          "path": "registry/default/ui/tooltip.tsx",
          "type": "registry:ui",
          "target": "components/ui/tooltip.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport { cn, tooltipContentVariants } from '@timui/core'\nimport type { Placement } from '@zag-js/popper'\nimport { mergeProps } from '@zag-js/react'\nimport { createPortal } from 'react-dom'\n\nimport { Slot } from './slot'\nimport { useTooltip, type UseTooltipProps } from './tooltip/use-tooltip'\nimport { TooltipContextProvider, useTooltipContext } from './tooltip/use-tooltip-context'\n\nconst TooltipProvider = ({\n  children,\n  delayDuration,\n  skipDelayDuration,\n  disableHoverableContent,\n}: {\n  children: React.ReactNode\n  delayDuration?: number\n  skipDelayDuration?: number\n  disableHoverableContent?: boolean\n}) => {\n  // Ideally coordinates delayGroups. For now, pass through.\n  return <>{children}</>\n}\nconst Tooltip = ({ children, ...props }: UseTooltipProps & { children: React.ReactNode }) => {\n  const api = useTooltip(props)\n  return <TooltipContextProvider value={api}>{children}</TooltipContextProvider>\n}\nTooltip.displayName = 'Tooltip'\n\nconst TooltipTrigger = React.forwardRef<\n  HTMLButtonElement,\n  React.ButtonHTMLAttributes<HTMLButtonElement> & { asChild?: boolean }\n>(({ className, asChild = false, ...props }, ref) => {\n  const api = useTooltipContext()\n  const Comp = asChild ? Slot : 'button'\n  const triggerProps = api.getTriggerProps()\n  const mergedProps = mergeProps(triggerProps, props)\n\n  return (\n    <Comp\n      ref={ref}\n      data-slot=\"tooltip-trigger\"\n      type=\"button\"\n      className={cn(className)}\n      {...mergedProps}\n    />\n  )\n})\nTooltipTrigger.displayName = 'TooltipTrigger'\n\nconst TooltipContent = React.forwardRef<\n  HTMLDivElement,\n  React.HTMLAttributes<HTMLDivElement> & {\n    sideOffset?: number\n    side?: 'top' | 'bottom' | 'left' | 'right'\n    showArrow?: boolean\n  }\n>(\n  (\n    { className, sideOffset = 4, side = 'top', showArrow = false, style, children, ...props },\n    ref\n  ) => {\n    const api = useTooltipContext()\n    React.useEffect(() => {\n      if (!api.open) return\n      api.reposition({ placement: side as Placement, gutter: sideOffset })\n    }, [api, side, sideOffset])\n    if (!api.open) return null\n    if (typeof window === 'undefined') return null\n\n    const positionerProps = api.getPositionerProps()\n    const contentProps = api.getContentProps()\n    const mergedProps = mergeProps(contentProps, props) as React.HTMLAttributes<HTMLDivElement>\n\n    return createPortal(\n      <div {...positionerProps} style={{ ...positionerProps.style, zIndex: 50 }}>\n        <div\n          ref={ref}\n          data-slot=\"tooltip-content\"\n          data-state=\"open\"\n          style={{ ...mergedProps.style, ...style }}\n          className={cn(tooltipContentVariants(), showArrow ? 'relative' : undefined, className)}\n          {...mergedProps}\n        >\n          {children}\n          {showArrow ? (\n            <span\n              data-slot=\"tooltip-arrow\"\n              className=\"absolute -bottom-1 left-1/2 h-2 w-2 -translate-x-1/2 rotate-45 border border-border bg-popover\"\n            />\n          ) : null}\n        </div>\n      </div>,\n      document.body\n    )\n  }\n)\nTooltipContent.displayName = 'TooltipContent'\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }\n"
        },
        {
          "path": "registry/default/ui/tooltip/use-tooltip-context.tsx",
          "target": "components/ui/tooltip/use-tooltip-context.tsx",
          "type": "registry:ui",
          "content": "import * as React from 'react'\n\nimport type { useTooltip } from './use-tooltip'\n\nexport type UseTooltipReturn = ReturnType<typeof useTooltip>\n\nconst TooltipContext = React.createContext<UseTooltipReturn | null>(null)\n\nexport function TooltipContextProvider({\n  children,\n  value,\n}: {\n  children: React.ReactNode\n  value: UseTooltipReturn\n}) {\n  return <TooltipContext.Provider value={value}>{children}</TooltipContext.Provider>\n}\n\nexport function useTooltipContext() {\n  const context = React.useContext(TooltipContext)\n  if (!context) {\n    throw new Error('useTooltipContext must be used within a TooltipProvider')\n  }\n  return context\n}\n"
        },
        {
          "path": "registry/default/ui/tooltip/use-tooltip.ts",
          "target": "components/ui/tooltip/use-tooltip.ts",
          "type": "registry:ui",
          "content": "import * as React from 'react'\nimport { tooltipConnect, tooltipMachine } from '@timui/core'\nimport type { PositioningOptions } from '@zag-js/popper'\nimport { normalizeProps, useMachine } from '@zag-js/react'\n\nexport interface UseTooltipProps {\n  id?: string\n  open?: boolean\n  defaultOpen?: boolean\n  onOpenChange?: (open: boolean) => void\n  openDelay?: number\n  closeDelay?: number\n  closeOnPointerDown?: boolean\n  closeOnEscape?: boolean\n  closeOnScroll?: boolean\n  closeOnClick?: boolean\n  interactive?: boolean\n  positioning?: PositioningOptions\n  disabled?: boolean\n}\n\nexport function useTooltip(props: UseTooltipProps) {\n  const generatedId = React.useId()\n  const service = useMachine(tooltipMachine, {\n    id: props.id ?? generatedId,\n    open: props.open,\n    defaultOpen: props.defaultOpen,\n    openDelay: props.openDelay,\n    closeDelay: props.closeDelay,\n    closeOnPointerDown: props.closeOnPointerDown,\n    closeOnEscape: props.closeOnEscape,\n    closeOnScroll: props.closeOnScroll,\n    closeOnClick: props.closeOnClick,\n    interactive: props.interactive,\n    positioning: props.positioning,\n    disabled: props.disabled,\n    onOpenChange: (details) => props.onOpenChange?.(details.open),\n  })\n\n  const api = React.useMemo(() => tooltipConnect(service, normalizeProps), [service])\n\n  return api\n}\n"
        },
        {
          "path": "registry/default/vue/tooltip/tooltip-content.vue",
          "target": "components/ui/tooltip/tooltip-content.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, watch } from \"vue\";\nimport { cn, tooltipContentVariants } from \"@timui/core\";\nimport { useTooltipContext } from \"./use-tooltip-context\";\nimport Presence from \"../presence/presence.vue\";\nimport type { Placement } from \"@zag-js/popper\";\n\nconst props = withDefaults(\n  defineProps<{\n    class?: string;\n    sideOffset?: number;\n    side?: \"top\" | \"bottom\" | \"left\" | \"right\";\n    showArrow?: boolean;\n  }>(),\n  {\n    sideOffset: 4,\n    side: \"top\",\n    showArrow: false,\n  }\n);\n\nconst context = useTooltipContext();\nconst isOpen = computed(() => context.value.open ?? false);\nconst positionerProps = computed(() => context.value.getPositionerProps?.() ?? {});\nconst contentProps = computed(() => context.value.getContentProps?.() ?? {});\n\nwatch(\n  () => [props.side, props.sideOffset],\n  () => {\n    context.value.reposition?.({ placement: props.side as Placement, gutter: props.sideOffset });\n  },\n  { immediate: true }\n);\n</script>\n\n<template>\n  <Teleport to=\"body\">\n    <Presence :present=\"isOpen\" :unmountOnExit=\"true\" v-bind=\"positionerProps\" style=\"z-index: 50\">\n      <div\n        v-bind=\"contentProps\"\n        data-slot=\"tooltip-content\"\n        data-state=\"open\"\n        :class=\"\n          cn(tooltipContentVariants(), props.showArrow && 'relative', props.class)\n        \"\n      >\n        <slot />\n        <span\n          v-if=\"props.showArrow\"\n          data-slot=\"tooltip-arrow\"\n          class=\"absolute -bottom-1 left-1/2 h-2 w-2 -translate-x-1/2 rotate-45 border border-border bg-popover\"\n        />\n      </div>\n    </Presence>\n  </Teleport>\n</template>\n"
        },
        {
          "path": "registry/default/vue/tooltip/tooltip-provider.vue",
          "target": "components/ui/tooltip/tooltip-provider.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { useAttrs } from 'vue'\n\nconst attrs = useAttrs()\n</script>\n\n<template>\n  <div v-bind=\"attrs\" data-slot=\"tooltip-provider\">\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/tooltip/tooltip-trigger.vue",
          "target": "components/ui/tooltip/tooltip-trigger.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, type Component, type HTMLAttributes } from \"vue\";\nimport { cn } from \"@timui/core\";\nimport { Primitive } from '../../primitive';\nimport { useTooltipContext } from \"./use-tooltip-context\";\n\nconst props = withDefaults(\n  defineProps<{\n    as?: string | Component;\n    asChild?: boolean;\n    class?: HTMLAttributes[\"class\"];\n  }>(),\n  {\n    as: \"button\",\n  }\n);\n\nconst context = useTooltipContext();\nconst triggerProps = computed(() => ({\n  ...(context.value.getTriggerProps?.() ?? {}),\n  type: props.asChild ? undefined : \"button\",\n  \"data-slot\": \"tooltip-trigger\",\n}));\n</script>\n\n<template>\n  <Primitive\n    :as=\"props.as\"\n    :as-child=\"props.asChild\"\n    :class=\"cn(props.class)\"\n    v-bind=\"triggerProps\"\n  >\n    <slot />\n  </Primitive>\n</template>\n"
        },
        {
          "path": "registry/default/vue/tooltip/tooltip.vue",
          "target": "components/ui/tooltip/tooltip.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes } from \"vue\";\nimport type { PositioningOptions } from \"@zag-js/popper\";\nimport { useTooltip } from \"./use-tooltip\";\nimport { TooltipProvider } from \"./use-tooltip-context\";\n\nconst props = defineProps<{\n  open?: boolean;\n  defaultOpen?: boolean;\n  openDelay?: number;\n  closeDelay?: number;\n  disabled?: boolean;\n  closeOnPointerDown?: boolean;\n  closeOnEscape?: boolean;\n  closeOnScroll?: boolean;\n  closeOnClick?: boolean;\n  interactive?: boolean;\n  positioning?: PositioningOptions;\n  onOpenChange?: (open: boolean) => void;\n  id?: string;\n  class?: HTMLAttributes[\"class\"];\n}>();\n\nconst emit = defineEmits([\"update:open\", \"change\"]);\n\nconst api = useTooltip(props, emit);\nTooltipProvider(api);\n</script>\n\n<template>\n  <slot />\n</template>\n"
        },
        {
          "path": "registry/default/vue/tooltip/use-tooltip-context.ts",
          "target": "components/ui/tooltip/use-tooltip-context.ts",
          "type": "registry:component",
          "content": "import { createContext } from '../../hooks/create-context'\nimport type { useTooltip } from './use-tooltip'\n\nexport type UseTooltipReturn = ReturnType<typeof useTooltip>\n\nexport const [TooltipProvider, useTooltipContext] = createContext<UseTooltipReturn>({\n  id: 'tooltipContext',\n  providerName: '<Tooltip />',\n})\n"
        },
        {
          "path": "registry/default/vue/tooltip/use-tooltip.ts",
          "target": "components/ui/tooltip/use-tooltip.ts",
          "type": "registry:component",
          "content": "import { tooltipConnect, tooltipMachine } from '@timui/core'\nimport type { PositioningOptions } from '@zag-js/popper'\nimport { normalizeProps, useMachine } from '@zag-js/vue'\nimport { computed, useId, watch } from 'vue'\n\nexport interface UseTooltipProps {\n  id?: string\n  open?: boolean\n  defaultOpen?: boolean\n  openDelay?: number\n  closeDelay?: number\n  disabled?: boolean\n  closeOnPointerDown?: boolean\n  closeOnEscape?: boolean\n  closeOnScroll?: boolean\n  closeOnClick?: boolean\n  interactive?: boolean\n  positioning?: PositioningOptions\n  onOpenChange?: (open: boolean) => void\n}\n\nexport interface UseTooltipEmits {\n  (e: 'update:open', value: boolean): void\n  (e: 'change', value: boolean): void\n}\n\nexport function useTooltip(props: UseTooltipProps, emit: UseTooltipEmits) {\n  const generatedId = useId()\n\n  const machineProps = computed(() => ({\n    id: props.id ?? generatedId,\n    open: props.open,\n    defaultOpen: props.open === undefined ? props.defaultOpen : undefined,\n    openDelay: props.openDelay,\n    closeDelay: props.closeDelay,\n    disabled: props.disabled,\n    closeOnPointerDown: props.closeOnPointerDown,\n    closeOnEscape: props.closeOnEscape,\n    closeOnScroll: props.closeOnScroll,\n    closeOnClick: props.closeOnClick,\n    interactive: props.interactive,\n    positioning: props.positioning,\n    onOpenChange(details: { open: boolean }) {\n      props.onOpenChange?.(details.open)\n      emit('update:open', details.open)\n      emit('change', details.open)\n    },\n  }))\n\n  const service = useMachine(tooltipMachine, machineProps)\n  const api = computed(() => tooltipConnect(service, normalizeProps))\n\n  watch(\n    () => props.open,\n    (val?: boolean) => {\n      if (val !== undefined && val !== api.value.open) {\n        api.value.setOpen(val)\n      }\n    }\n  )\n\n  return api\n}\n"
        },
        {
          "path": "registry/default/html/tooltip.html",
          "target": "components/ui/tooltip.html",
          "type": "registry:component",
          "content": "<div data-timui-root data-timui-init=\"auto\">\n  <div data-slot=\"tooltip-root\" data-state=\"closed\" class=\"relative inline-flex\">\n    <button\n      data-slot=\"tooltip-trigger\"\n      type=\"button\"\n      class=\"rounded-md border px-3 py-2 text-sm\"\n    >\n      Hover for details\n    </button>\n    <div\n      data-slot=\"tooltip-content\"\n      data-state=\"closed\"\n      hidden\n      class=\"data-[state&#x3D;open]:animate-in data-[state&#x3D;closed]:animate-out data-[state&#x3D;closed]:fade-out-0 data-[state&#x3D;open]:fade-in-0 data-[state&#x3D;closed]:zoom-out-95 data-[state&#x3D;open]:zoom-in-95 data-[side&#x3D;bottom]:slide-in-from-top-2 data-[side&#x3D;left]:slide-in-from-right-2 data-[side&#x3D;right]:slide-in-from-left-2 data-[side&#x3D;top]:slide-in-from-bottom-2 z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-xs text-popover-foreground shadow-md absolute left-1/2 top-full z-50 mt-2 -translate-x-1/2 whitespace-nowrap\"\n    >\n      Tooltip content\n    </div>\n  </div>\n</div>\n<script type=\"module\">\n  import { autoInitHtmlRuntime } from '@timui/html'\n  autoInitHtmlRuntime({ components: ['tooltip'] })\n</script>"
        },
        {
          "path": "registry/default/weapp/tooltip.wxml",
          "target": "components/ui/tooltip.wxml",
          "type": "registry:component",
          "content": "<view class=\"relative inline-block\">\n  <view bindlongtap=\"onTriggerLongPress\" bindtouchend=\"onTriggerTouchEnd\">\n    <slot name=\"trigger\"></slot>\n  </view>\n  <view wx:if=\"{{open}}\" class=\"{{contentClass}} absolute z-50\">\n    <slot name=\"content\"></slot>\n  </view>\n</view>\n\n"
        },
        {
          "path": "registry/default/weapp/tooltip.wxss",
          "target": "components/ui/tooltip.wxss",
          "type": "registry:component",
          "content": "/* Tooltip specific styles */\n.relative { position: relative; }\n.inline-block { display: inline-block; }\n.absolute { position: absolute; }\n"
        },
        {
          "path": "registry/default/weapp/tooltip.ts",
          "target": "components/ui/tooltip.ts",
          "type": "registry:component",
          "content": "import { resolveClasses, tooltipContentVariants } from '../utils'\nimport { setupTooltipMachine } from './use-tooltip'\n\ntype MachineEvent =\n  | string\n  | {\n      type: string\n      [key: string]: string | number | boolean | string[] | number[] | null | undefined\n    }\n\ntype WeappTooltipApi = {\n  open?: () => void\n  close?: () => void\n}\n\ntype WeappService = {\n  setContext: (context: { disabled?: boolean; openDelay?: number; closeDelay?: number }) => void\n}\n\ntype WeappTooltipInternal = WechatMiniprogram.Component.InstanceMethods<WeappTooltipApi> & {\n  _service?: WeappService\n  _cleanup?: () => void\n  _send?: (event: MachineEvent) => void\n  _connect?: (state: object, send: (event: MachineEvent) => void) => WeappTooltipApi\n  data: {\n    api: WeappTooltipApi\n  }\n  properties: {\n    disabled: boolean\n    openDelay: number\n    closeDelay: number\n    id: string\n    extClass: string\n  }\n}\n\nComponent({\n  options: {\n    multipleSlots: true,\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    disabled: { type: Boolean, value: false },\n    openDelay: { type: Number, value: 700 },\n    closeDelay: { type: Number, value: 300 },\n    id: { type: String, value: 'tooltip' },\n    extClass: { type: String, value: '' },\n  },\n\n  data: {\n    api: {} as WeappTooltipApi,\n    contentClass: '',\n  },\n\n  lifetimes: {\n    attached() {\n      const self = this as WeappTooltipInternal\n      const { controller, connect } = setupTooltipMachine(self)\n\n      self._service = controller.service as WeappService\n      self._cleanup = controller.start()\n      self._send = controller.send as (event: MachineEvent) => void\n      self._connect = connect\n    },\n    detached() {\n      const self = this as WeappTooltipInternal\n      self._cleanup?.()\n    },\n  },\n\n  observers: {\n    state: function (state) {\n      const self = this as WeappTooltipInternal\n      if (!state || !self._send || !self._connect) return\n      const api = self._connect(state, self._send) as WeappTooltipApi\n\n      const contentClass = resolveClasses(tooltipContentVariants())\n\n      this.setData({ api, contentClass })\n    },\n  },\n\n  methods: {\n    onTriggerLongPress() {\n      const self = this as WeappTooltipInternal\n      self.data.api.open?.()\n    },\n    onTriggerTouchEnd() {\n      const self = this as WeappTooltipInternal\n      self.data.api.close?.()\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/tooltip.json",
          "target": "components/ui/tooltip.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        }
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@zag-js/popper",
              "@zag-js/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@zag-js/popper",
              "@zag-js/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "tree",
      "type": "registry:component",
      "dependencies": [
        "@headless-tree/core",
        "@timui/core"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/ui/tree.tsx",
          "type": "registry:component",
          "target": "components/ui/tree.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport { ItemInstance } from '@headless-tree/core'\nimport type { AssertNoExtraKeys, TreeProps as CoreTreeProps, TreeContainerApi } from '@timui/core'\nimport {\n  cn,\n  treeDragLineVariants,\n  treeItemLabelIconVariants,\n  treeItemLabelVariants,\n  treeItemVariants,\n  treeVariants,\n} from '@timui/core'\nimport { ChevronDownIcon } from 'lucide-react'\n\nimport { Slot } from './slot'\n\ninterface TreeContextValue<T = Record<string, never>> {\n  indent: number\n  currentItem?: ItemInstance<T>\n  tree?: TreeContainerApi\n}\n\nconst TreeContext = React.createContext<TreeContextValue>({\n  indent: 20,\n  currentItem: undefined,\n  tree: undefined,\n})\n\nfunction useTreeContext<T = Record<string, never>>() {\n  return React.useContext(TreeContext) as TreeContextValue<T>\n}\n\ntype TreeProps = CoreTreeProps & React.HTMLAttributes<HTMLDivElement>\ntype _TreePropsGuard = AssertNoExtraKeys<\n  TreeProps,\n  CoreTreeProps & React.HTMLAttributes<HTMLDivElement>\n>\n\nfunction Tree({ indent = 20, tree, className, ...props }: TreeProps) {\n  const containerProps = tree?.getContainerProps?.() ?? {}\n  const mergedProps = { ...props, ...containerProps }\n\n  // Extract style from mergedProps to merge with our custom styles\n  const { style: propStyle, ...otherProps } = mergedProps\n\n  // Merge styles\n  const mergedStyle = {\n    ...propStyle,\n    '--tree-indent': `${indent}px`,\n  } as React.CSSProperties\n\n  return (\n    <TreeContext.Provider value={{ indent, tree }}>\n      <div\n        data-slot=\"tree\"\n        style={mergedStyle}\n        className={cn(treeVariants(), className)}\n        {...otherProps}\n      />\n    </TreeContext.Provider>\n  )\n}\n\ninterface TreeItemProps<T = Record<string, never>> extends React.HTMLAttributes<HTMLButtonElement> {\n  item: ItemInstance<T>\n  indent?: number\n  asChild?: boolean\n}\n\nfunction TreeItem<T = Record<string, never>>({\n  item,\n  className,\n  asChild,\n  children,\n  ...props\n}: Omit<TreeItemProps<T>, 'indent'>) {\n  const { indent } = useTreeContext<T>()\n\n  const itemProps = typeof item.getProps === 'function' ? item.getProps() : {}\n  const mergedProps = { ...props, ...itemProps }\n\n  // Extract style from mergedProps to merge with our custom styles\n  const { style: propStyle, ...otherProps } = mergedProps\n\n  // Merge styles\n  const mergedStyle = {\n    ...propStyle,\n    '--tree-padding': `${item.getItemMeta().level * indent}px`,\n  } as React.CSSProperties\n\n  const Comp = asChild ? Slot : 'button'\n\n  return (\n    <TreeContext.Provider\n      value={{ indent, currentItem: item as ItemInstance<Record<string, never>> }}\n    >\n      <Comp\n        data-slot=\"tree-item\"\n        style={mergedStyle}\n        className={cn(treeItemVariants(), className)}\n        data-focus={typeof item.isFocused === 'function' ? item.isFocused() || false : undefined}\n        data-folder={typeof item.isFolder === 'function' ? item.isFolder() || false : undefined}\n        data-selected={\n          typeof item.isSelected === 'function' ? item.isSelected() || false : undefined\n        }\n        data-drag-target={\n          typeof item.isDragTarget === 'function' ? item.isDragTarget() || false : undefined\n        }\n        data-search-match={\n          typeof item.isMatchingSearch === 'function' ? item.isMatchingSearch() || false : undefined\n        }\n        aria-expanded={item.isExpanded()}\n        {...otherProps}\n      >\n        {children}\n      </Comp>\n    </TreeContext.Provider>\n  )\n}\n\ninterface TreeItemLabelProps<\n  T = Record<string, never>,\n> extends React.HTMLAttributes<HTMLSpanElement> {\n  item?: ItemInstance<T>\n}\n\nfunction TreeItemLabel<T = Record<string, never>>({\n  item: propItem,\n  children,\n  className,\n  ...props\n}: TreeItemLabelProps<T>) {\n  const { currentItem } = useTreeContext<T>()\n  const item = propItem || currentItem\n\n  if (!item) {\n    console.warn('TreeItemLabel: No item provided via props or context')\n    return null\n  }\n\n  return (\n    <span data-slot=\"tree-item-label\" className={cn(treeItemLabelVariants(), className)} {...props}>\n      {item.isFolder() && <ChevronDownIcon className={treeItemLabelIconVariants()} />}\n      {children || (typeof item.getItemName === 'function' ? item.getItemName() : null)}\n    </span>\n  )\n}\n\nfunction TreeDragLine({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n  const { tree } = useTreeContext()\n\n  if (!tree || typeof tree.getDragLineStyle !== 'function') {\n    console.warn(\n      'TreeDragLine: No tree provided via context or tree does not have getDragLineStyle method'\n    )\n    return null\n  }\n\n  const dragLine = tree.getDragLineStyle()\n  return (\n    <div\n      style={dragLine ?? undefined}\n      className={cn(treeDragLineVariants(), className)}\n      {...props}\n    />\n  )\n}\n\nexport { Tree, TreeItem, TreeItemLabel, TreeDragLine }\n"
        },
        {
          "path": "registry/default/vue/tree.vue",
          "type": "registry:component",
          "target": "components/ui/tree.vue",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed, toRef } from \"vue\";\nimport { cn, treeVariants } from '@timui/core';\nimport { provideTreeContext, type TreeApi } from \"./tree-context\";\n\nconst props = withDefaults(\n  defineProps<{\n    class?: HTMLAttributes[\"class\"];\n    indent?: number;\n    tree?: TreeApi;\n  }>(),\n  {\n    indent: 20,\n  }\n);\n\ntype TreeBindValue =\n  | string\n  | number\n  | boolean\n  | null\n  | undefined\n  | Record<string, string | number>;\n\ntype TreeContainerProps = {\n  style?: Record<string, string | number>;\n  [key: string]: TreeBindValue;\n};\n\nprovideTreeContext({\n  indent: toRef(props, \"indent\"),\n  tree: props.tree,\n});\n\nconst containerProps = computed<TreeContainerProps>(() => {\n  return props.tree && typeof props.tree.getContainerProps === \"function\"\n    ? (props.tree.getContainerProps() as TreeContainerProps)\n    : {};\n});\n\nconst mergedStyle = computed(() => {\n  const style = containerProps.value.style || {};\n  return {\n    ...style,\n    \"--tree-indent\": `${props.indent}px`,\n  };\n});\n</script>\n\n<template>\n  <div\n    data-slot=\"tree\"\n    :style=\"mergedStyle\"\n    :class=\"cn(treeVariants(), props.class)\"\n    v-bind=\"containerProps\"\n  >\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/tree/tree-context.ts",
          "target": "components/ui/tree/tree-context.ts",
          "type": "registry:component",
          "content": "import { createContext } from 'radix-vue'\nimport type { Ref } from 'vue'\n\nexport type TreeApi = {\n  getContainerProps?: () => Record<string, string | number | boolean | undefined>\n  getDragLineStyle?: () => Record<string, string | number> | null\n}\n\nexport type TreeItemApi = {\n  getProps?: () => Record<string, string | number | boolean | undefined>\n  getItemMeta?: () => { level: number }\n  isFocused?: () => boolean\n  isFolder?: () => boolean\n  isSelected?: () => boolean\n  isDragTarget?: () => boolean\n  isMatchingSearch?: () => boolean\n  isExpanded?: () => boolean\n  getItemName?: () => string\n}\n\nexport interface TreeContextValue {\n  indent: Ref<number>\n  tree?: TreeApi\n}\n\nexport interface TreeItemContextValue {\n  indent: Ref<number>\n  currentItem?: TreeItemApi\n}\n\nexport const [injectTreeContext, provideTreeContext] = createContext<TreeContextValue>('Tree')\n\nexport const [injectTreeItemContext, provideTreeItemContext] =\n  createContext<TreeItemContextValue>('TreeItem')\n"
        },
        {
          "path": "registry/default/vue/tree/tree-drag-line.vue",
          "target": "components/ui/tree/tree-drag-line.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed } from \"vue\";\nimport { cn, treeDragLineVariants } from '@timui/core';\nimport { injectTreeContext } from \"./tree-context\";\n\nconst props = defineProps<{\n  class?: HTMLAttributes[\"class\"];\n}>();\n\nconst context = injectTreeContext();\nconst tree = context?.tree;\n\nconst dragLineStyle = computed(() => {\n  if (tree && typeof tree.getDragLineStyle === \"function\") {\n    return tree.getDragLineStyle();\n  }\n  return {};\n});\n</script>\n\n<template>\n  <div\n    v-if=\"tree && tree.getDragLineStyle\"\n    :style=\"dragLineStyle\"\n    :class=\"\n      cn(\n        treeDragLineVariants(),\n        props.class\n      )\n    \"\n  />\n</template>\n"
        },
        {
          "path": "registry/default/vue/tree/tree-item-label.vue",
          "target": "components/ui/tree/tree-item-label.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed } from \"vue\";\nimport { ChevronDown } from \"lucide-vue-next\";\nimport { cn, treeItemLabelIconVariants, treeItemLabelVariants } from '@timui/core';\nimport { injectTreeItemContext, type TreeItemApi } from \"./tree-context\";\n\nconst props = defineProps<{\n  class?: HTMLAttributes[\"class\"];\n  item?: TreeItemApi;\n}>();\n\nconst context = injectTreeItemContext();\n\nconst item = computed(() => props.item || context?.currentItem);\n\nconst isFolder = computed(() =>\n  item.value && typeof item.value.isFolder === \"function\"\n    ? item.value.isFolder()\n    : false\n);\nconst itemName = computed(() =>\n  item.value && typeof item.value.getItemName === \"function\"\n    ? item.value.getItemName()\n    : null\n);\n</script>\n\n<template>\n  <span\n    v-if=\"item\"\n    data-slot=\"tree-item-label\"\n    :class=\"\n      cn(\n        treeItemLabelVariants(),\n        props.class\n      )\n    \"\n  >\n    <template v-if=\"isFolder\">\n      <ChevronDown\n        :class=\"treeItemLabelIconVariants()\"\n      />\n    </template>\n    <slot>\n      {{ itemName }}\n    </slot>\n  </span>\n</template>\n"
        },
        {
          "path": "registry/default/vue/tree/tree-item.vue",
          "target": "components/ui/tree/tree-item.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed } from \"vue\";\nimport { Primitive, type PrimitiveProps } from '../../primitive';\nimport { cn, treeItemVariants } from '@timui/core';\nimport { injectTreeContext, provideTreeItemContext, type TreeItemApi } from \"./tree-context\";\n\nconst props = withDefaults(\n  defineProps<\n    PrimitiveProps & {\n      class?: HTMLAttributes[\"class\"];\n      item: TreeItemApi;\n    }\n  >(),\n  {\n    as: \"button\",\n  }\n);\n\nconst context = injectTreeContext();\nif (!context) {\n  throw new Error(\"TreeItem must be used within a Tree\");\n}\nconst { indent } = context;\n\nprovideTreeItemContext({\n  indent,\n  currentItem: props.item,\n});\n\ntype TreeBindValue =\n  | string\n  | number\n  | boolean\n  | null\n  | undefined\n  | Record<string, string | number>;\n\ntype TreeItemPropsMap = {\n  style?: Record<string, string | number>;\n  [key: string]: TreeBindValue;\n};\n\nconst itemProps = computed(() => {\n  return typeof props.item.getProps === \"function\" ? (props.item.getProps() as TreeItemPropsMap) : {};\n});\n\nconst mergedStyle = computed(() => {\n  const level = typeof props.item.getItemMeta === \"function\" ? props.item.getItemMeta().level : 0;\n  const style = itemProps.value.style || {};\n  return {\n    ...style,\n    \"--tree-padding\": `${level * indent.value}px`,\n  };\n});\n\nconst isFocused = computed(() =>\n  typeof props.item.isFocused === \"function\" ? props.item.isFocused() : false\n);\nconst isFolder = computed(() =>\n  typeof props.item.isFolder === \"function\" ? props.item.isFolder() : false\n);\nconst isSelected = computed(() =>\n  typeof props.item.isSelected === \"function\" ? props.item.isSelected() : false\n);\nconst isDragTarget = computed(() =>\n  typeof props.item.isDragTarget === \"function\"\n    ? props.item.isDragTarget()\n    : false\n);\nconst isMatchingSearch = computed(() =>\n  typeof props.item.isMatchingSearch === \"function\"\n    ? props.item.isMatchingSearch()\n    : false\n);\nconst isExpanded = computed(() =>\n  typeof props.item.isExpanded === \"function\" ? props.item.isExpanded() : false\n);\n</script>\n\n<template>\n  <Primitive\n    data-slot=\"tree-item\"\n    :as=\"as\"\n    :as-child=\"asChild\"\n    :style=\"mergedStyle\"\n    :class=\"\n      cn(\n        treeItemVariants(),\n        props.class\n      )\n    \"\n    :data-focus=\"isFocused || undefined\"\n    :data-folder=\"isFolder || undefined\"\n    :data-selected=\"isSelected || undefined\"\n    :data-drag-target=\"isDragTarget || undefined\"\n    :data-search-match=\"isMatchingSearch || undefined\"\n    :aria-expanded=\"isExpanded\"\n    v-bind=\"itemProps\"\n  >\n    <slot />\n  </Primitive>\n</template>\n"
        },
        {
          "path": "registry/default/vue/tree/tree.vue",
          "target": "components/ui/tree/tree.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed, toRef } from \"vue\";\nimport { cn, treeVariants } from '@timui/core';\nimport { provideTreeContext, type TreeApi } from \"./tree-context\";\n\nconst props = withDefaults(\n  defineProps<{\n    class?: HTMLAttributes[\"class\"];\n    indent?: number;\n    tree?: TreeApi;\n  }>(),\n  {\n    indent: 20,\n  }\n);\n\ntype TreeBindValue =\n  | string\n  | number\n  | boolean\n  | null\n  | undefined\n  | Record<string, string | number>;\n\ntype TreeContainerProps = {\n  style?: Record<string, string | number>;\n  [key: string]: TreeBindValue;\n};\n\nprovideTreeContext({\n  indent: toRef(props, \"indent\"),\n  tree: props.tree,\n});\n\nconst containerProps = computed<TreeContainerProps>(() => {\n  return props.tree && typeof props.tree.getContainerProps === \"function\"\n    ? (props.tree.getContainerProps() as TreeContainerProps)\n    : {};\n});\n\nconst mergedStyle = computed(() => {\n  const style = containerProps.value.style || {};\n  return {\n    ...style,\n    \"--tree-indent\": `${props.indent}px`,\n  };\n});\n</script>\n\n<template>\n  <div\n    data-slot=\"tree\"\n    :style=\"mergedStyle\"\n    :class=\"cn(treeVariants(), props.class)\"\n    v-bind=\"containerProps\"\n  >\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/html/tree.html",
          "target": "components/ui/tree.html",
          "type": "registry:component",
          "content": "<ul data-slot=\"tree\" class=\"space-y-1 text-sm\">\n  <li>\n    <button type=\"button\" class=\"inline-flex items-center\">\n      <span>▾</span><span>src</span>\n    </button>\n    <ul class=\"ml-5 mt-1 space-y-1\">\n      <li><button type=\"button\" class=\"rounded-sm px-2 py-1 hover:bg-accent\">components</button></li>\n      <li><button type=\"button\" class=\"rounded-sm px-2 py-1 hover:bg-accent\">hooks</button></li>\n    </ul>\n  </li>\n</ul>"
        },
        {
          "path": "registry/default/weapp/tree.wxml",
          "target": "components/ui/tree.wxml",
          "type": "registry:component",
          "content": "<view class=\"tree {{extClass}}\">\n  <block wx:for=\"{{flatNodes}}\" wx:key=\"id\">\n    <view class=\"tree-row\" style=\"padding-left: {{item.level * 24}}rpx;\">\n      <view\n        wx:if=\"{{item.children && item.children.length}}\"\n        class=\"tree-toggle\"\n        data-id=\"{{item.id}}\"\n        bindtap=\"onToggle\"\n      >\n        <text>{{expandedMap[item.id] ? '▾' : '▸'}}</text>\n      </view>\n      <view wx:else class=\"tree-toggle tree-toggle-empty\"></view>\n      <view class=\"tree-label\" data-id=\"{{item.id}}\" bindtap=\"onSelect\">\n        <text>{{item.label}}</text>\n      </view>\n    </view>\n  </block>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/tree.wxss",
          "target": "components/ui/tree.wxss",
          "type": "registry:component",
          "content": ".tree {\n  display: flex;\n  flex-direction: column;\n  gap: 8rpx;\n}\n\n.tree-row {\n  display: flex;\n  align-items: center;\n  gap: 8rpx;\n  min-height: 48rpx;\n}\n\n.tree-toggle {\n  width: 28rpx;\n  color: #6b7280;\n}\n\n.tree-toggle-empty {\n  visibility: hidden;\n}\n\n.tree-label {\n  flex: 1;\n  font-size: 26rpx;\n  color: #111827;\n}\n"
        },
        {
          "path": "registry/default/weapp/tree.ts",
          "target": "components/ui/tree.ts",
          "type": "registry:component",
          "content": "type TreeNode = {\n  id: string\n  label: string\n  children?: TreeNode[]\n}\n\ntype FlatNode = TreeNode & { level: number }\n\nconst flatten = (nodes: TreeNode[], level = 0, acc: FlatNode[] = []) => {\n  nodes.forEach((node) => {\n    acc.push({ ...node, level })\n    if (Array.isArray(node.children) && node.children.length > 0) {\n      flatten(node.children, level + 1, acc)\n    }\n  })\n  return acc\n}\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    nodes: {\n      type: Array,\n      value: [],\n    },\n    expandedKeys: {\n      type: Array,\n      value: [],\n    },\n    extClass: {\n      type: String,\n      value: '',\n    },\n  },\n\n  data: {\n    flatNodes: [] as FlatNode[],\n    expandedMap: {} as Record<string, boolean>,\n  },\n\n  lifetimes: {\n    attached() {\n      this.syncData()\n    },\n  },\n\n  observers: {\n    'nodes, expandedKeys': function () {\n      this.syncData()\n    },\n  },\n\n  methods: {\n    syncData() {\n      const flatNodes = flatten((this.properties.nodes || []) as TreeNode[])\n      const expandedMap: Record<string, boolean> = {}\n      ;(this.properties.expandedKeys as string[]).forEach((id) => {\n        expandedMap[id] = true\n      })\n      this.setData({ flatNodes, expandedMap })\n    },\n\n    hasChildren(node: FlatNode) {\n      return Array.isArray(node.children) && node.children.length > 0\n    },\n\n    onToggle(e: WechatMiniprogram.BaseEvent) {\n      const id = String(e.currentTarget.dataset.id || '')\n      if (!id) return\n      const expandedMap = { ...(this.data.expandedMap || {}) }\n      expandedMap[id] = !expandedMap[id]\n      const expandedKeys = Object.keys(expandedMap).filter((key) => expandedMap[key])\n      this.setData({ expandedMap })\n      this.triggerEvent('expandedChange', { expandedKeys })\n      this.triggerEvent('update:expandedKeys', expandedKeys)\n    },\n\n    onSelect(e: WechatMiniprogram.BaseEvent) {\n      const id = String(e.currentTarget.dataset.id || '')\n      if (!id) return\n      this.triggerEvent('select', { id })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/tree.json",
          "target": "components/ui/tree.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        }
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@headless-tree/core",
              "@timui/core"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next",
              "radix-vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": true
      }
    },
    {
      "name": "use-character-limit",
      "type": "registry:hook",
      "files": [
        {
          "path": "registry/default/hooks/use-character-limit.ts",
          "type": "registry:hook",
          "target": "components/ui/use-character-limit/use-character-limit.ts",
          "content": "'use client'\n\nimport { ChangeEvent, useState } from 'react'\n\ntype UseCharacterLimitProps = {\n  maxLength: number\n  initialValue?: string\n}\n\nexport function useCharacterLimit({ maxLength, initialValue = '' }: UseCharacterLimitProps) {\n  const [value, setValue] = useState(initialValue)\n  const [characterCount, setCharacterCount] = useState(initialValue.length)\n\n  const handleChange = (e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {\n    const newValue = e.target.value\n    if (newValue.length <= maxLength) {\n      setValue(newValue)\n      setCharacterCount(newValue.length)\n    }\n  }\n\n  return {\n    value,\n    characterCount,\n    handleChange,\n    maxLength,\n  }\n}\n"
        }
      ],
      "meta": {
        "frameworks": [],
        "dependenciesByFramework": {},
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "use-file-upload",
      "type": "registry:hook",
      "files": [
        {
          "path": "registry/default/hooks/use-file-upload.ts",
          "type": "registry:hook",
          "target": "components/ui/use-file-upload/use-file-upload.ts",
          "content": "'use client'\n\nimport type React from 'react'\nimport {\n  useCallback,\n  useRef,\n  useState,\n  type ChangeEvent,\n  type DragEvent,\n  type InputHTMLAttributes,\n} from 'react'\n\nexport type FileMetadata = {\n  name: string\n  size: number\n  type: string\n  url: string\n  id: string\n}\n\nexport type FileWithPreview = {\n  file: File | FileMetadata\n  id: string\n  preview?: string\n}\n\nexport type FileUploadOptions = {\n  maxFiles?: number // Only used when multiple is true, defaults to Infinity\n  maxSize?: number // in bytes\n  accept?: string\n  multiple?: boolean // Defaults to false\n  initialFiles?: FileMetadata[]\n  onFilesChange?: (files: FileWithPreview[]) => void // Callback when files change\n  onFilesAdded?: (addedFiles: FileWithPreview[]) => void // Callback when new files are added\n}\n\nexport type FileUploadState = {\n  files: FileWithPreview[]\n  isDragging: boolean\n  errors: string[]\n}\n\nexport type FileUploadActions = {\n  addFiles: (files: FileList | File[]) => void\n  removeFile: (id: string) => void\n  clearFiles: () => void\n  clearErrors: () => void\n  handleDragEnter: (e: DragEvent<HTMLElement>) => void\n  handleDragLeave: (e: DragEvent<HTMLElement>) => void\n  handleDragOver: (e: DragEvent<HTMLElement>) => void\n  handleDrop: (e: DragEvent<HTMLElement>) => void\n  handleFileChange: (e: ChangeEvent<HTMLInputElement>) => void\n  openFileDialog: () => void\n  getInputProps: (\n    props?: InputHTMLAttributes<HTMLInputElement>\n  ) => InputHTMLAttributes<HTMLInputElement> & {\n    ref: React.Ref<HTMLInputElement>\n  }\n}\n\nexport const useFileUpload = (\n  options: FileUploadOptions = {}\n): [FileUploadState, FileUploadActions] => {\n  const {\n    maxFiles = Infinity,\n    maxSize = Infinity,\n    accept = '*',\n    multiple = false,\n    initialFiles = [],\n    onFilesChange,\n    onFilesAdded,\n  } = options\n\n  const [state, setState] = useState<FileUploadState>({\n    files: initialFiles.map((file) => ({\n      file,\n      id: file.id,\n      preview: file.url,\n    })),\n    isDragging: false,\n    errors: [],\n  })\n\n  const inputRef = useRef<HTMLInputElement>(null)\n\n  const validateFile = useCallback(\n    (file: File | FileMetadata): string | null => {\n      if (file instanceof File) {\n        if (file.size > maxSize) {\n          return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n        }\n      } else {\n        if (file.size > maxSize) {\n          return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n        }\n      }\n\n      if (accept !== '*') {\n        const acceptedTypes = accept.split(',').map((type) => type.trim())\n        const fileType = file instanceof File ? file.type || '' : file.type\n        const fileExtension = `.${file instanceof File ? file.name.split('.').pop() : file.name.split('.').pop()}`\n\n        const isAccepted = acceptedTypes.some((type) => {\n          if (type.startsWith('.')) {\n            return fileExtension.toLowerCase() === type.toLowerCase()\n          }\n          if (type.endsWith('/*')) {\n            const baseType = type.split('/')[0]\n            return fileType.startsWith(`${baseType}/`)\n          }\n          return fileType === type\n        })\n\n        if (!isAccepted) {\n          return `File \"${file instanceof File ? file.name : file.name}\" is not an accepted file type.`\n        }\n      }\n\n      return null\n    },\n    [accept, maxSize]\n  )\n\n  const createPreview = useCallback((file: File | FileMetadata): string | undefined => {\n    if (file instanceof File) {\n      return URL.createObjectURL(file)\n    }\n    return file.url\n  }, [])\n\n  const generateUniqueId = useCallback((file: File | FileMetadata): string => {\n    if (file instanceof File) {\n      return `${file.name}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`\n    }\n    return file.id\n  }, [])\n\n  const clearFiles = useCallback(() => {\n    setState((prev) => {\n      // Clean up object URLs\n      prev.files.forEach((file) => {\n        if (file.preview && file.file instanceof File && file.file.type.startsWith('image/')) {\n          URL.revokeObjectURL(file.preview)\n        }\n      })\n\n      if (inputRef.current) {\n        inputRef.current.value = ''\n      }\n\n      const newState = {\n        ...prev,\n        files: [],\n        errors: [],\n      }\n\n      onFilesChange?.(newState.files)\n      return newState\n    })\n  }, [onFilesChange])\n\n  const addFiles = useCallback(\n    (newFiles: FileList | File[]) => {\n      if (!newFiles || newFiles.length === 0) return\n\n      const newFilesArray = Array.from(newFiles)\n      const errors: string[] = []\n\n      // Clear existing errors when new files are uploaded\n      setState((prev) => ({ ...prev, errors: [] }))\n\n      // In single file mode, clear existing files first\n      if (!multiple) {\n        clearFiles()\n      }\n\n      // Check if adding these files would exceed maxFiles (only in multiple mode)\n      if (\n        multiple &&\n        maxFiles !== Infinity &&\n        state.files.length + newFilesArray.length > maxFiles\n      ) {\n        errors.push(`You can only upload a maximum of ${maxFiles} files.`)\n        setState((prev) => ({ ...prev, errors }))\n        return\n      }\n\n      const validFiles: FileWithPreview[] = []\n\n      newFilesArray.forEach((file) => {\n        // Only check for duplicates if multiple files are allowed\n        if (multiple) {\n          const isDuplicate = state.files.some(\n            (existingFile) =>\n              existingFile.file.name === file.name && existingFile.file.size === file.size\n          )\n\n          // Skip duplicate files silently\n          if (isDuplicate) {\n            return\n          }\n        }\n\n        // Check file size\n        if (file.size > maxSize) {\n          errors.push(\n            multiple\n              ? `Some files exceed the maximum size of ${formatBytes(maxSize)}.`\n              : `File exceeds the maximum size of ${formatBytes(maxSize)}.`\n          )\n          return\n        }\n\n        const error = validateFile(file)\n        if (error) {\n          errors.push(error)\n        } else {\n          validFiles.push({\n            file,\n            id: generateUniqueId(file),\n            preview: createPreview(file),\n          })\n        }\n      })\n\n      // Only update state if we have valid files to add\n      if (validFiles.length > 0) {\n        // Call the onFilesAdded callback with the newly added valid files\n        onFilesAdded?.(validFiles)\n\n        setState((prev) => {\n          const newFiles = !multiple ? validFiles : [...prev.files, ...validFiles]\n          onFilesChange?.(newFiles)\n          return {\n            ...prev,\n            files: newFiles,\n            errors,\n          }\n        })\n      } else if (errors.length > 0) {\n        setState((prev) => ({\n          ...prev,\n          errors,\n        }))\n      }\n\n      // Reset input value after handling files\n      if (inputRef.current) {\n        inputRef.current.value = ''\n      }\n    },\n    [\n      state.files,\n      maxFiles,\n      multiple,\n      maxSize,\n      validateFile,\n      createPreview,\n      generateUniqueId,\n      clearFiles,\n      onFilesChange,\n      onFilesAdded,\n    ]\n  )\n\n  const removeFile = useCallback(\n    (id: string) => {\n      setState((prev) => {\n        const fileToRemove = prev.files.find((file) => file.id === id)\n        if (\n          fileToRemove &&\n          fileToRemove.preview &&\n          fileToRemove.file instanceof File &&\n          fileToRemove.file.type.startsWith('image/')\n        ) {\n          URL.revokeObjectURL(fileToRemove.preview)\n        }\n\n        const newFiles = prev.files.filter((file) => file.id !== id)\n        onFilesChange?.(newFiles)\n\n        return {\n          ...prev,\n          files: newFiles,\n          errors: [],\n        }\n      })\n    },\n    [onFilesChange]\n  )\n\n  const clearErrors = useCallback(() => {\n    setState((prev) => ({\n      ...prev,\n      errors: [],\n    }))\n  }, [])\n\n  const handleDragEnter = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n    setState((prev) => ({ ...prev, isDragging: true }))\n  }, [])\n\n  const handleDragLeave = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n\n    if (e.currentTarget.contains(e.relatedTarget as Node)) {\n      return\n    }\n\n    setState((prev) => ({ ...prev, isDragging: false }))\n  }, [])\n\n  const handleDragOver = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n  }, [])\n\n  const handleDrop = useCallback(\n    (e: DragEvent<HTMLElement>) => {\n      e.preventDefault()\n      e.stopPropagation()\n      setState((prev) => ({ ...prev, isDragging: false }))\n\n      // Don't process files if the input is disabled\n      if (inputRef.current?.disabled) {\n        return\n      }\n\n      if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n        // In single file mode, only use the first file\n        if (!multiple) {\n          const file = e.dataTransfer.files[0]\n          addFiles([file])\n        } else {\n          addFiles(e.dataTransfer.files)\n        }\n      }\n    },\n    [addFiles, multiple]\n  )\n\n  const handleFileChange = useCallback(\n    (e: ChangeEvent<HTMLInputElement>) => {\n      if (e.target.files && e.target.files.length > 0) {\n        addFiles(e.target.files)\n      }\n    },\n    [addFiles]\n  )\n\n  const openFileDialog = useCallback(() => {\n    if (inputRef.current) {\n      inputRef.current.click()\n    }\n  }, [])\n\n  const getInputProps = useCallback(\n    (props: InputHTMLAttributes<HTMLInputElement> = {}) => {\n      return {\n        ...props,\n        type: 'file' as const,\n        onChange: handleFileChange,\n        accept: props.accept || accept,\n        multiple: props.multiple !== undefined ? props.multiple : multiple,\n        ref: inputRef,\n      }\n    },\n    [accept, multiple, handleFileChange]\n  )\n\n  return [\n    state,\n    {\n      addFiles,\n      removeFile,\n      clearFiles,\n      clearErrors,\n      handleDragEnter,\n      handleDragLeave,\n      handleDragOver,\n      handleDrop,\n      handleFileChange,\n      openFileDialog,\n      getInputProps,\n    },\n  ]\n}\n\n// Helper function to format bytes to human-readable format\nexport const formatBytes = (bytes: number, decimals = 2): string => {\n  if (bytes === 0) return '0 Bytes'\n\n  const k = 1024\n  const dm = decimals < 0 ? 0 : decimals\n  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']\n\n  const i = Math.floor(Math.log(bytes) / Math.log(k))\n\n  return Number.parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + sizes[i]\n}\n"
        }
      ],
      "meta": {
        "frameworks": [],
        "dependenciesByFramework": {},
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "use-pagination",
      "type": "registry:hook",
      "files": [
        {
          "path": "registry/default/hooks/use-pagination.ts",
          "type": "registry:hook",
          "target": "components/ui/use-pagination/use-pagination.ts",
          "content": "type UsePaginationProps = {\n  currentPage: number\n  totalPages: number\n  paginationItemsToDisplay: number\n}\n\ntype UsePaginationReturn = {\n  pages: number[]\n  showLeftEllipsis: boolean\n  showRightEllipsis: boolean\n}\n\nexport function usePagination({\n  currentPage,\n  totalPages,\n  paginationItemsToDisplay,\n}: UsePaginationProps): UsePaginationReturn {\n  const showLeftEllipsis = currentPage - 1 > paginationItemsToDisplay / 2\n  const showRightEllipsis = totalPages - currentPage + 1 > paginationItemsToDisplay / 2\n\n  function calculatePaginationRange(): number[] {\n    if (totalPages <= paginationItemsToDisplay) {\n      return Array.from({ length: totalPages }, (_, i) => i + 1)\n    }\n\n    const halfDisplay = Math.floor(paginationItemsToDisplay / 2)\n    const initialRange = {\n      start: currentPage - halfDisplay,\n      end: currentPage + halfDisplay,\n    }\n\n    const adjustedRange = {\n      start: Math.max(1, initialRange.start),\n      end: Math.min(totalPages, initialRange.end),\n    }\n\n    if (adjustedRange.start === 1) {\n      adjustedRange.end = paginationItemsToDisplay\n    }\n    if (adjustedRange.end === totalPages) {\n      adjustedRange.start = totalPages - paginationItemsToDisplay + 1\n    }\n\n    if (showLeftEllipsis) adjustedRange.start++\n    if (showRightEllipsis) adjustedRange.end--\n\n    return Array.from(\n      { length: adjustedRange.end - adjustedRange.start + 1 },\n      (_, i) => adjustedRange.start + i\n    )\n  }\n\n  const pages = calculatePaginationRange()\n\n  return {\n    pages,\n    showLeftEllipsis,\n    showRightEllipsis,\n  }\n}\n"
        }
      ],
      "meta": {
        "frameworks": [],
        "dependenciesByFramework": {},
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "use-slider-with-input",
      "type": "registry:hook",
      "files": [
        {
          "path": "registry/default/hooks/use-slider-with-input.ts",
          "type": "registry:hook",
          "target": "components/ui/use-slider-with-input/use-slider-with-input.ts",
          "content": "'use client'\n\nimport { useCallback, useState } from 'react'\n\ntype UseSliderWithInputProps = {\n  minValue?: number\n  maxValue?: number\n  initialValue?: number[]\n  defaultValue?: number[]\n}\n\nexport function useSliderWithInput({\n  minValue = 0,\n  maxValue = 100,\n  initialValue = [minValue],\n  defaultValue = [minValue],\n}: UseSliderWithInputProps) {\n  const [sliderValue, setSliderValue] = useState(initialValue)\n  const [inputValues, setInputValues] = useState(initialValue.map((v) => v.toString()))\n\n  const showReset =\n    sliderValue.length === defaultValue.length &&\n    !sliderValue.every((value, index) => value === defaultValue[index])\n\n  const validateAndUpdateValue = useCallback(\n    (rawValue: string, index: number) => {\n      if (rawValue === '' || rawValue === '-') {\n        const newInputValues = [...inputValues]\n        newInputValues[index] = '0'\n        setInputValues(newInputValues)\n\n        const newSliderValues = [...sliderValue]\n        newSliderValues[index] = 0\n        setSliderValue(newSliderValues)\n        return\n      }\n\n      const numValue = parseFloat(rawValue)\n\n      if (isNaN(numValue)) {\n        const newInputValues = [...inputValues]\n        newInputValues[index] = sliderValue[index]!.toString()\n        setInputValues(newInputValues)\n        return\n      }\n\n      let clampedValue = Math.min(maxValue, Math.max(minValue, numValue))\n\n      if (sliderValue.length > 1) {\n        if (index === 0) {\n          clampedValue = Math.min(clampedValue, sliderValue[1]!)\n        } else {\n          clampedValue = Math.max(clampedValue, sliderValue[0]!)\n        }\n      }\n\n      const newSliderValues = [...sliderValue]\n      newSliderValues[index] = clampedValue\n      setSliderValue(newSliderValues)\n\n      const newInputValues = [...inputValues]\n      newInputValues[index] = clampedValue.toString()\n      setInputValues(newInputValues)\n    },\n    [sliderValue, inputValues, minValue, maxValue]\n  )\n\n  const handleInputChange = useCallback(\n    (e: React.ChangeEvent<HTMLInputElement>, index: number) => {\n      const newValue = e.target.value\n      if (newValue === '' || /^-?\\d*\\.?\\d*$/.test(newValue)) {\n        const newInputValues = [...inputValues]\n        newInputValues[index] = newValue\n        setInputValues(newInputValues)\n      }\n    },\n    [inputValues]\n  )\n\n  const handleSliderChange = useCallback((newValue: number[]) => {\n    setSliderValue(newValue)\n    setInputValues(newValue.map((v) => v.toString()))\n  }, [])\n\n  const resetToDefault = useCallback(() => {\n    setSliderValue(defaultValue)\n    setInputValues(defaultValue.map((v) => v.toString()))\n  }, [defaultValue])\n\n  return {\n    sliderValue,\n    inputValues,\n    validateAndUpdateValue,\n    handleInputChange,\n    handleSliderChange,\n    resetToDefault,\n    showReset,\n  }\n}\n"
        }
      ],
      "meta": {
        "frameworks": [],
        "dependenciesByFramework": {},
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "use-toast",
      "type": "registry:hook",
      "files": [
        {
          "path": "registry/default/hooks/use-toast.ts",
          "type": "registry:hook",
          "target": "components/ui/use-toast/use-toast.ts",
          "content": "'use client'\n\n// Inspired by react-hot-toast library\nimport * as React from 'react'\n\nimport type { ToastActionElement, ToastProps } from '../components/ui/toast'\n\nconst TOAST_LIMIT = 1\nconst TOAST_REMOVE_DELAY = 1000000\n\ntype ToasterToast = ToastProps & {\n  id: string\n  title?: React.ReactNode\n  description?: React.ReactNode\n  action?: ToastActionElement\n}\n\nconst actionTypes = {\n  ADD_TOAST: 'ADD_TOAST',\n  UPDATE_TOAST: 'UPDATE_TOAST',\n  DISMISS_TOAST: 'DISMISS_TOAST',\n  REMOVE_TOAST: 'REMOVE_TOAST',\n} as const\n\nlet count = 0\n\nfunction genId() {\n  count = (count + 1) % Number.MAX_SAFE_INTEGER\n  return count.toString()\n}\n\ntype ActionType = typeof actionTypes\n\ntype Action =\n  | {\n      type: ActionType['ADD_TOAST']\n      toast: ToasterToast\n    }\n  | {\n      type: ActionType['UPDATE_TOAST']\n      toast: Partial<ToasterToast>\n    }\n  | {\n      type: ActionType['DISMISS_TOAST']\n      toastId?: ToasterToast['id']\n    }\n  | {\n      type: ActionType['REMOVE_TOAST']\n      toastId?: ToasterToast['id']\n    }\n\ninterface State {\n  toasts: ToasterToast[]\n}\n\nconst toastTimeouts = new Map<string, ReturnType<typeof setTimeout>>()\n\nconst addToRemoveQueue = (toastId: string) => {\n  if (toastTimeouts.has(toastId)) {\n    return\n  }\n\n  const timeout = setTimeout(() => {\n    toastTimeouts.delete(toastId)\n    dispatch({\n      type: 'REMOVE_TOAST',\n      toastId: toastId,\n    })\n  }, TOAST_REMOVE_DELAY)\n\n  toastTimeouts.set(toastId, timeout)\n}\n\nexport const reducer = (state: State, action: Action): State => {\n  switch (action.type) {\n    case 'ADD_TOAST':\n      return {\n        ...state,\n        toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT),\n      }\n\n    case 'UPDATE_TOAST':\n      return {\n        ...state,\n        toasts: state.toasts.map((t) => (t.id === action.toast.id ? { ...t, ...action.toast } : t)),\n      }\n\n    case 'DISMISS_TOAST': {\n      const { toastId } = action\n\n      // ! Side effects ! - This could be extracted into a dismissToast() action,\n      // but I'll keep it here for simplicity\n      if (toastId) {\n        addToRemoveQueue(toastId)\n      } else {\n        state.toasts.forEach((toast) => {\n          addToRemoveQueue(toast.id)\n        })\n      }\n\n      return {\n        ...state,\n        toasts: state.toasts.map((t) =>\n          t.id === toastId || toastId === undefined\n            ? {\n                ...t,\n                open: false,\n              }\n            : t\n        ),\n      }\n    }\n    case 'REMOVE_TOAST':\n      if (action.toastId === undefined) {\n        return {\n          ...state,\n          toasts: [],\n        }\n      }\n      return {\n        ...state,\n        toasts: state.toasts.filter((t) => t.id !== action.toastId),\n      }\n  }\n}\n\nconst listeners: Array<(state: State) => void> = []\n\nlet memoryState: State = { toasts: [] }\n\nfunction dispatch(action: Action) {\n  memoryState = reducer(memoryState, action)\n  listeners.forEach((listener) => {\n    listener(memoryState)\n  })\n}\n\ntype Toast = Omit<ToasterToast, 'id'>\n\nfunction toast({ ...props }: Toast) {\n  const id = genId()\n\n  const update = (props: ToasterToast) =>\n    dispatch({\n      type: 'UPDATE_TOAST',\n      toast: { ...props, id },\n    })\n  const dismiss = () => dispatch({ type: 'DISMISS_TOAST', toastId: id })\n\n  dispatch({\n    type: 'ADD_TOAST',\n    toast: {\n      ...props,\n      id,\n      open: true,\n      onOpenChange: (open) => {\n        if (!open) dismiss()\n      },\n    },\n  })\n\n  return {\n    id: id,\n    dismiss,\n    update,\n  }\n}\n\nfunction useToast() {\n  const [state, setState] = React.useState<State>(memoryState)\n\n  React.useEffect(() => {\n    listeners.push(setState)\n    return () => {\n      const index = listeners.indexOf(setState)\n      if (index > -1) {\n        listeners.splice(index, 1)\n      }\n    }\n  }, [state])\n\n  return {\n    ...state,\n    toast,\n    dismiss: (toastId?: string) => dispatch({ type: 'DISMISS_TOAST', toastId }),\n  }\n}\n\nexport { toast, useToast }\n"
        },
        {
          "path": "registry/default/vue/use-toast.ts",
          "type": "registry:hook",
          "target": "components/ui/toast/use-toast.ts",
          "content": "import { computed, ref, type Component, type ComputedRef, type VNode } from 'vue'\n\nconst TOAST_LIMIT = 1\nconst TOAST_REMOVE_DELAY = 1000000\n\ntype ToasterToast = {\n  id: string\n  title?: string\n  description?: string | VNode | Component\n  action?: VNode | Component\n  variant?: 'default' | 'destructive'\n  open?: boolean\n  onOpenChange?: (open: boolean) => void\n}\n\nconst actionTypes = {\n  ADD_TOAST: 'ADD_TOAST',\n  UPDATE_TOAST: 'UPDATE_TOAST',\n  DISMISS_TOAST: 'DISMISS_TOAST',\n  REMOVE_TOAST: 'REMOVE_TOAST',\n} as const\n\nlet count = 0\n\nfunction genId() {\n  count = (count + 1) % Number.MAX_SAFE_INTEGER\n  return count.toString()\n}\n\ntype ActionType = typeof actionTypes\n\ntype Action =\n  | {\n      type: ActionType['ADD_TOAST']\n      toast: ToasterToast\n    }\n  | {\n      type: ActionType['UPDATE_TOAST']\n      toast: Partial<ToasterToast>\n    }\n  | {\n      type: ActionType['DISMISS_TOAST']\n      toastId?: ToasterToast['id']\n    }\n  | {\n      type: ActionType['REMOVE_TOAST']\n      toastId?: ToasterToast['id']\n    }\n\ninterface State {\n  toasts: ToasterToast[]\n}\n\nconst toastTimeouts = new Map<string, ReturnType<typeof setTimeout>>()\n\n// Helper to manage state\nconst state = ref<State>({\n  toasts: [],\n})\n\nfunction addToRemoveQueue(toastId: string) {\n  if (toastTimeouts.has(toastId)) {\n    return\n  }\n\n  const timeout = setTimeout(() => {\n    toastTimeouts.delete(toastId)\n    dispatch({\n      type: 'REMOVE_TOAST',\n      toastId: toastId,\n    })\n  }, TOAST_REMOVE_DELAY)\n\n  toastTimeouts.set(toastId, timeout)\n}\n\nfunction dispatch(action: Action) {\n  switch (action.type) {\n    case 'ADD_TOAST':\n      state.value.toasts = [action.toast, ...state.value.toasts].slice(0, TOAST_LIMIT)\n      break\n    case 'UPDATE_TOAST':\n      state.value.toasts = state.value.toasts.map((t) =>\n        t.id === action.toast.id ? { ...t, ...action.toast } : t\n      )\n      break\n    case 'DISMISS_TOAST': {\n      const { toastId } = action\n\n      // ! Side effects ! - This could be extracted into a dismissToast() action,\n      // but I'll keep it here for simplicity\n      if (toastId) {\n        addToRemoveQueue(toastId)\n      } else {\n        state.value.toasts.forEach((toast) => {\n          addToRemoveQueue(toast.id)\n        })\n      }\n\n      state.value.toasts = state.value.toasts.map((t) =>\n        t.id === toastId || toastId === undefined\n          ? {\n              ...t,\n              open: false,\n            }\n          : t\n      )\n      break\n    }\n    case 'REMOVE_TOAST':\n      if (action.toastId === undefined) {\n        state.value.toasts = []\n      } else {\n        state.value.toasts = state.value.toasts.filter((t) => t.id !== action.toastId)\n      }\n      break\n  }\n}\n\ntype UseToastReturn = {\n  toasts: ComputedRef<ToasterToast[]>\n  toast: typeof toast\n  dismiss: (toastId?: string) => void\n}\n\nfunction useToast(): UseToastReturn {\n  return {\n    toasts: computed(() => state.value.toasts),\n    toast,\n    dismiss: (toastId?: string) => dispatch({ type: 'DISMISS_TOAST', toastId }),\n  }\n}\n\nfunction toast(props: Omit<ToasterToast, 'id'>) {\n  const id = genId()\n\n  const update = (props: ToasterToast) =>\n    dispatch({\n      type: 'UPDATE_TOAST',\n      toast: { ...props, id },\n    })\n\n  const dismiss = () => dispatch({ type: 'DISMISS_TOAST', toastId: id })\n\n  dispatch({\n    type: 'ADD_TOAST',\n    toast: {\n      ...props,\n      id,\n      open: true,\n      onOpenChange: (open) => {\n        if (!open) dismiss()\n      },\n    },\n  })\n\n  return {\n    id: id,\n    dismiss,\n    update,\n  }\n}\n\nexport { useToast, toast }\n"
        }
      ],
      "meta": {
        "frameworks": [],
        "dependenciesByFramework": {},
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "utils",
      "type": "registry:lib",
      "description": "Utility functions",
      "dependencies": [
        "clsx",
        "tailwind-merge",
        "class-variance-authority"
      ],
      "files": [
        {
          "path": "lib/utils.ts",
          "content": "import { clsx, type ClassValue } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nimport { JsonValue, TimEvent } from './schema'\n\nexport type AssertNoExtraKeys<T, Expected> = [T] extends [Expected]\n  ? [Expected] extends [T]\n    ? T\n    : 'Error: Extra keys detected in Prop implementation'\n  : 'Error: Prop implementation is missing required keys'\n\nexport function createTimEvent<TDetail = Record<string, JsonValue>>(\n  type: string,\n  targetId: string,\n  detail: TDetail\n): TimEvent<TDetail> {\n  return {\n    type,\n    target: { id: targetId },\n    detail,\n    timestamp: Date.now(),\n  }\n}\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function formatDate(input: string | number): string {\n  const date = new Date(input)\n  return date.toLocaleDateString('en-US', {\n    month: 'long',\n    day: 'numeric',\n    year: 'numeric',\n  })\n}\n",
          "type": "registry:lib",
          "target": "lib/utils.ts"
        }
      ]
    },
    {
      "name": "input-01",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-01.tsx",
          "type": "registry:component",
          "target": "components/ui/input-01.tsx",
          "content": "import { useId } from 'react'\nimport { Input, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Simple input</Label>\n      <Input id={id} placeholder=\"Email\" type=\"email\" />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-01.vue",
          "target": "components/ui/input-01.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'input-01';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Simple input</Label><Input :id=\"id\" placeholder=\"Email\" type=\"email\" /></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-01.html",
          "target": "components/ui/input-01.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Simple input</Label><Input id=\"${id}\" placeholder=\"Email\" type=\"email\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-01.wxml",
          "target": "components/ui/input-01/input-01.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Simple input</label><input id=\"{{id}}\" placeholder=\"Email\" type=\"email\" /></view>\n</view>"
        },
        {
          "path": "registry/default/components/input/input-01.wxss",
          "target": "components/ui/input-01/input-01.wxss",
          "type": "registry:component",
          "content": "/* space-y-2 equivalent */\n.space-y-2 > view + view,\n.space-y-2 > input + input,\n.space-y-2 > label + input {\n  margin-top: 8px;\n}\n\n.label {\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n}\n\n.input {\n  display: flex;\n  height: 40px;\n  width: 100%;\n  border-radius: 6px;\n  border: 1px solid #e2e8f0;\n  background-color: transparent;\n  padding: 8px 12px;\n  font-size: 14px;\n}\n"
        },
        {
          "path": "registry/default/components/input/input-01.json",
          "target": "components/ui/input-01/input-01.json",
          "type": "registry:component",
          "content": "{\n    \"component\": true,\n    \"usingComponents\": {}\n}"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-01",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-01",
              "path": "registry/default/components/input/input-01.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-01",
              "path": "registry/default/components/input/input-01.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-01",
              "path": "registry/default/components/input/input-01.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-01",
              "path": "registry/default/components/input/input-01.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-02",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-02.tsx",
          "type": "registry:component",
          "target": "components/ui/input-02.tsx",
          "content": "import { useId } from 'react'\nimport { Input, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>\n        Required input <span className=\"text-destructive\">*</span>\n      </Label>\n      <Input id={id} placeholder=\"Email\" type=\"email\" required />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-02.vue",
          "target": "components/ui/input-02.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'input-02';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Required input <span class=\"text-destructive\">*</span></Label><Input :id=\"id\" placeholder=\"Email\" type=\"email\" required /></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-02.html",
          "target": "components/ui/input-02.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Required input <span class=\"text-destructive\">*</span></Label><Input id=\"${id}\" placeholder=\"Email\" type=\"email\" required /></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-02.wxml",
          "target": "components/ui/input-02/input-02.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Required input <text class=\"text-destructive\">*</text></label><input id=\"{{id}}\" placeholder=\"Email\" type=\"email\" required /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "required"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-02",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-02",
              "path": "registry/default/components/input/input-02.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-02",
              "path": "registry/default/components/input/input-02.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-02",
              "path": "registry/default/components/input/input-02.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-02",
              "path": "registry/default/components/input/input-02.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-03",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-03.tsx",
          "type": "registry:component",
          "target": "components/ui/input-03.tsx",
          "content": "import { useId } from 'react'\nimport { Input, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Input with helper text</Label>\n      <Input id={id} placeholder=\"Email\" type=\"email\" />\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        We won&lsquo;t share your email with anyone\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-03.vue",
          "target": "components/ui/input-03.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'input-03';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Input with helper text</Label><Input :id=\"id\" placeholder=\"Email\" type=\"email\" /><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">We won&lsquo;t share your email with anyone\n      </p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-03.html",
          "target": "components/ui/input-03.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Input with helper text</Label><Input id=\"${id}\" placeholder=\"Email\" type=\"email\" /><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">We won&lsquo;t share your email with anyone\n      </p></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-03.wxml",
          "target": "components/ui/input-03/input-03.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Input with helper text</label><input id=\"{{id}}\" placeholder=\"Email\" type=\"email\" /><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">We won&lsquo;t share your email with anyone\n      </text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "helper"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-03",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-03",
              "path": "registry/default/components/input/input-03.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-03",
              "path": "registry/default/components/input/input-03.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-03",
              "path": "registry/default/components/input/input-03.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-03",
              "path": "registry/default/components/input/input-03.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-04",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-04.tsx",
          "type": "registry:component",
          "target": "components/ui/input-04.tsx",
          "content": "import { useId } from 'react'\nimport { Input, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <div className=\"flex items-center justify-between gap-1\">\n        <Label htmlFor={id} className=\"leading-6\">\n          Input with hint\n        </Label>\n        <span className=\"text-muted-foreground text-sm\">Optional</span>\n      </div>\n      <Input id={id} placeholder=\"Email\" type=\"email\" />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-04.vue",
          "target": "components/ui/input-04.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'input-04';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><div class=\"flex items-center justify-between gap-1\"><Label :htmlFor=\"id\" class=\"leading-6\">Input with hint\n        </Label><span class=\"text-muted-foreground text-sm\">Optional</span></div><Input :id=\"id\" placeholder=\"Email\" type=\"email\" /></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-04.html",
          "target": "components/ui/input-04.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><div class=\"flex items-center justify-between gap-1\"><Label htmlfor=\"${id}\" class=\"leading-6\">Input with hint\n        </Label><span class=\"text-muted-foreground text-sm\">Optional</span></div><Input id=\"${id}\" placeholder=\"Email\" type=\"email\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-04.wxml",
          "target": "components/ui/input-04/input-04.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><view class=\"flex items-center justify-between gap-1\"><label htmlfor=\"{{id}}\" class=\"leading-6\">Input with hint\n        </label><text class=\"text-muted-foreground text-sm\">Optional</text></view><input id=\"{{id}}\" placeholder=\"Email\" type=\"email\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "hint"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-04",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-04",
              "path": "registry/default/components/input/input-04.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-04",
              "path": "registry/default/components/input/input-04.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-04",
              "path": "registry/default/components/input/input-04.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-04",
              "path": "registry/default/components/input/input-04.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-05",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-05.tsx",
          "type": "registry:component",
          "target": "components/ui/input-05.tsx",
          "content": "import { useId } from 'react'\nimport { Input, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <>\n      <div className=\"[--ring:var(--color-indigo-300)] *:not-first:mt-2 in-[.dark]:[--ring:var(--color-indigo-900)]\">\n        <Label htmlFor={id}>Input with colored border and ring</Label>\n        <Input id={id} placeholder=\"Email\" type=\"email\" />\n      </div>\n    </>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-05.vue",
          "target": "components/ui/input-05.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'input-05';\n\n</script>\n\n<template>\n  <div class=\"[--ring:var(--color-indigo-300)] *:not-first:mt-2 in-[.dark]:[--ring:var(--color-indigo-900)]\"><Label :htmlFor=\"id\">Input with colored border and ring</Label><Input :id=\"id\" placeholder=\"Email\" type=\"email\" /></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-05.html",
          "target": "components/ui/input-05.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"[--ring:var(--color-indigo-300)] *:not-first:mt-2 in-[.dark]:[--ring:var(--color-indigo-900)]\"><Label htmlfor=\"${id}\">Input with colored border and ring</Label><Input id=\"${id}\" placeholder=\"Email\" type=\"email\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-05.wxml",
          "target": "components/ui/input-05/input-05.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"[--ring:var(--color-indigo-300)] *:not-first:mt-2 in-[.dark]:[--ring:var(--color-indigo-900)]\"><label htmlfor=\"{{id}}\">Input with colored border and ring</label><input id=\"{{id}}\" placeholder=\"Email\" type=\"email\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-05",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-05",
              "path": "registry/default/components/input/input-05.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-05",
              "path": "registry/default/components/input/input-05.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-05",
              "path": "registry/default/components/input/input-05.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-05",
              "path": "registry/default/components/input/input-05.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-06",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-06.tsx",
          "type": "registry:component",
          "target": "components/ui/input-06.tsx",
          "content": "import { useId } from 'react'\nimport { Input, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Input with error</Label>\n      <Input\n        id={id}\n        className=\"peer\"\n        placeholder=\"Email\"\n        type=\"email\"\n        defaultValue=\"invalid@email.com\"\n        aria-invalid\n      />\n      <p\n        className=\"peer-aria-invalid:text-destructive mt-2 text-xs\"\n        role=\"alert\"\n        aria-live=\"polite\"\n      >\n        Email is invalid\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-06.vue",
          "target": "components/ui/input-06.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'input-06';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Input with error</Label><Input :id=\"id\" class=\"peer\" placeholder=\"Email\" type=\"email\" default-value=\"invalid@email.com\" aria-invalid /><p class=\"peer-aria-invalid:text-destructive mt-2 text-xs\" role=\"alert\" aria-live=\"polite\">Email is invalid\n      </p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-06.html",
          "target": "components/ui/input-06.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Input with error</Label><Input id=\"${id}\" class=\"peer\" placeholder=\"Email\" type=\"email\" default-value=\"invalid@email.com\" aria-invalid /><p class=\"peer-aria-invalid:text-destructive mt-2 text-xs\" role=\"alert\" aria-live=\"polite\">Email is invalid\n      </p></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-06.wxml",
          "target": "components/ui/input-06/input-06.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Input with error</label><input id=\"{{id}}\" class=\"peer\" placeholder=\"Email\" type=\"email\" default-value=\"invalid@email.com\" aria-invalid /><text class=\"peer-aria-invalid:text-destructive mt-2 text-xs\" role=\"alert\" aria-live=\"polite\">Email is invalid\n      </text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "error"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-06",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-06",
              "path": "registry/default/components/input/input-06.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-06",
              "path": "registry/default/components/input/input-06.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-06",
              "path": "registry/default/components/input/input-06.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-06",
              "path": "registry/default/components/input/input-06.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-07",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-07.tsx",
          "type": "registry:component",
          "target": "components/ui/input-07.tsx",
          "content": "import { useId } from 'react'\nimport { Input, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Input with gray background</Label>\n      <Input\n        id={id}\n        className=\"bg-muted border-transparent shadow-none\"\n        placeholder=\"Email\"\n        type=\"email\"\n      />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-07.vue",
          "target": "components/ui/input-07.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'input-07';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Input with gray background</Label><Input :id=\"id\" class=\"bg-muted border-transparent shadow-none\" placeholder=\"Email\" type=\"email\" /></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-07.html",
          "target": "components/ui/input-07.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Input with gray background</Label><Input id=\"${id}\" class=\"bg-muted border-transparent shadow-none\" placeholder=\"Email\" type=\"email\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-07.wxml",
          "target": "components/ui/input-07/input-07.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Input with gray background</label><input id=\"{{id}}\" class=\"bg-muted border-transparent shadow-none\" placeholder=\"Email\" type=\"email\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-07",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-07",
              "path": "registry/default/components/input/input-07.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-07",
              "path": "registry/default/components/input/input-07.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-07",
              "path": "registry/default/components/input/input-07.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-07",
              "path": "registry/default/components/input/input-07.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-08",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-08.tsx",
          "type": "registry:component",
          "target": "components/ui/input-08.tsx",
          "content": "import { useId } from 'react'\nimport { Input, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Disabled input</Label>\n      <Input id={id} placeholder=\"Email\" type=\"email\" disabled />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-08.vue",
          "target": "components/ui/input-08.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'input-08';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Disabled input</Label><Input :id=\"id\" placeholder=\"Email\" type=\"email\" disabled /></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-08.html",
          "target": "components/ui/input-08.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Disabled input</Label><Input id=\"${id}\" placeholder=\"Email\" type=\"email\" disabled /></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-08.wxml",
          "target": "components/ui/input-08/input-08.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Disabled input</label><input id=\"{{id}}\" placeholder=\"Email\" type=\"email\" disabled /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "disabled"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-08",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-08",
              "path": "registry/default/components/input/input-08.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-08",
              "path": "registry/default/components/input/input-08.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-08",
              "path": "registry/default/components/input/input-08.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-08",
              "path": "registry/default/components/input/input-08.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-09",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-09.tsx",
          "type": "registry:component",
          "target": "components/ui/input-09.tsx",
          "content": "import { useId } from 'react'\nimport { Input, Label } from '@timui/react'\nimport { AtSignIcon } from 'lucide-react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Input with start icon</Label>\n      <div className=\"relative\">\n        <Input id={id} className=\"peer ps-9\" placeholder=\"Email\" type=\"email\" />\n        <div className=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\">\n          <AtSignIcon size={16} aria-hidden=\"true\" />\n        </div>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-09.vue",
          "target": "components/ui/input-09.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { AtSignIcon } from 'lucide-vue-next';\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'input-09';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Input with start icon</Label><div class=\"relative\"><Input :id=\"id\" class=\"peer ps-9\" placeholder=\"Email\" type=\"email\" /><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\"><AtSignIcon :size=\"16\" aria-hidden=\"true\" /></div></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-09.html",
          "target": "components/ui/input-09.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Input with start icon</Label><div class=\"relative\"><Input id=\"${id}\" class=\"peer ps-9\" placeholder=\"Email\" type=\"email\" /><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\"><AtSignIcon size=\"${16}\" aria-hidden=\"true\" /></div></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-09.wxml",
          "target": "components/ui/input-09/input-09.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Input with start icon</label><view class=\"relative\"><input id=\"{{id}}\" class=\"peer ps-9\" placeholder=\"Email\" type=\"email\" /><view class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\"><atsignicon size=\"{{16}}\" aria-hidden=\"true\" /></view></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-09",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-09",
              "path": "registry/default/components/input/input-09.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-09",
              "path": "registry/default/components/input/input-09.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-09",
              "path": "registry/default/components/input/input-09.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-09",
              "path": "registry/default/components/input/input-09.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-10",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-10.tsx",
          "type": "registry:component",
          "target": "components/ui/input-10.tsx",
          "content": "import { useId } from 'react'\nimport { Input, Label } from '@timui/react'\nimport { MailIcon } from 'lucide-react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Input with end icon</Label>\n      <div className=\"relative\">\n        <Input id={id} className=\"peer pe-9\" placeholder=\"Email\" type=\"email\" />\n        <div className=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 peer-disabled:opacity-50\">\n          <MailIcon size={16} aria-hidden=\"true\" />\n        </div>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-10.vue",
          "target": "components/ui/input-10.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { MailIcon } from 'lucide-vue-next';\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'input-10';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Input with end icon</Label><div class=\"relative\"><Input :id=\"id\" class=\"peer pe-9\" placeholder=\"Email\" type=\"email\" /><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 peer-disabled:opacity-50\"><MailIcon :size=\"16\" aria-hidden=\"true\" /></div></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-10.html",
          "target": "components/ui/input-10.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Input with end icon</Label><div class=\"relative\"><Input id=\"${id}\" class=\"peer pe-9\" placeholder=\"Email\" type=\"email\" /><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 peer-disabled:opacity-50\"><MailIcon size=\"${16}\" aria-hidden=\"true\" /></div></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-10.wxml",
          "target": "components/ui/input-10/input-10.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Input with end icon</label><view class=\"relative\"><input id=\"{{id}}\" class=\"peer pe-9\" placeholder=\"Email\" type=\"email\" /><view class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 peer-disabled:opacity-50\"><mailicon size=\"{{16}}\" aria-hidden=\"true\" /></view></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-10",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-10",
              "path": "registry/default/components/input/input-10.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-10",
              "path": "registry/default/components/input/input-10.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-10",
              "path": "registry/default/components/input/input-10.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-10",
              "path": "registry/default/components/input/input-10.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-11",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-11.tsx",
          "type": "registry:component",
          "target": "components/ui/input-11.tsx",
          "content": "import { useId } from 'react'\nimport { Input, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Input with start inline add-on</Label>\n      <div className=\"relative\">\n        <Input id={id} className=\"peer ps-16\" placeholder=\"google.com\" type=\"text\" />\n        <span className=\"text-muted-foreground pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 text-sm peer-disabled:opacity-50\">\n          https://\n        </span>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-11.vue",
          "target": "components/ui/input-11.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'input-11';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Input with start inline add-on</Label><div class=\"relative\"><Input :id=\"id\" class=\"peer ps-16\" placeholder=\"google.com\" type=\"text\" /><span class=\"text-muted-foreground pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 text-sm peer-disabled:opacity-50\">https://\n        </span></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-11.html",
          "target": "components/ui/input-11.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Input with start inline add-on</Label><div class=\"relative\"><Input id=\"${id}\" class=\"peer ps-16\" placeholder=\"google.com\" type=\"text\" /><span class=\"text-muted-foreground pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 text-sm peer-disabled:opacity-50\">https://\n        </span></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-11.wxml",
          "target": "components/ui/input-11/input-11.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Input with start inline add-on</label><view class=\"relative\"><input id=\"{{id}}\" class=\"peer ps-16\" placeholder=\"google.com\" type=\"text\" /><text class=\"text-muted-foreground pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 text-sm peer-disabled:opacity-50\">https://\n        </text></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-11",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-11",
              "path": "registry/default/components/input/input-11.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-11",
              "path": "registry/default/components/input/input-11.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-11",
              "path": "registry/default/components/input/input-11.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-11",
              "path": "registry/default/components/input/input-11.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-12",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-12.tsx",
          "type": "registry:component",
          "target": "components/ui/input-12.tsx",
          "content": "import { useId } from 'react'\nimport { Input, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Input with end inline add-on</Label>\n      <div className=\"relative\">\n        <Input id={id} className=\"peer pe-12\" placeholder=\"google\" type=\"text\" />\n        <span className=\"text-muted-foreground pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 text-sm peer-disabled:opacity-50\">\n          .com\n        </span>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-12.vue",
          "target": "components/ui/input-12.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'input-12';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Input with end inline add-on</Label><div class=\"relative\"><Input :id=\"id\" class=\"peer pe-12\" placeholder=\"google\" type=\"text\" /><span class=\"text-muted-foreground pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 text-sm peer-disabled:opacity-50\">.com\n        </span></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-12.html",
          "target": "components/ui/input-12.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Input with end inline add-on</Label><div class=\"relative\"><Input id=\"${id}\" class=\"peer pe-12\" placeholder=\"google\" type=\"text\" /><span class=\"text-muted-foreground pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 text-sm peer-disabled:opacity-50\">.com\n        </span></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-12.wxml",
          "target": "components/ui/input-12/input-12.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Input with end inline add-on</label><view class=\"relative\"><input id=\"{{id}}\" class=\"peer pe-12\" placeholder=\"google\" type=\"text\" /><text class=\"text-muted-foreground pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 text-sm peer-disabled:opacity-50\">.com\n        </text></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-12",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-12",
              "path": "registry/default/components/input/input-12.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-12",
              "path": "registry/default/components/input/input-12.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-12",
              "path": "registry/default/components/input/input-12.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-12",
              "path": "registry/default/components/input/input-12.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-13",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-13.tsx",
          "type": "registry:component",
          "target": "components/ui/input-13.tsx",
          "content": "import { useId } from 'react'\nimport { Input, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Input with inline add-ons</Label>\n      <div className=\"relative\">\n        <Input id={id} className=\"peer ps-6 pe-12\" placeholder=\"0.00\" type=\"text\" />\n        <span className=\"text-muted-foreground pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 text-sm peer-disabled:opacity-50\">\n          €\n        </span>\n        <span className=\"text-muted-foreground pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 text-sm peer-disabled:opacity-50\">\n          EUR\n        </span>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-13.vue",
          "target": "components/ui/input-13.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'input-13';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Input with inline add-ons</Label><div class=\"relative\"><Input :id=\"id\" class=\"peer ps-6 pe-12\" placeholder=\"0.00\" type=\"text\" /><span class=\"text-muted-foreground pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 text-sm peer-disabled:opacity-50\">€\n        </span><span class=\"text-muted-foreground pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 text-sm peer-disabled:opacity-50\">EUR\n        </span></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-13.html",
          "target": "components/ui/input-13.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Input with inline add-ons</Label><div class=\"relative\"><Input id=\"${id}\" class=\"peer ps-6 pe-12\" placeholder=\"0.00\" type=\"text\" /><span class=\"text-muted-foreground pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 text-sm peer-disabled:opacity-50\">€\n        </span><span class=\"text-muted-foreground pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 text-sm peer-disabled:opacity-50\">EUR\n        </span></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-13.wxml",
          "target": "components/ui/input-13/input-13.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Input with inline add-ons</label><view class=\"relative\"><input id=\"{{id}}\" class=\"peer ps-6 pe-12\" placeholder=\"0.00\" type=\"text\" /><text class=\"text-muted-foreground pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 text-sm peer-disabled:opacity-50\">€\n        </text><text class=\"text-muted-foreground pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 text-sm peer-disabled:opacity-50\">EUR\n        </text></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-13",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-13",
              "path": "registry/default/components/input/input-13.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-13",
              "path": "registry/default/components/input/input-13.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-13",
              "path": "registry/default/components/input/input-13.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-13",
              "path": "registry/default/components/input/input-13.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-14",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-14.tsx",
          "type": "registry:component",
          "target": "components/ui/input-14.tsx",
          "content": "import { useId } from 'react'\nimport { Input, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Input with start add-on</Label>\n      <div className=\"flex rounded-md shadow-xs\">\n        <span className=\"border-input bg-background text-muted-foreground -z-10 inline-flex items-center rounded-s-md border px-3 text-sm\">\n          https://\n        </span>\n        <Input\n          id={id}\n          className=\"-ms-px rounded-s-none shadow-none\"\n          placeholder=\"google.com\"\n          type=\"text\"\n        />\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-14.vue",
          "target": "components/ui/input-14.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'input-14';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Input with start add-on</Label><div class=\"flex rounded-md shadow-xs\"><span class=\"border-input bg-background text-muted-foreground -z-10 inline-flex items-center rounded-s-md border px-3 text-sm\">https://\n        </span><Input :id=\"id\" class=\"-ms-px rounded-s-none shadow-none\" placeholder=\"google.com\" type=\"text\" /></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-14.html",
          "target": "components/ui/input-14.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Input with start add-on</Label><div class=\"flex rounded-md shadow-xs\"><span class=\"border-input bg-background text-muted-foreground -z-10 inline-flex items-center rounded-s-md border px-3 text-sm\">https://\n        </span><Input id=\"${id}\" class=\"-ms-px rounded-s-none shadow-none\" placeholder=\"google.com\" type=\"text\" /></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-14.wxml",
          "target": "components/ui/input-14/input-14.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Input with start add-on</label><view class=\"flex rounded-md shadow-xs\"><text class=\"border-input bg-background text-muted-foreground -z-10 inline-flex items-center rounded-s-md border px-3 text-sm\">https://\n        </text><input id=\"{{id}}\" class=\"-ms-px rounded-s-none shadow-none\" placeholder=\"google.com\" type=\"text\" /></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-14",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-14",
              "path": "registry/default/components/input/input-14.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-14",
              "path": "registry/default/components/input/input-14.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-14",
              "path": "registry/default/components/input/input-14.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-14",
              "path": "registry/default/components/input/input-14.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-15",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-15.tsx",
          "type": "registry:component",
          "target": "components/ui/input-15.tsx",
          "content": "import { useId } from 'react'\nimport { Input, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Input with end add-on</Label>\n      <div className=\"flex rounded-md shadow-xs\">\n        <Input\n          id={id}\n          className=\"-me-px rounded-e-none shadow-none\"\n          placeholder=\"google\"\n          type=\"text\"\n        />\n        <span className=\"border-input bg-background text-muted-foreground -z-10 inline-flex items-center rounded-e-md border px-3 text-sm\">\n          .com\n        </span>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-15.vue",
          "target": "components/ui/input-15.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'input-15';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Input with end add-on</Label><div class=\"flex rounded-md shadow-xs\"><Input :id=\"id\" class=\"-me-px rounded-e-none shadow-none\" placeholder=\"google\" type=\"text\" /><span class=\"border-input bg-background text-muted-foreground -z-10 inline-flex items-center rounded-e-md border px-3 text-sm\">.com\n        </span></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-15.html",
          "target": "components/ui/input-15.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Input with end add-on</Label><div class=\"flex rounded-md shadow-xs\"><Input id=\"${id}\" class=\"-me-px rounded-e-none shadow-none\" placeholder=\"google\" type=\"text\" /><span class=\"border-input bg-background text-muted-foreground -z-10 inline-flex items-center rounded-e-md border px-3 text-sm\">.com\n        </span></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-15.wxml",
          "target": "components/ui/input-15/input-15.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Input with end add-on</label><view class=\"flex rounded-md shadow-xs\"><input id=\"{{id}}\" class=\"-me-px rounded-e-none shadow-none\" placeholder=\"google\" type=\"text\" /><text class=\"border-input bg-background text-muted-foreground -z-10 inline-flex items-center rounded-e-md border px-3 text-sm\">.com\n        </text></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-15",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-15",
              "path": "registry/default/components/input/input-15.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-15",
              "path": "registry/default/components/input/input-15.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-15",
              "path": "registry/default/components/input/input-15.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-15",
              "path": "registry/default/components/input/input-15.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-16",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-16.tsx",
          "type": "registry:component",
          "target": "components/ui/input-16.tsx",
          "content": "import { useId } from 'react'\nimport { Input, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Input with inline start and end add-on</Label>\n      <div className=\"relative flex rounded-md shadow-xs\">\n        <span className=\"text-muted-foreground pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 text-sm\">\n          €\n        </span>\n        <Input\n          id={id}\n          className=\"-me-px rounded-e-none ps-6 shadow-none\"\n          placeholder=\"0.00\"\n          type=\"text\"\n        />\n        <span className=\"border-input bg-background text-muted-foreground -z-10 inline-flex items-center rounded-e-md border px-3 text-sm\">\n          EUR\n        </span>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-16.vue",
          "target": "components/ui/input-16.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'input-16';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Input with inline start and end add-on</Label><div class=\"relative flex rounded-md shadow-xs\"><span class=\"text-muted-foreground pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 text-sm\">€\n        </span><Input :id=\"id\" class=\"-me-px rounded-e-none ps-6 shadow-none\" placeholder=\"0.00\" type=\"text\" /><span class=\"border-input bg-background text-muted-foreground -z-10 inline-flex items-center rounded-e-md border px-3 text-sm\">EUR\n        </span></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-16.html",
          "target": "components/ui/input-16.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Input with inline start and end add-on</Label><div class=\"relative flex rounded-md shadow-xs\"><span class=\"text-muted-foreground pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 text-sm\">€\n        </span><Input id=\"${id}\" class=\"-me-px rounded-e-none ps-6 shadow-none\" placeholder=\"0.00\" type=\"text\" /><span class=\"border-input bg-background text-muted-foreground -z-10 inline-flex items-center rounded-e-md border px-3 text-sm\">EUR\n        </span></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-16.wxml",
          "target": "components/ui/input-16/input-16.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Input with inline start and end add-on</label><view class=\"relative flex rounded-md shadow-xs\"><text class=\"text-muted-foreground pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 text-sm\">€\n        </text><input id=\"{{id}}\" class=\"-me-px rounded-e-none ps-6 shadow-none\" placeholder=\"0.00\" type=\"text\" /><text class=\"border-input bg-background text-muted-foreground -z-10 inline-flex items-center rounded-e-md border px-3 text-sm\">EUR\n        </text></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-16",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-16",
              "path": "registry/default/components/input/input-16.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-16",
              "path": "registry/default/components/input/input-16.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-16",
              "path": "registry/default/components/input/input-16.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-16",
              "path": "registry/default/components/input/input-16.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-17",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/select-native.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-17.tsx",
          "type": "registry:component",
          "target": "components/ui/input-17.tsx",
          "content": "import { useId } from 'react'\nimport { Input, Label, SelectNative } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Input with start select</Label>\n      <div className=\"flex rounded-md shadow-xs\">\n        <SelectNative className=\"text-muted-foreground hover:text-foreground w-fit rounded-e-none shadow-none\">\n          <option value=\"https://\">https://</option>\n          <option value=\"http://\">http://</option>\n          <option value=\"ftp://\">ftp://</option>\n          <option value=\"sftp://\">sftp://</option>\n          <option value=\"ws://\">ws://</option>\n          <option value=\"wss://\">wss://</option>\n        </SelectNative>\n        <Input\n          id={id}\n          className=\"-ms-px rounded-s-none shadow-none focus-visible:z-10\"\n          placeholder=\"192.168.1.1\"\n          type=\"text\"\n        />\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-17.vue",
          "target": "components/ui/input-17.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\nimport { SelectNative } from '@timui/vue';\n\n\n\n\n\nconst id = 'input-17';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Input with start select</Label><div class=\"flex rounded-md shadow-xs\"><SelectNative class=\"text-muted-foreground hover:text-foreground w-fit rounded-e-none shadow-none\"><option value=\"https://\">https://</option><option value=\"http://\">http://</option><option value=\"ftp://\">ftp://</option><option value=\"sftp://\">sftp://</option><option value=\"ws://\">ws://</option><option value=\"wss://\">wss://</option></SelectNative><Input :id=\"id\" class=\"-ms-px rounded-s-none shadow-none focus-visible:z-10\" placeholder=\"192.168.1.1\" type=\"text\" /></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-17.html",
          "target": "components/ui/input-17.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Input with start select</Label><div class=\"flex rounded-md shadow-xs\"><SelectNative class=\"text-muted-foreground hover:text-foreground w-fit rounded-e-none shadow-none\"><option value=\"https://\">https://</option><option value=\"http://\">http://</option><option value=\"ftp://\">ftp://</option><option value=\"sftp://\">sftp://</option><option value=\"ws://\">ws://</option><option value=\"wss://\">wss://</option></SelectNative><Input id=\"${id}\" class=\"-ms-px rounded-s-none shadow-none focus-visible:z-10\" placeholder=\"192.168.1.1\" type=\"text\" /></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-17.wxml",
          "target": "components/ui/input-17/input-17.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Input with start select</label><view class=\"flex rounded-md shadow-xs\"><selectnative class=\"text-muted-foreground hover:text-foreground w-fit rounded-e-none shadow-none\"><option value=\"https://\">https://</option><option value=\"http://\">http://</option><option value=\"ftp://\">ftp://</option><option value=\"sftp://\">sftp://</option><option value=\"ws://\">ws://</option><option value=\"wss://\">wss://</option></selectnative><input id=\"{{id}}\" class=\"-ms-px rounded-s-none shadow-none focus-visible:z-10\" placeholder=\"192.168.1.1\" type=\"text\" /></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "select",
          "native select"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-17",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-17",
              "path": "registry/default/components/input/input-17.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-17",
              "path": "registry/default/components/input/input-17.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-17",
              "path": "registry/default/components/input/input-17.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-17",
              "path": "registry/default/components/input/input-17.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-18",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/select-native.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-18.tsx",
          "type": "registry:component",
          "target": "components/ui/input-18.tsx",
          "content": "import { useId } from 'react'\nimport { Input, Label, SelectNative } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Input with end select</Label>\n      <div className=\"flex rounded-md shadow-xs\">\n        <Input\n          id={id}\n          className=\"-me-px rounded-e-none shadow-none focus-visible:z-10\"\n          placeholder=\"google\"\n          type=\"text\"\n        />\n        <SelectNative className=\"text-muted-foreground hover:text-foreground w-fit rounded-s-none shadow-none\">\n          <option>.com</option>\n          <option>.org</option>\n          <option>.net</option>\n        </SelectNative>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-18.vue",
          "target": "components/ui/input-18.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\nimport { SelectNative } from '@timui/vue';\n\n\n\n\n\nconst id = 'input-18';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Input with end select</Label><div class=\"flex rounded-md shadow-xs\"><Input :id=\"id\" class=\"-me-px rounded-e-none shadow-none focus-visible:z-10\" placeholder=\"google\" type=\"text\" /><SelectNative class=\"text-muted-foreground hover:text-foreground w-fit rounded-s-none shadow-none\"><option>.com</option><option>.org</option><option>.net</option></SelectNative></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-18.html",
          "target": "components/ui/input-18.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Input with end select</Label><div class=\"flex rounded-md shadow-xs\"><Input id=\"${id}\" class=\"-me-px rounded-e-none shadow-none focus-visible:z-10\" placeholder=\"google\" type=\"text\" /><SelectNative class=\"text-muted-foreground hover:text-foreground w-fit rounded-s-none shadow-none\"><option>.com</option><option>.org</option><option>.net</option></SelectNative></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-18.wxml",
          "target": "components/ui/input-18/input-18.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Input with end select</label><view class=\"flex rounded-md shadow-xs\"><input id=\"{{id}}\" class=\"-me-px rounded-e-none shadow-none focus-visible:z-10\" placeholder=\"google\" type=\"text\" /><selectnative class=\"text-muted-foreground hover:text-foreground w-fit rounded-s-none shadow-none\"><option>.com</option><option>.org</option><option>.net</option></selectnative></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "select",
          "native select"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-18",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-18",
              "path": "registry/default/components/input/input-18.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-18",
              "path": "registry/default/components/input/input-18.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-18",
              "path": "registry/default/components/input/input-18.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-18",
              "path": "registry/default/components/input/input-18.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-19",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-19.tsx",
          "type": "registry:component",
          "target": "components/ui/input-19.tsx",
          "content": "import { useId } from 'react'\nimport { Input, Label } from '@timui/react'\nimport { SendIcon } from 'lucide-react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Input with end inline button</Label>\n      <div className=\"relative\">\n        <Input id={id} className=\"pe-9\" placeholder=\"Email\" type=\"email\" />\n        <button\n          className=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\"\n          aria-label=\"Subscribe\"\n        >\n          <SendIcon size={16} aria-hidden=\"true\" />\n        </button>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-19.vue",
          "target": "components/ui/input-19.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { SendIcon } from 'lucide-vue-next';\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'input-19';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Input with end inline button</Label><div class=\"relative\"><Input :id=\"id\" class=\"pe-9\" placeholder=\"Email\" type=\"email\" /><button class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\" aria-label=\"Subscribe\"><SendIcon :size=\"16\" aria-hidden=\"true\" /></button></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-19.html",
          "target": "components/ui/input-19.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Input with end inline button</Label><div class=\"relative\"><Input id=\"${id}\" class=\"pe-9\" placeholder=\"Email\" type=\"email\" /><button class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\" aria-label=\"Subscribe\"><SendIcon size=\"${16}\" aria-hidden=\"true\" /></button></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-19.wxml",
          "target": "components/ui/input-19/input-19.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Input with end inline button</label><view class=\"relative\"><input id=\"{{id}}\" class=\"pe-9\" placeholder=\"Email\" type=\"email\" /><button class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\" aria-label=\"Subscribe\"><sendicon size=\"{{16}}\" aria-hidden=\"true\" /></button></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "button"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-19",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-19",
              "path": "registry/default/components/input/input-19.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-19",
              "path": "registry/default/components/input/input-19.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-19",
              "path": "registry/default/components/input/input-19.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-19",
              "path": "registry/default/components/input/input-19.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-20",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-20.tsx",
          "type": "registry:component",
          "target": "components/ui/input-20.tsx",
          "content": "import { useId } from 'react'\nimport { Input, Label } from '@timui/react'\nimport { DownloadIcon } from 'lucide-react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Input with end icon button</Label>\n      <div className=\"flex rounded-md shadow-xs\">\n        <Input\n          id={id}\n          className=\"-me-px flex-1 rounded-e-none shadow-none focus-visible:z-10\"\n          placeholder=\"Email\"\n          type=\"email\"\n        />\n        <button\n          className=\"border-input bg-background text-muted-foreground/80 hover:bg-accent hover:text-accent-foreground focus-visible:border-ring focus-visible:ring-ring/50 inline-flex w-9 items-center justify-center rounded-e-md border text-sm transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\"\n          aria-label=\"Subscribe\"\n        >\n          <DownloadIcon size={16} aria-hidden=\"true\" />\n        </button>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-20.vue",
          "target": "components/ui/input-20.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { DownloadIcon } from 'lucide-vue-next';\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'input-20';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Input with end icon button</Label><div class=\"flex rounded-md shadow-xs\"><Input :id=\"id\" class=\"-me-px flex-1 rounded-e-none shadow-none focus-visible:z-10\" placeholder=\"Email\" type=\"email\" /><button class=\"border-input bg-background text-muted-foreground/80 hover:bg-accent hover:text-accent-foreground focus-visible:border-ring focus-visible:ring-ring/50 inline-flex w-9 items-center justify-center rounded-e-md border text-sm transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\" aria-label=\"Subscribe\"><DownloadIcon :size=\"16\" aria-hidden=\"true\" /></button></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-20.html",
          "target": "components/ui/input-20.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Input with end icon button</Label><div class=\"flex rounded-md shadow-xs\"><Input id=\"${id}\" class=\"-me-px flex-1 rounded-e-none shadow-none focus-visible:z-10\" placeholder=\"Email\" type=\"email\" /><button class=\"border-input bg-background text-muted-foreground/80 hover:bg-accent hover:text-accent-foreground focus-visible:border-ring focus-visible:ring-ring/50 inline-flex w-9 items-center justify-center rounded-e-md border text-sm transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\" aria-label=\"Subscribe\"><DownloadIcon size=\"${16}\" aria-hidden=\"true\" /></button></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-20.wxml",
          "target": "components/ui/input-20/input-20.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Input with end icon button</label><view class=\"flex rounded-md shadow-xs\"><input id=\"{{id}}\" class=\"-me-px flex-1 rounded-e-none shadow-none focus-visible:z-10\" placeholder=\"Email\" type=\"email\" /><button class=\"border-input bg-background text-muted-foreground/80 hover:bg-accent hover:text-accent-foreground focus-visible:border-ring focus-visible:ring-ring/50 inline-flex w-9 items-center justify-center rounded-e-md border text-sm transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\" aria-label=\"Subscribe\"><downloadicon size=\"{{16}}\" aria-hidden=\"true\" /></button></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "button"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-20",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-20",
              "path": "registry/default/components/input/input-20.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-20",
              "path": "registry/default/components/input/input-20.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-20",
              "path": "registry/default/components/input/input-20.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-20",
              "path": "registry/default/components/input/input-20.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-21",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-21.tsx",
          "type": "registry:component",
          "target": "components/ui/input-21.tsx",
          "content": "import { useId } from 'react'\nimport { Input, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Input with end button</Label>\n      <div className=\"flex rounded-md shadow-xs\">\n        <Input\n          id={id}\n          className=\"-me-px flex-1 rounded-e-none shadow-none focus-visible:z-10\"\n          placeholder=\"Email\"\n          type=\"email\"\n        />\n        <button className=\"border-input bg-background text-foreground hover:bg-accent hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 inline-flex items-center rounded-e-md border px-3 text-sm font-medium transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50\">\n          Send\n        </button>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-21.vue",
          "target": "components/ui/input-21.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'input-21';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Input with end button</Label><div class=\"flex rounded-md shadow-xs\"><Input :id=\"id\" class=\"-me-px flex-1 rounded-e-none shadow-none focus-visible:z-10\" placeholder=\"Email\" type=\"email\" /><button class=\"border-input bg-background text-foreground hover:bg-accent hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 inline-flex items-center rounded-e-md border px-3 text-sm font-medium transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50\">Send\n        </button></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-21.html",
          "target": "components/ui/input-21.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Input with end button</Label><div class=\"flex rounded-md shadow-xs\"><Input id=\"${id}\" class=\"-me-px flex-1 rounded-e-none shadow-none focus-visible:z-10\" placeholder=\"Email\" type=\"email\" /><button class=\"border-input bg-background text-foreground hover:bg-accent hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 inline-flex items-center rounded-e-md border px-3 text-sm font-medium transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50\">Send\n        </button></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-21.wxml",
          "target": "components/ui/input-21/input-21.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Input with end button</label><view class=\"flex rounded-md shadow-xs\"><input id=\"{{id}}\" class=\"-me-px flex-1 rounded-e-none shadow-none focus-visible:z-10\" placeholder=\"Email\" type=\"email\" /><button class=\"border-input bg-background text-foreground hover:bg-accent hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 inline-flex items-center rounded-e-md border px-3 text-sm font-medium transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50\">Send\n        </button></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "button"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-21",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-21",
              "path": "registry/default/components/input/input-21.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-21",
              "path": "registry/default/components/input/input-21.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-21",
              "path": "registry/default/components/input/input-21.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-21",
              "path": "registry/default/components/input/input-21.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-22",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-22.tsx",
          "type": "registry:component",
          "target": "components/ui/input-22.tsx",
          "content": "import { useId } from 'react'\nimport { Button, Input, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Input with button</Label>\n      <div className=\"flex gap-2\">\n        <Input id={id} className=\"flex-1\" placeholder=\"Email\" type=\"email\" />\n        <Button variant=\"outline\">Send</Button>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-22.vue",
          "target": "components/ui/input-22.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'input-22';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Input with button</Label><div class=\"flex gap-2\"><Input :id=\"id\" class=\"flex-1\" placeholder=\"Email\" type=\"email\" /><Button variant=\"outline\">Send</Button></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-22.html",
          "target": "components/ui/input-22.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Input with button</Label><div class=\"flex gap-2\"><Input id=\"${id}\" class=\"flex-1\" placeholder=\"Email\" type=\"email\" /><Button variant=\"outline\">Send</Button></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-22.wxml",
          "target": "components/ui/input-22/input-22.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Input with button</label><view class=\"flex gap-2\"><input id=\"{{id}}\" class=\"flex-1\" placeholder=\"Email\" type=\"email\" /><button variant=\"outline\">Send</button></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "button"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-22",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-22",
              "path": "registry/default/components/input/input-22.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-22",
              "path": "registry/default/components/input/input-22.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-22",
              "path": "registry/default/components/input/input-22.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-22",
              "path": "registry/default/components/input/input-22.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-23",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-23.tsx",
          "type": "registry:component",
          "target": "components/ui/input-23.tsx",
          "content": "'use client'\n\nimport { useId, useState } from 'react'\nimport { Input, Label } from '@timui/react'\nimport { EyeIcon, EyeOffIcon } from 'lucide-react'\n\nexport default function Component() {\n  const id = useId()\n  const [isVisible, setIsVisible] = useState<boolean>(false)\n\n  const toggleVisibility = () => setIsVisible((prevState) => !prevState)\n\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Show/hide password input</Label>\n      <div className=\"relative\">\n        <Input\n          id={id}\n          className=\"pe-9\"\n          placeholder=\"Password\"\n          type={isVisible ? 'text' : 'password'}\n        />\n        <button\n          className=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\"\n          type=\"button\"\n          onClick={toggleVisibility}\n          aria-label={isVisible ? 'Hide password' : 'Show password'}\n          aria-pressed={isVisible}\n          aria-controls=\"password\"\n        >\n          {isVisible ? (\n            <EyeOffIcon size={16} aria-hidden=\"true\" />\n          ) : (\n            <EyeIcon size={16} aria-hidden=\"true\" />\n          )}\n        </button>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-23.vue",
          "target": "components/ui/input-23.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { EyeIcon, EyeOffIcon } from 'lucide-vue-next';\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\nconst isVisible = ref<boolean>(false);\n\n\nconst id = 'input-23';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Show/hide password input</Label><div class=\"relative\"><Input :id=\"id\" class=\"pe-9\" placeholder=\"Password\" :type=\"isVisible ? 'text' : 'password'\" /><button class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\" type=\"button\" @click=\"toggleVisibility\" :aria-label=\"isVisible ? 'Hide password' : 'Show password'\" :aria-pressed=\"isVisible\" aria-controls=\"password\"><template v-if=\"isVisible\">\n<EyeOffIcon :size=\"16\" aria-hidden=\"true\" />\n</template>\n<template v-else>\n<EyeIcon :size=\"16\" aria-hidden=\"true\" />\n</template></button></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-23.html",
          "target": "components/ui/input-23.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Show/hide password input</Label><div class=\"relative\"><Input id=\"${id}\" class=\"pe-9\" placeholder=\"Password\" type=\"${isVisible ? 'text' : 'password'}\" /><button class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\" type=\"button\" on-click=\"${toggleVisibility}\" aria-label=\"${isVisible ? 'Hide password' : 'Show password'}\" aria-pressed=\"${isVisible}\" aria-controls=\"password\"><!-- if isVisible -->\n<EyeOffIcon size=\"${16}\" aria-hidden=\"true\" />\n<!-- else -->\n<EyeIcon size=\"${16}\" aria-hidden=\"true\" />\n<!-- endif --></button></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-23.wxml",
          "target": "components/ui/input-23/input-23.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Show/hide password input</label><view class=\"relative\"><input id=\"{{id}}\" class=\"pe-9\" placeholder=\"Password\" type=\"{{isVisible ? 'text' : 'password'}}\" /><button class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\" type=\"button\" bindtap=\"toggleVisibility\" aria-label=\"{{isVisible ? 'Hide password' : 'Show password'}}\" aria-pressed=\"{{isVisible}}\" aria-controls=\"password\"><block wx:if=\"{{isVisible}}\">\n<eyeofficon size=\"{{16}}\" aria-hidden=\"true\" />\n</block>\n<block wx:else>\n<eyeicon size=\"{{16}}\" aria-hidden=\"true\" />\n</block></button></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "button",
          "password"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-23",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-23",
              "path": "registry/default/components/input/input-23.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-23",
              "path": "registry/default/components/input/input-23.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-23",
              "path": "registry/default/components/input/input-23.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-23",
              "path": "registry/default/components/input/input-23.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-24",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-24.tsx",
          "type": "registry:component",
          "target": "components/ui/input-24.tsx",
          "content": "'use client'\n\nimport { useId, useRef, useState } from 'react'\nimport { Input, Label } from '@timui/react'\nimport { CircleXIcon } from 'lucide-react'\n\nexport default function Component() {\n  const id = useId()\n  const [inputValue, setInputValue] = useState('Click to clear')\n  const inputRef = useRef<HTMLInputElement>(null)\n\n  const handleClearInput = () => {\n    setInputValue('')\n    if (inputRef.current) {\n      inputRef.current.focus()\n    }\n  }\n\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Input with clear button</Label>\n      <div className=\"relative\">\n        <Input\n          id={id}\n          ref={inputRef}\n          className=\"pe-9\"\n          placeholder=\"Type something...\"\n          type=\"text\"\n          value={inputValue}\n          onChange={(e) => setInputValue(e.target.value)}\n        />\n        {inputValue && (\n          <button\n            className=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\"\n            aria-label=\"Clear input\"\n            onClick={handleClearInput}\n          >\n            <CircleXIcon size={16} aria-hidden=\"true\" />\n          </button>\n        )}\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-24.vue",
          "target": "components/ui/input-24.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { CircleXIcon } from 'lucide-vue-next';\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\nconst id = 'input-24';\nconst inputValue = ref('Click to clear');\n\nfunction handleClearInput() {\n  inputValue.value = '';\n}\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\">\n    <Label :htmlFor=\"id\">Input with clear button</Label>\n    <div class=\"relative\">\n      <Input\n        :id=\"id\"\n        class=\"pe-9\"\n        placeholder=\"Type something...\"\n        type=\"text\"\n        v-model=\"inputValue\"\n      />\n      <button\n        v-if=\"inputValue\"\n        class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\"\n        aria-label=\"Clear input\"\n        @click=\"handleClearInput\"\n      >\n        <CircleXIcon :size=\"16\" aria-hidden=\"true\" />\n      </button>\n    </div>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-24.html",
          "target": "components/ui/input-24.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Input with clear button</Label><div class=\"relative\"><Input id=\"${id}\" ref=\"${inputRef}\" class=\"pe-9\" placeholder=\"Type something...\" type=\"text\" value=\"${inputValue}\" onchange=\"${(e) => setInputValue(e.target.value)}\" /><!-- if inputValue -->\n<button class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\" aria-label=\"Clear input\" on-click=\"${handleClearInput}\"><CircleXIcon size=\"${16}\" aria-hidden=\"true\" /></button>\n<!-- endif --></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-24.wxml",
          "target": "components/ui/input-24/input-24.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Input with clear button</label><view class=\"relative\"><input id=\"{{id}}\" ref=\"{{inputRef}}\" class=\"pe-9\" placeholder=\"Type something...\" type=\"text\" value=\"{{inputValue}}\" onchange=\"{{(e) => setInputValue(e.target.value)}}\" /><button wx:if=\"{{inputValue}}\" class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\" aria-label=\"Clear input\" bindtap=\"handleClearInput\"><circlexicon size=\"{{16}}\" aria-hidden=\"true\" /></button></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "button"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-24",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-24",
              "path": "registry/default/components/input/input-24.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-24",
              "path": "registry/default/components/input/input-24.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-24",
              "path": "registry/default/components/input/input-24.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-24",
              "path": "registry/default/components/input/input-24.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-25",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-25.tsx",
          "type": "registry:component",
          "target": "components/ui/input-25.tsx",
          "content": "import { useId } from 'react'\nimport { Input, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Search input with &lt;kbd&gt;</Label>\n      <div className=\"relative\">\n        <Input id={id} className=\"pe-11\" placeholder=\"Search...\" type=\"search\" />\n        <div className=\"text-muted-foreground pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-2\">\n          <kbd className=\"text-muted-foreground/70 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">\n            ⌘K\n          </kbd>\n        </div>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-25.vue",
          "target": "components/ui/input-25.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'input-25';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Search input with &lt;kbd&gt;</Label><div class=\"relative\"><Input :id=\"id\" class=\"pe-11\" placeholder=\"Search...\" type=\"search\" /><div class=\"text-muted-foreground pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-2\"><kbd class=\"text-muted-foreground/70 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">⌘K\n          </kbd></div></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-25.html",
          "target": "components/ui/input-25.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Search input with &lt;kbd&gt;</Label><div class=\"relative\"><Input id=\"${id}\" class=\"pe-11\" placeholder=\"Search...\" type=\"search\" /><div class=\"text-muted-foreground pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-2\"><kbd class=\"text-muted-foreground/70 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">⌘K\n          </kbd></div></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-25.wxml",
          "target": "components/ui/input-25/input-25.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Search input with &lt;kbd&gt;</label><view class=\"relative\"><input id=\"{{id}}\" class=\"pe-11\" placeholder=\"Search...\" type=\"search\" /><view class=\"text-muted-foreground pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-2\"><kbd class=\"text-muted-foreground/70 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">⌘K\n          </kbd></view></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "search",
          "kbd"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-25",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-25",
              "path": "registry/default/components/input/input-25.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-25",
              "path": "registry/default/components/input/input-25.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-25",
              "path": "registry/default/components/input/input-25.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-25",
              "path": "registry/default/components/input/input-25.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-26",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-26.tsx",
          "type": "registry:component",
          "target": "components/ui/input-26.tsx",
          "content": "import { useId } from 'react'\nimport { Input, Label } from '@timui/react'\nimport { ArrowRightIcon, SearchIcon } from 'lucide-react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Search input with icon and button</Label>\n      <div className=\"relative\">\n        <Input id={id} className=\"peer ps-9 pe-9\" placeholder=\"Search...\" type=\"search\" />\n        <div className=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\">\n          <SearchIcon size={16} />\n        </div>\n        <button\n          className=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\"\n          aria-label=\"Submit search\"\n          type=\"submit\"\n        >\n          <ArrowRightIcon size={16} aria-hidden=\"true\" />\n        </button>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-26.vue",
          "target": "components/ui/input-26.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ArrowRightIcon, SearchIcon } from 'lucide-vue-next';\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'input-26';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Search input with icon and button</Label><div class=\"relative\"><Input :id=\"id\" class=\"peer ps-9 pe-9\" placeholder=\"Search...\" type=\"search\" /><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\"><SearchIcon :size=\"16\" /></div><button class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\" aria-label=\"Submit search\" type=\"submit\"><ArrowRightIcon :size=\"16\" aria-hidden=\"true\" /></button></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-26.html",
          "target": "components/ui/input-26.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Search input with icon and button</Label><div class=\"relative\"><Input id=\"${id}\" class=\"peer ps-9 pe-9\" placeholder=\"Search...\" type=\"search\" /><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\"><SearchIcon size=\"${16}\" /></div><button class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\" aria-label=\"Submit search\" type=\"submit\"><ArrowRightIcon size=\"${16}\" aria-hidden=\"true\" /></button></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-26.wxml",
          "target": "components/ui/input-26/input-26.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Search input with icon and button</label><view class=\"relative\"><input id=\"{{id}}\" class=\"peer ps-9 pe-9\" placeholder=\"Search...\" type=\"search\" /><view class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\"><searchicon size=\"{{16}}\" /></view><button class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\" aria-label=\"Submit search\" type=\"submit\"><arrowrighticon size=\"{{16}}\" aria-hidden=\"true\" /></button></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "button",
          "search"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-26",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-26",
              "path": "registry/default/components/input/input-26.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-26",
              "path": "registry/default/components/input/input-26.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-26",
              "path": "registry/default/components/input/input-26.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-26",
              "path": "registry/default/components/input/input-26.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-27",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-27.tsx",
          "type": "registry:component",
          "target": "components/ui/input-27.tsx",
          "content": "'use client'\n\nimport { useEffect, useId, useState } from 'react'\nimport { Input, Label } from '@timui/react'\nimport { LoaderCircleIcon, MicIcon, SearchIcon } from 'lucide-react'\n\nexport default function Component() {\n  const id = useId()\n  const [inputValue, setInputValue] = useState('')\n  const [isLoading, setIsLoading] = useState<boolean>(false)\n\n  useEffect(() => {\n    if (inputValue) {\n      setIsLoading(true)\n      const timer = setTimeout(() => {\n        setIsLoading(false)\n      }, 500)\n      return () => clearTimeout(timer)\n    }\n    setIsLoading(false)\n  }, [inputValue])\n\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Search input with loader</Label>\n      <div className=\"relative\">\n        <Input\n          id={id}\n          className=\"peer ps-9 pe-9\"\n          placeholder=\"Search...\"\n          type=\"search\"\n          value={inputValue}\n          onChange={(e) => setInputValue(e.target.value)}\n        />\n        <div className=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\">\n          {isLoading ? (\n            <LoaderCircleIcon\n              className=\"animate-spin\"\n              size={16}\n              role=\"status\"\n              aria-label=\"Loading...\"\n            />\n          ) : (\n            <SearchIcon size={16} aria-hidden=\"true\" />\n          )}\n        </div>\n        <button\n          className=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\"\n          aria-label=\"Press to speak\"\n          type=\"submit\"\n        >\n          <MicIcon size={16} aria-hidden=\"true\" />\n        </button>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-27.vue",
          "target": "components/ui/input-27.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { LoaderCircleIcon, MicIcon, SearchIcon } from 'lucide-vue-next';\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\nconst id = 'input-27';\nconst inputValue = ref('');\nconst isLoading = ref(false);\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\">\n    <Label :htmlFor=\"id\">Search input with loader</Label>\n    <div class=\"relative\">\n      <Input :id=\"id\" class=\"peer ps-9 pe-9\" placeholder=\"Search...\" type=\"search\" v-model=\"inputValue\" />\n      <div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\">\n        <template v-if=\"isLoading\">\n          <LoaderCircleIcon class=\"animate-spin\" :size=\"16\" role=\"status\" aria-label=\"Loading...\" />\n        </template>\n        <template v-else>\n          <SearchIcon :size=\"16\" aria-hidden=\"true\" />\n        </template>\n      </div>\n      <button class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\" aria-label=\"Press to speak\" type=\"submit\">\n        <MicIcon :size=\"16\" aria-hidden=\"true\" />\n      </button>\n    </div>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-27.html",
          "target": "components/ui/input-27.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Search input with loader</Label><div class=\"relative\"><Input id=\"${id}\" class=\"peer ps-9 pe-9\" placeholder=\"Search...\" type=\"search\" value=\"${inputValue}\" onchange=\"${(e) => setInputValue(e.target.value)}\" /><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\"><!-- if isLoading -->\n<LoaderCircleIcon class=\"animate-spin\" size=\"${16}\" role=\"status\" aria-label=\"Loading...\" />\n<!-- else -->\n<SearchIcon size=\"${16}\" aria-hidden=\"true\" />\n<!-- endif --></div><button class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\" aria-label=\"Press to speak\" type=\"submit\"><MicIcon size=\"${16}\" aria-hidden=\"true\" /></button></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-27.wxml",
          "target": "components/ui/input-27/input-27.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Search input with loader</label><view class=\"relative\"><input id=\"{{id}}\" class=\"peer ps-9 pe-9\" placeholder=\"Search...\" type=\"search\" value=\"{{inputValue}}\" onchange=\"{{(e) => setInputValue(e.target.value)}}\" /><view class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\"><block wx:if=\"{{isLoading}}\">\n<loadercircleicon class=\"animate-spin\" size=\"{{16}}\" role=\"status\" aria-label=\"Loading...\" />\n</block>\n<block wx:else>\n<searchicon size=\"{{16}}\" aria-hidden=\"true\" />\n</block></view><button class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\" aria-label=\"Press to speak\" type=\"submit\"><micicon size=\"{{16}}\" aria-hidden=\"true\" /></button></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "button",
          "search"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-27",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-27",
              "path": "registry/default/components/input/input-27.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-27",
              "path": "registry/default/components/input/input-27.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-27",
              "path": "registry/default/components/input/input-27.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-27",
              "path": "registry/default/components/input/input-27.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-28",
      "type": "registry:component",
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-28.tsx",
          "type": "registry:component",
          "target": "components/ui/input-28.tsx",
          "content": "'use client'\n\nimport { useId, useState } from 'react'\nimport { Button, Input, Label } from '@timui/react'\nimport { MinusIcon, PlusIcon } from 'lucide-react'\n\nexport default function Component() {\n  const id = useId()\n  const [value, setValue] = useState(2048)\n\n  const decrement = () => setValue((prev) => Math.max(0, prev - 1))\n  const increment = () => setValue((prev) => prev + 1)\n\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Number input with plus/minus buttons</Label>\n      <div className=\"border-input bg-background relative inline-flex h-9 w-full items-center overflow-hidden rounded-md border text-sm shadow-xs\">\n        <Button\n          type=\"button\"\n          size=\"icon\"\n          variant=\"ghost\"\n          className=\"h-full rounded-none border-r\"\n          onClick={decrement}\n          aria-label=\"Decrease value\"\n        >\n          <MinusIcon size={16} aria-hidden=\"true\" />\n        </Button>\n        <Input\n          id={id}\n          type=\"number\"\n          min={0}\n          value={String(value)}\n          onChange={(event) => {\n            const next = Number(event.target.value)\n            setValue(Number.isFinite(next) ? Math.max(0, next) : 0)\n          }}\n          className=\"h-full rounded-none border-0 text-center tabular-nums shadow-none\"\n        />\n        <Button\n          type=\"button\"\n          size=\"icon\"\n          variant=\"ghost\"\n          className=\"h-full rounded-none border-l\"\n          onClick={increment}\n          aria-label=\"Increase value\"\n        >\n          <PlusIcon size={16} aria-hidden=\"true\" />\n        </Button>\n      </div>\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Built with TimUI atomic components\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-28.vue",
          "target": "components/ui/input-28.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { MinusIcon, PlusIcon } from 'lucide-vue-next'\nimport { Button } from '@timui/vue'\nimport { Input } from '@timui/vue'\nimport { Label } from '@timui/vue'\n\nconst id = 'input-28'\nconst value = ref(2048)\n\nfunction decrement() {\n  value.value = Math.max(0, value.value - 1)\n}\n\nfunction increment() {\n  value.value += 1\n}\n\nfunction handleInput(event: Event) {\n  const target = event.target as HTMLInputElement\n  const next = Number(target.value)\n  value.value = Number.isFinite(next) ? Math.max(0, next) : 0\n}\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\">\n    <Label :htmlFor=\"id\">Number input with plus/minus buttons</Label>\n    <div class=\"border-input bg-background relative inline-flex h-9 w-full items-center overflow-hidden rounded-md border text-sm shadow-xs\">\n      <Button\n        type=\"button\"\n        size=\"icon\"\n        variant=\"ghost\"\n        class=\"h-full rounded-none border-r\"\n        aria-label=\"Decrease value\"\n        @click=\"decrement\"\n      >\n        <MinusIcon :size=\"16\" aria-hidden=\"true\" />\n      </Button>\n      <Input\n        :id=\"id\"\n        type=\"number\"\n        min=\"0\"\n        :value=\"String(value)\"\n        class=\"h-full rounded-none border-0 text-center tabular-nums shadow-none\"\n        @input=\"handleInput\"\n      />\n      <Button\n        type=\"button\"\n        size=\"icon\"\n        variant=\"ghost\"\n        class=\"h-full rounded-none border-l\"\n        aria-label=\"Increase value\"\n        @click=\"increment\"\n      >\n        <PlusIcon :size=\"16\" aria-hidden=\"true\" />\n      </Button>\n    </div>\n    <p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n      Built with TimUI atomic components\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-28.html",
          "target": "components/ui/input-28.html",
          "type": "registry:component",
          "content": "<template>\n  <NumberField default-value=\"${2048}\" minvalue=\"${0}\"><div class=\"*:not-first:mt-2\"><Label class=\"text-foreground text-sm font-medium\">Number input with plus/minus buttons\n        </Label><Group class=\"border-input data-focus-within:border-ring data-focus-within:ring-ring/50 data-focus-within:has-aria-invalid:ring-destructive/20 dark:data-focus-within:has-aria-invalid:ring-destructive/40 data-focus-within:has-aria-invalid:border-destructive relative inline-flex h-9 w-full items-center overflow-hidden rounded-md border text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none data-disabled:opacity-50 data-focus-within:ring-[3px]\"><Button slot=\"decrement\" class=\"border-input bg-background text-muted-foreground/80 hover:bg-accent hover:text-foreground -ms-px flex aspect-square h-[inherit] items-center justify-center rounded-s-md border text-sm transition-[color,box-shadow] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\"><MinusIcon size=\"${16}\" aria-hidden=\"true\" /></Button><Input class=\"bg-background text-foreground w-full grow px-3 py-2 text-center tabular-nums\" /><Button slot=\"increment\" class=\"border-input bg-background text-muted-foreground/80 hover:bg-accent hover:text-foreground -me-px flex aspect-square h-[inherit] items-center justify-center rounded-e-md border text-sm transition-[color,box-shadow] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\"><PlusIcon size=\"${16}\" aria-hidden=\"true\" /></Button></Group></div><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with${' '}<a class=\"hover:text-foreground underline\" href=\"https://react-spectrum.adobe.com/react-aria/DateField.html\" target=\"_blank\" rel=\"noopener nofollow\">React Aria\n        </a></p></NumberField>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-28.wxml",
          "target": "components/ui/input-28/input-28.wxml",
          "type": "registry:component",
          "content": "<view>\n  <numberfield default-value=\"{{2048}}\" minvalue=\"{{0}}\"><view class=\"*:not-first:mt-2\"><label class=\"text-foreground text-sm font-medium\">Number input with plus/minus buttons\n        </label><group class=\"border-input data-focus-within:border-ring data-focus-within:ring-ring/50 data-focus-within:has-aria-invalid:ring-destructive/20 dark:data-focus-within:has-aria-invalid:ring-destructive/40 data-focus-within:has-aria-invalid:border-destructive relative inline-flex h-9 w-full items-center overflow-hidden rounded-md border text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none data-disabled:opacity-50 data-focus-within:ring-[3px]\"><button slot=\"decrement\" class=\"border-input bg-background text-muted-foreground/80 hover:bg-accent hover:text-foreground -ms-px flex aspect-square h-[inherit] items-center justify-center rounded-s-md border text-sm transition-[color,box-shadow] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\"><minusicon size=\"{{16}}\" aria-hidden=\"true\" /></button><input class=\"bg-background text-foreground w-full grow px-3 py-2 text-center tabular-nums\" /><button slot=\"increment\" class=\"border-input bg-background text-muted-foreground/80 hover:bg-accent hover:text-foreground -me-px flex aspect-square h-[inherit] items-center justify-center rounded-e-md border text-sm transition-[color,box-shadow] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\"><plusicon size=\"{{16}}\" aria-hidden=\"true\" /></button></group></view><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://react-spectrum.adobe.com/react-aria/DateField.html\" target=\"_blank\" rel=\"noopener nofollow\">React Aria\n        </a></text></numberfield>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "button",
          "number",
          "react aria"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-28",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-28",
              "path": "registry/default/components/input/input-28.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-28",
              "path": "registry/default/components/input/input-28.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-28",
              "path": "registry/default/components/input/input-28.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-28",
              "path": "registry/default/components/input/input-28.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-29",
      "type": "registry:component",
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-29.tsx",
          "type": "registry:component",
          "target": "components/ui/input-29.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Button, Input, Label } from '@timui/react'\nimport { ChevronDownIcon, ChevronUpIcon } from 'lucide-react'\n\nconst formatter = new Intl.NumberFormat('en-US', {\n  style: 'currency',\n  currency: 'EUR',\n  currencySign: 'accounting',\n})\n\nexport default function Component() {\n  const [value, setValue] = useState(99)\n\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label>Number input with chevrons</Label>\n      <div className=\"border-input bg-background relative inline-flex h-9 w-full items-center overflow-hidden rounded-md border text-sm shadow-xs\">\n        <Input\n          value={formatter.format(value)}\n          readOnly\n          className=\"h-full rounded-none border-0 tabular-nums shadow-none\"\n        />\n        <div className=\"flex h-full flex-col border-l\">\n          <Button\n            type=\"button\"\n            size=\"icon\"\n            variant=\"ghost\"\n            className=\"h-1/2 w-8 rounded-none border-b\"\n            onClick={() => setValue((prev) => prev + 1)}\n            aria-label=\"Increase value\"\n          >\n            <ChevronUpIcon size={12} aria-hidden=\"true\" />\n          </Button>\n          <Button\n            type=\"button\"\n            size=\"icon\"\n            variant=\"ghost\"\n            className=\"h-1/2 w-8 rounded-none\"\n            onClick={() => setValue((prev) => prev - 1)}\n            aria-label=\"Decrease value\"\n          >\n            <ChevronDownIcon size={12} aria-hidden=\"true\" />\n          </Button>\n        </div>\n      </div>\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Built with TimUI atomic components\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-29.vue",
          "target": "components/ui/input-29.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport { ChevronDownIcon, ChevronUpIcon } from 'lucide-vue-next'\nimport { Button } from '@timui/vue'\nimport { Input } from '@timui/vue'\nimport { Label } from '@timui/vue'\n\nconst value = ref(99)\n\nconst formatter = new Intl.NumberFormat('en-US', {\n  style: 'currency',\n  currency: 'EUR',\n  currencySign: 'accounting',\n})\n\nconst displayValue = computed(() => formatter.format(value.value))\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\">\n    <Label>Number input with chevrons</Label>\n    <div class=\"border-input bg-background relative inline-flex h-9 w-full items-center overflow-hidden rounded-md border text-sm shadow-xs\">\n      <Input :value=\"displayValue\" readonly class=\"h-full rounded-none border-0 tabular-nums shadow-none\" />\n      <div class=\"flex h-full flex-col border-l\">\n        <Button\n          type=\"button\"\n          size=\"icon\"\n          variant=\"ghost\"\n          class=\"h-1/2 w-8 rounded-none border-b\"\n          aria-label=\"Increase value\"\n          @click=\"value += 1\"\n        >\n          <ChevronUpIcon :size=\"12\" aria-hidden=\"true\" />\n        </Button>\n        <Button\n          type=\"button\"\n          size=\"icon\"\n          variant=\"ghost\"\n          class=\"h-1/2 w-8 rounded-none\"\n          aria-label=\"Decrease value\"\n          @click=\"value -= 1\"\n        >\n          <ChevronDownIcon :size=\"12\" aria-hidden=\"true\" />\n        </Button>\n      </div>\n    </div>\n    <p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n      Built with TimUI atomic components\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-29.html",
          "target": "components/ui/input-29.html",
          "type": "registry:component",
          "content": "<template>\n  <NumberField default-value=\"${99}\" formatoptions=\"${{\n        style: 'currency',\n        currency: 'EUR',\n        currencySign: 'accounting',\n      }}\"><div class=\"*:not-first:mt-2\"><Label class=\"text-foreground text-sm font-medium\">Number input with chevrons</Label><Group class=\"border-input doutline-none data-focus-within:border-ring data-focus-within:ring-ring/50 data-focus-within:has-aria-invalid:ring-destructive/20 dark:data-focus-within:has-aria-invalid:ring-destructive/40 data-focus-within:has-aria-invalid:border-destructive relative inline-flex h-9 w-full items-center overflow-hidden rounded-md border text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] data-disabled:opacity-50 data-focus-within:ring-[3px]\"><Input class=\"bg-background text-foreground flex-1 px-3 py-2 tabular-nums\" /><div class=\"flex h-[calc(100%+2px)] flex-col\"><Button slot=\"increment\" class=\"border-input bg-background text-muted-foreground/80 hover:bg-accent hover:text-foreground -me-px flex h-1/2 w-6 flex-1 items-center justify-center border text-sm transition-[color,box-shadow] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\"><ChevronUpIcon size=\"${12}\" aria-hidden=\"true\" /></Button><Button slot=\"decrement\" class=\"border-input bg-background text-muted-foreground/80 hover:bg-accent hover:text-foreground -me-px -mt-px flex h-1/2 w-6 flex-1 items-center justify-center border text-sm transition-[color,box-shadow] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\"><ChevronDownIcon size=\"${12}\" aria-hidden=\"true\" /></Button></div></Group></div><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with${' '}<a class=\"hover:text-foreground underline\" href=\"https://react-spectrum.adobe.com/react-aria/DateField.html\" target=\"_blank\" rel=\"noopener nofollow\">React Aria\n        </a></p></NumberField>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-29.wxml",
          "target": "components/ui/input-29/input-29.wxml",
          "type": "registry:component",
          "content": "<view>\n  <numberfield default-value=\"{{99}}\" formatoptions=\"{{{\n        style: 'currency',\n        currency: 'EUR',\n        currencySign: 'accounting',\n      }}}\"><view class=\"*:not-first:mt-2\"><label class=\"text-foreground text-sm font-medium\">Number input with chevrons</label><group class=\"border-input doutline-none data-focus-within:border-ring data-focus-within:ring-ring/50 data-focus-within:has-aria-invalid:ring-destructive/20 dark:data-focus-within:has-aria-invalid:ring-destructive/40 data-focus-within:has-aria-invalid:border-destructive relative inline-flex h-9 w-full items-center overflow-hidden rounded-md border text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] data-disabled:opacity-50 data-focus-within:ring-[3px]\"><input class=\"bg-background text-foreground flex-1 px-3 py-2 tabular-nums\" /><view class=\"flex h-[calc(100%+2px)] flex-col\"><button slot=\"increment\" class=\"border-input bg-background text-muted-foreground/80 hover:bg-accent hover:text-foreground -me-px flex h-1/2 w-6 flex-1 items-center justify-center border text-sm transition-[color,box-shadow] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\"><chevronupicon size=\"{{12}}\" aria-hidden=\"true\" /></button><button slot=\"decrement\" class=\"border-input bg-background text-muted-foreground/80 hover:bg-accent hover:text-foreground -me-px -mt-px flex h-1/2 w-6 flex-1 items-center justify-center border text-sm transition-[color,box-shadow] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\"><chevrondownicon size=\"{{12}}\" aria-hidden=\"true\" /></button></view></group></view><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://react-spectrum.adobe.com/react-aria/DateField.html\" target=\"_blank\" rel=\"noopener nofollow\">React Aria\n        </a></text></numberfield>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "button",
          "number",
          "react aria"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-29",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-29",
              "path": "registry/default/components/input/input-29.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-29",
              "path": "registry/default/components/input/input-29.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-29",
              "path": "registry/default/components/input/input-29.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-29",
              "path": "registry/default/components/input/input-29.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-30",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-30.tsx",
          "type": "registry:component",
          "target": "components/ui/input-30.tsx",
          "content": "import { useId } from 'react'\nimport { Input, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>File input</Label>\n      <Input id={id} className=\"p-0 pe-3 file:me-3 file:border-0 file:border-e\" type=\"file\" />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-30.vue",
          "target": "components/ui/input-30.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'input-30';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">File input</Label><Input :id=\"id\" class=\"p-0 pe-3 file:me-3 file:border-0 file:border-e\" type=\"file\" /></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-30.html",
          "target": "components/ui/input-30.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">File input</Label><Input id=\"${id}\" class=\"p-0 pe-3 file:me-3 file:border-0 file:border-e\" type=\"file\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-30.wxml",
          "target": "components/ui/input-30/input-30.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">File input</label><input id=\"{{id}}\" class=\"p-0 pe-3 file:me-3 file:border-0 file:border-e\" type=\"file\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "file"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-30",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-30",
              "path": "registry/default/components/input/input-30.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-30",
              "path": "registry/default/components/input/input-30.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-30",
              "path": "registry/default/components/input/input-30.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-30",
              "path": "registry/default/components/input/input-30.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-31",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-31.tsx",
          "type": "registry:component",
          "target": "components/ui/input-31.tsx",
          "content": "import { useId } from 'react'\nimport { Input } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"group relative\">\n      <label\n        htmlFor={id}\n        className=\"bg-background text-foreground absolute start-1 top-0 z-10 block -translate-y-1/2 px-2 text-xs font-medium group-has-disabled:opacity-50\"\n      >\n        Input with overlapping label\n      </label>\n      <Input id={id} className=\"h-10\" placeholder=\"Email\" type=\"email\" />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-31.vue",
          "target": "components/ui/input-31.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Input } from '@timui/vue';\n\n\n\n\n\nconst id = 'input-31';\n\n</script>\n\n<template>\n  <div class=\"group relative\"><label :for=\"id\" class=\"bg-background text-foreground absolute start-1 top-0 z-10 block -translate-y-1/2 px-2 text-xs font-medium group-has-disabled:opacity-50\">Input with overlapping label\n      </label><Input :id=\"id\" class=\"h-10\" placeholder=\"Email\" type=\"email\" /></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-31.html",
          "target": "components/ui/input-31.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"group relative\"><label htmlfor=\"${id}\" class=\"bg-background text-foreground absolute start-1 top-0 z-10 block -translate-y-1/2 px-2 text-xs font-medium group-has-disabled:opacity-50\">Input with overlapping label\n      </label><Input id=\"${id}\" class=\"h-10\" placeholder=\"Email\" type=\"email\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-31.wxml",
          "target": "components/ui/input-31/input-31.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"group relative\"><label htmlfor=\"{{id}}\" class=\"bg-background text-foreground absolute start-1 top-0 z-10 block -translate-y-1/2 px-2 text-xs font-medium group-has-disabled:opacity-50\">Input with overlapping label\n      </label><input id=\"{{id}}\" class=\"h-10\" placeholder=\"Email\" type=\"email\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-31",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-31",
              "path": "registry/default/components/input/input-31.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-31",
              "path": "registry/default/components/input/input-31.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-31",
              "path": "registry/default/components/input/input-31.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-31",
              "path": "registry/default/components/input/input-31.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-32",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-32.tsx",
          "type": "registry:component",
          "target": "components/ui/input-32.tsx",
          "content": "import { useId } from 'react'\nimport { Input } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"group relative\">\n      <label\n        htmlFor={id}\n        className=\"origin-start text-muted-foreground/70 group-focus-within:text-foreground has-[+input:not(:placeholder-shown)]:text-foreground absolute top-1/2 block -translate-y-1/2 cursor-text px-1 text-sm transition-all group-focus-within:pointer-events-none group-focus-within:top-0 group-focus-within:cursor-default group-focus-within:text-xs group-focus-within:font-medium has-[+input:not(:placeholder-shown)]:pointer-events-none has-[+input:not(:placeholder-shown)]:top-0 has-[+input:not(:placeholder-shown)]:cursor-default has-[+input:not(:placeholder-shown)]:text-xs has-[+input:not(:placeholder-shown)]:font-medium\"\n      >\n        <span className=\"bg-background inline-flex px-2\">Input with label animation</span>\n      </label>\n      <Input id={id} type=\"email\" placeholder=\" \" />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-32.vue",
          "target": "components/ui/input-32.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Input } from '@timui/vue';\n\n\n\n\n\nconst id = 'input-32';\n\n</script>\n\n<template>\n  <div class=\"group relative\"><label :for=\"id\" class=\"origin-start text-muted-foreground/70 group-focus-within:text-foreground has-[+input:not(:placeholder-shown)]:text-foreground absolute top-1/2 block -translate-y-1/2 cursor-text px-1 text-sm transition-all group-focus-within:pointer-events-none group-focus-within:top-0 group-focus-within:cursor-default group-focus-within:text-xs group-focus-within:font-medium has-[+input:not(:placeholder-shown)]:pointer-events-none has-[+input:not(:placeholder-shown)]:top-0 has-[+input:not(:placeholder-shown)]:cursor-default has-[+input:not(:placeholder-shown)]:text-xs has-[+input:not(:placeholder-shown)]:font-medium\"><span class=\"bg-background inline-flex px-2\">Input with label animation</span></label><Input :id=\"id\" type=\"email\" placeholder=\" \" /></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-32.html",
          "target": "components/ui/input-32.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"group relative\"><label htmlfor=\"${id}\" class=\"origin-start text-muted-foreground/70 group-focus-within:text-foreground has-[+input:not(:placeholder-shown)]:text-foreground absolute top-1/2 block -translate-y-1/2 cursor-text px-1 text-sm transition-all group-focus-within:pointer-events-none group-focus-within:top-0 group-focus-within:cursor-default group-focus-within:text-xs group-focus-within:font-medium has-[+input:not(:placeholder-shown)]:pointer-events-none has-[+input:not(:placeholder-shown)]:top-0 has-[+input:not(:placeholder-shown)]:cursor-default has-[+input:not(:placeholder-shown)]:text-xs has-[+input:not(:placeholder-shown)]:font-medium\"><span class=\"bg-background inline-flex px-2\">Input with label animation</span></label><Input id=\"${id}\" type=\"email\" placeholder=\" \" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-32.wxml",
          "target": "components/ui/input-32/input-32.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"group relative\"><label htmlfor=\"{{id}}\" class=\"origin-start text-muted-foreground/70 group-focus-within:text-foreground has-[+input:not(:placeholder-shown)]:text-foreground absolute top-1/2 block -translate-y-1/2 cursor-text px-1 text-sm transition-all group-focus-within:pointer-events-none group-focus-within:top-0 group-focus-within:cursor-default group-focus-within:text-xs group-focus-within:font-medium has-[+input:not(:placeholder-shown)]:pointer-events-none has-[+input:not(:placeholder-shown)]:top-0 has-[+input:not(:placeholder-shown)]:cursor-default has-[+input:not(:placeholder-shown)]:text-xs has-[+input:not(:placeholder-shown)]:font-medium\"><text class=\"bg-background inline-flex px-2\">Input with label animation</text></label><input id=\"{{id}}\" type=\"email\" placeholder=\" \" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-32",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-32",
              "path": "registry/default/components/input/input-32.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-32",
              "path": "registry/default/components/input/input-32.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-32",
              "path": "registry/default/components/input/input-32.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-32",
              "path": "registry/default/components/input/input-32.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-33",
      "type": "registry:component",
      "files": [
        {
          "path": "registry/default/components/input/input-33.tsx",
          "type": "registry:component",
          "target": "components/ui/input-33.tsx",
          "content": "import { useId } from 'react'\nimport { Input, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n\n  return (\n    <div className=\"border-input bg-background focus-within:border-ring focus-within:ring-ring/50 relative rounded-md border shadow-xs transition-[color,box-shadow] outline-none focus-within:ring-[3px] has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50\">\n      <Label htmlFor={id} className=\"text-foreground block px-3 pt-2 text-xs font-medium\">\n        Input with inset label\n      </Label>\n      <Input\n        id={id}\n        className=\"h-10 rounded-none border-0 px-3 pb-2 shadow-none\"\n        placeholder=\"Email\"\n        type=\"email\"\n        disabled\n      />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-33.vue",
          "target": "components/ui/input-33.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Input } from '@timui/vue'\nimport { Label } from '@timui/vue'\n\nconst id = 'input-33'\n</script>\n\n<template>\n  <div class=\"border-input bg-background focus-within:border-ring focus-within:ring-ring/50 relative rounded-md border shadow-xs transition-[color,box-shadow] outline-none focus-within:ring-[3px] has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50\">\n    <Label :htmlFor=\"id\" class=\"text-foreground block px-3 pt-2 text-xs font-medium\">\n      Input with inset label\n    </Label>\n    <Input\n      :id=\"id\"\n      class=\"h-10 rounded-none border-0 px-3 pb-2 shadow-none\"\n      placeholder=\"Email\"\n      type=\"email\"\n      disabled\n    />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-33.html",
          "target": "components/ui/input-33.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"border-input bg-background focus-within:border-ring focus-within:ring-ring/50 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40 has-aria-invalid:border-destructive relative rounded-md border shadow-xs transition-[color,box-shadow] outline-none focus-within:ring-[3px] has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50 has-[input:is(:disabled)]:*:pointer-events-none\"><label htmlfor=\"${id}\" class=\"text-foreground block px-3 pt-2 text-xs font-medium\">Input with inset label\n      </label><input id=\"${id}\" class=\"text-foreground placeholder:text-muted-foreground/70 flex h-10 w-full bg-transparent px-3 pb-2 text-sm focus-visible:outline-none\" placeholder=\"Email\" type=\"email\" disabled /></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-33.wxml",
          "target": "components/ui/input-33/input-33.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"border-input bg-background focus-within:border-ring focus-within:ring-ring/50 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40 has-aria-invalid:border-destructive relative rounded-md border shadow-xs transition-[color,box-shadow] outline-none focus-within:ring-[3px] has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50 has-[input:is(:disabled)]:*:pointer-events-none\"><label htmlfor=\"{{id}}\" class=\"text-foreground block px-3 pt-2 text-xs font-medium\">Input with inset label\n      </label><input id=\"{{id}}\" class=\"text-foreground placeholder:text-muted-foreground/70 flex h-10 w-full bg-transparent px-3 pb-2 text-sm focus-visible:outline-none\" placeholder=\"Email\" type=\"email\" disabled /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-33",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-33",
              "path": "registry/default/components/input/input-33.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-33",
              "path": "registry/default/components/input/input-33.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-33",
              "path": "registry/default/components/input/input-33.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-33",
              "path": "registry/default/components/input/input-33.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-34",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-34.tsx",
          "type": "registry:component",
          "target": "components/ui/input-34.tsx",
          "content": "'use client'\n\nimport { useId } from 'react'\nimport { Input, Label } from '@timui/react'\n\nimport { useCharacterLimit } from '@/registry/default/hooks/use-character-limit'\n\nexport default function Component() {\n  const id = useId()\n  const maxLength = 50\n  const { value, characterCount, handleChange, maxLength: limit } = useCharacterLimit({ maxLength })\n\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Input with character limit</Label>\n      <div className=\"relative\">\n        <Input\n          id={id}\n          className=\"peer pe-14\"\n          type=\"text\"\n          value={value}\n          maxLength={maxLength}\n          onChange={handleChange}\n          aria-describedby={`${id}-description`}\n        />\n        <div\n          id={`${id}-description`}\n          className=\"text-muted-foreground pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 text-xs tabular-nums peer-disabled:opacity-50\"\n          aria-live=\"polite\"\n          role=\"status\"\n        >\n          {characterCount}/{limit}\n        </div>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/hooks/use-character-limit.ts",
          "type": "registry:hook",
          "target": "components/ui/input-34/use-character-limit.ts",
          "content": "'use client'\n\nimport { ChangeEvent, useState } from 'react'\n\ntype UseCharacterLimitProps = {\n  maxLength: number\n  initialValue?: string\n}\n\nexport function useCharacterLimit({ maxLength, initialValue = '' }: UseCharacterLimitProps) {\n  const [value, setValue] = useState(initialValue)\n  const [characterCount, setCharacterCount] = useState(initialValue.length)\n\n  const handleChange = (e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {\n    const newValue = e.target.value\n    if (newValue.length <= maxLength) {\n      setValue(newValue)\n      setCharacterCount(newValue.length)\n    }\n  }\n\n  return {\n    value,\n    characterCount,\n    handleChange,\n    maxLength,\n  }\n}\n"
        },
        {
          "path": "registry/default/components/input/input-34.vue",
          "target": "components/ui/input-34.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\nimport { useCharacterLimit } from '@/registry/default/hooks/use-character-limit-vue';\n\nconst id = 'input-34';\nconst maxLength = 50;\n\nconst { value, characterCount, maxLength: limit } = useCharacterLimit({ maxLength });\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\">\n    <Label :htmlFor=\"id\">Input with character limit</Label>\n    <div class=\"relative\">\n      <Input\n        :id=\"id\"\n        v-model=\"value\"\n        class=\"peer pe-14\"\n        type=\"text\"\n        :maxLength=\"maxLength\"\n        :aria-describedby=\"`${id}-description`\"\n      />\n      <div\n        :id=\"`${id}-description`\"\n        class=\"text-muted-foreground pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 text-xs tabular-nums peer-disabled:opacity-50\"\n        aria-live=\"polite\"\n        role=\"status\"\n      >\n        {{ characterCount }}/{{ limit }}\n      </div>\n    </div>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-34.html",
          "target": "components/ui/input-34.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Input with character limit</Label><div class=\"relative\"><Input id=\"${id}\" class=\"peer pe-14\" type=\"text\" value=\"${value}\" maxlength=\"${maxLength}\" onchange=\"${handleChange}\" aria-describedby=\"${`${id}-description`}\" /><div id=\"${`${id}-description`}\" class=\"text-muted-foreground pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 text-xs tabular-nums peer-disabled:opacity-50\" aria-live=\"polite\" role=\"status\">${characterCount}/${limit}</div></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-34.wxml",
          "target": "components/ui/input-34/input-34.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Input with character limit</label><view class=\"relative\"><input id=\"{{id}}\" class=\"peer pe-14\" type=\"text\" value=\"{{value}}\" maxlength=\"{{maxLength}}\" onchange=\"{{handleChange}}\" aria-describedby=\"{{`${id}-description`}}\" /><view id=\"{{`${id}-description`}}\" class=\"text-muted-foreground pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 text-xs tabular-nums peer-disabled:opacity-50\" aria-live=\"polite\" role=\"status\">{{ characterCount }}/{{ limit }}</view></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-34",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-34",
              "path": "registry/default/components/input/input-34.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-34",
              "path": "registry/default/components/input/input-34.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-34",
              "path": "registry/default/components/input/input-34.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-34",
              "path": "registry/default/components/input/input-34.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-35",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-35.tsx",
          "type": "registry:component",
          "target": "components/ui/input-35.tsx",
          "content": "'use client'\n\nimport { useId } from 'react'\nimport { Input, Label } from '@timui/react'\n\nimport { useCharacterLimit } from '@/registry/default/hooks/use-character-limit'\n\nexport default function Component() {\n  const id = useId()\n  const maxLength = 8\n  const { value, characterCount, handleChange, maxLength: limit } = useCharacterLimit({ maxLength })\n\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Input with characters left</Label>\n      <Input\n        id={id}\n        type=\"text\"\n        value={value}\n        maxLength={maxLength}\n        onChange={handleChange}\n        aria-describedby={`${id}-description`}\n      />\n      <p\n        id={`${id}-description`}\n        className=\"text-muted-foreground mt-2 text-xs\"\n        role=\"status\"\n        aria-live=\"polite\"\n      >\n        <span className=\"tabular-nums\">{limit - characterCount}</span> characters left\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/hooks/use-character-limit.ts",
          "type": "registry:hook",
          "target": "components/ui/input-35/use-character-limit.ts",
          "content": "'use client'\n\nimport { ChangeEvent, useState } from 'react'\n\ntype UseCharacterLimitProps = {\n  maxLength: number\n  initialValue?: string\n}\n\nexport function useCharacterLimit({ maxLength, initialValue = '' }: UseCharacterLimitProps) {\n  const [value, setValue] = useState(initialValue)\n  const [characterCount, setCharacterCount] = useState(initialValue.length)\n\n  const handleChange = (e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {\n    const newValue = e.target.value\n    if (newValue.length <= maxLength) {\n      setValue(newValue)\n      setCharacterCount(newValue.length)\n    }\n  }\n\n  return {\n    value,\n    characterCount,\n    handleChange,\n    maxLength,\n  }\n}\n"
        },
        {
          "path": "registry/default/components/input/input-35.vue",
          "target": "components/ui/input-35.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\nimport { useCharacterLimit } from '@/registry/default/hooks/use-character-limit-vue';\n\nconst id = 'input-35';\nconst maxLength = 8;\n\nconst { value, characterCount, maxLength: limit } = useCharacterLimit({ maxLength });\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\">\n    <Label :htmlFor=\"id\">Input with characters left</Label>\n    <Input\n      :id=\"id\"\n      v-model=\"value\"\n      type=\"text\"\n      :maxLength=\"maxLength\"\n      :aria-describedby=\"`${id}-description`\"\n    />\n    <p :id=\"`${id}-description`\" class=\"text-muted-foreground mt-2 text-xs\" role=\"status\" aria-live=\"polite\">\n      <span class=\"tabular-nums\">{{ limit - characterCount }}</span> characters left\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-35.html",
          "target": "components/ui/input-35.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Input with characters left</Label><Input id=\"${id}\" type=\"text\" value=\"${value}\" maxlength=\"${maxLength}\" onchange=\"${handleChange}\" aria-describedby=\"${`${id}-description`}\" /><p id=\"${`${id}-description`}\" class=\"text-muted-foreground mt-2 text-xs\" role=\"status\" aria-live=\"polite\"><span class=\"tabular-nums\">${limit - characterCount}</span>characters left\n      </p></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-35.wxml",
          "target": "components/ui/input-35/input-35.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Input with characters left</label><input id=\"{{id}}\" type=\"text\" value=\"{{value}}\" maxlength=\"{{maxLength}}\" onchange=\"{{handleChange}}\" aria-describedby=\"{{`${id}-description`}}\" /><text id=\"{{`${id}-description`}}\" class=\"text-muted-foreground mt-2 text-xs\" role=\"status\" aria-live=\"polite\"><text class=\"tabular-nums\">{{ limit - characterCount }}</text>characters left\n      </text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-35",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-35",
              "path": "registry/default/components/input/input-35.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-35",
              "path": "registry/default/components/input/input-35.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-35",
              "path": "registry/default/components/input/input-35.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-35",
              "path": "registry/default/components/input/input-35.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-36",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/datefield-rac.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-36.tsx",
          "type": "registry:component",
          "target": "components/ui/input-36.tsx",
          "content": "'use client'\n\nimport { DateField, DateInput, Label } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <DateField className=\"*:not-first:mt-2\">\n      <Label className=\"text-foreground text-sm font-medium\">Date input</Label>\n      <DateInput />\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Built with{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://react-spectrum.adobe.com/react-aria/DateField.html\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React Aria\n        </a>\n      </p>\n    </DateField>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-36.vue",
          "target": "components/ui/input-36.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { DateField } from '@timui/vue'\nimport { DateInput } from '@timui/vue'\nimport { Label } from '@timui/vue'\n</script>\n\n<template>\n  <DateField class=\"*:not-first:mt-2\">\n    <Label class=\"text-foreground text-sm font-medium\">Date input</Label>\n    <DateInput />\n    <p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n      Built with\n      <a\n        class=\"hover:text-foreground underline\"\n        href=\"https://react-spectrum.adobe.com/react-aria/DateField.html\"\n        target=\"_blank\"\n        rel=\"noopener nofollow\"\n      >\n        React Aria\n      </a>\n    </p>\n  </DateField>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-36.html",
          "target": "components/ui/input-36.html",
          "type": "registry:component",
          "content": "<template>\n  <DateField class=\"*:not-first:mt-2\"><Label class=\"text-foreground text-sm font-medium\">Date input</Label><DateInput /><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with${' '}<a class=\"hover:text-foreground underline\" href=\"https://react-spectrum.adobe.com/react-aria/DateField.html\" target=\"_blank\" rel=\"noopener nofollow\">React Aria\n        </a></p></DateField>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-36.wxml",
          "target": "components/ui/input-36/input-36.wxml",
          "type": "registry:component",
          "content": "<view>\n  <datefield class=\"*:not-first:mt-2\"><label class=\"text-foreground text-sm font-medium\">Date input</label><dateinput /><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://react-spectrum.adobe.com/react-aria/DateField.html\" target=\"_blank\" rel=\"noopener nofollow\">React Aria\n        </a></text></datefield>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "date",
          "react aria"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-36",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-36",
              "path": "registry/default/components/input/input-36.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-36",
              "path": "registry/default/components/input/input-36.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-36",
              "path": "registry/default/components/input/input-36.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-36",
              "path": "registry/default/components/input/input-36.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-37",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/datefield-rac.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-37.tsx",
          "type": "registry:component",
          "target": "components/ui/input-37.tsx",
          "content": "'use client'\n\nimport { DateInput, Label, TimeField } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <TimeField className=\"*:not-first:mt-2\">\n      <Label className=\"text-foreground text-sm font-medium\">Time input</Label>\n      <DateInput />\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Built with{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://react-spectrum.adobe.com/react-aria/DateField.html\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React Aria\n        </a>\n      </p>\n    </TimeField>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-37.vue",
          "target": "components/ui/input-37.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { DateInput } from '@timui/vue'\nimport { Label } from '@timui/vue'\nimport { TimeField } from '@timui/vue'\n</script>\n\n<template>\n  <TimeField class=\"*:not-first:mt-2\">\n    <Label class=\"text-foreground text-sm font-medium\">Time input</Label>\n    <DateInput />\n    <p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n      Built with\n      <a\n        class=\"hover:text-foreground underline\"\n        href=\"https://react-spectrum.adobe.com/react-aria/DateField.html\"\n        target=\"_blank\"\n        rel=\"noopener nofollow\"\n      >\n        React Aria\n      </a>\n    </p>\n  </TimeField>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-37.html",
          "target": "components/ui/input-37.html",
          "type": "registry:component",
          "content": "<template>\n  <TimeField class=\"*:not-first:mt-2\"><Label class=\"text-foreground text-sm font-medium\">Time input</Label><DateInput /><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with${' '}<a class=\"hover:text-foreground underline\" href=\"https://react-spectrum.adobe.com/react-aria/DateField.html\" target=\"_blank\" rel=\"noopener nofollow\">React Aria\n        </a></p></TimeField>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-37.wxml",
          "target": "components/ui/input-37/input-37.wxml",
          "type": "registry:component",
          "content": "<view>\n  <timefield class=\"*:not-first:mt-2\"><label class=\"text-foreground text-sm font-medium\">Time input</label><dateinput /><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://react-spectrum.adobe.com/react-aria/DateField.html\" target=\"_blank\" rel=\"noopener nofollow\">React Aria\n        </a></text></timefield>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "date",
          "react aria"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-37",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-37",
              "path": "registry/default/components/input/input-37.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-37",
              "path": "registry/default/components/input/input-37.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-37",
              "path": "registry/default/components/input/input-37.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-37",
              "path": "registry/default/components/input/input-37.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-38",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/datefield-rac.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-38.tsx",
          "type": "registry:component",
          "target": "components/ui/input-38.tsx",
          "content": "'use client'\n\nimport { DateInput, Label, TimeField } from '@timui/react'\nimport { ClockIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <TimeField className=\"*:not-first:mt-2\">\n      <Label className=\"text-foreground text-sm font-medium\">Time input with start icon</Label>\n      <div className=\"relative\">\n        <div className=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 z-10 flex items-center justify-center ps-3\">\n          <ClockIcon size={16} aria-hidden=\"true\" />\n        </div>\n        <DateInput className=\"ps-9\" />\n      </div>\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Built with{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://react-spectrum.adobe.com/react-aria/DateField.html\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React Aria\n        </a>\n      </p>\n    </TimeField>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-38.vue",
          "target": "components/ui/input-38.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ClockIcon } from 'lucide-vue-next'\nimport { DateInput } from '@timui/vue'\nimport { Label } from '@timui/vue'\nimport { TimeField } from '@timui/vue'\n</script>\n\n<template>\n  <TimeField class=\"*:not-first:mt-2\">\n    <Label class=\"text-foreground text-sm font-medium\">Time input with start icon</Label>\n    <div class=\"relative\">\n      <div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 z-10 flex items-center justify-center ps-3\">\n        <ClockIcon :size=\"16\" aria-hidden=\"true\" />\n      </div>\n      <DateInput class=\"ps-9\" />\n    </div>\n    <p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n      Built with\n      <a\n        class=\"hover:text-foreground underline\"\n        href=\"https://react-spectrum.adobe.com/react-aria/DateField.html\"\n        target=\"_blank\"\n        rel=\"noopener nofollow\"\n      >\n        React Aria\n      </a>\n    </p>\n  </TimeField>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-38.html",
          "target": "components/ui/input-38.html",
          "type": "registry:component",
          "content": "<template>\n  <TimeField class=\"*:not-first:mt-2\"><Label class=\"text-foreground text-sm font-medium\">Time input with start icon</Label><div class=\"relative\"><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 z-10 flex items-center justify-center ps-3\"><ClockIcon size=\"${16}\" aria-hidden=\"true\" /></div><DateInput class=\"ps-9\" /></div><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with${' '}<a class=\"hover:text-foreground underline\" href=\"https://react-spectrum.adobe.com/react-aria/DateField.html\" target=\"_blank\" rel=\"noopener nofollow\">React Aria\n        </a></p></TimeField>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-38.wxml",
          "target": "components/ui/input-38/input-38.wxml",
          "type": "registry:component",
          "content": "<view>\n  <timefield class=\"*:not-first:mt-2\"><label class=\"text-foreground text-sm font-medium\">Time input with start icon</label><view class=\"relative\"><view class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 z-10 flex items-center justify-center ps-3\"><clockicon size=\"{{16}}\" aria-hidden=\"true\" /></view><dateinput class=\"ps-9\" /></view><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://react-spectrum.adobe.com/react-aria/DateField.html\" target=\"_blank\" rel=\"noopener nofollow\">React Aria\n        </a></text></timefield>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "date",
          "react aria"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-38",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-38",
              "path": "registry/default/components/input/input-38.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-38",
              "path": "registry/default/components/input/input-38.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-38",
              "path": "registry/default/components/input/input-38.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-38",
              "path": "registry/default/components/input/input-38.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-39",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/datefield-rac.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-39.tsx",
          "type": "registry:component",
          "target": "components/ui/input-39.tsx",
          "content": "'use client'\n\nimport { DateInput, Label, TimeField } from '@timui/react'\nimport { ClockIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <TimeField className=\"*:not-first:mt-2\">\n      <Label className=\"text-foreground text-sm font-medium\">Time input with end icon</Label>\n      <div className=\"relative\">\n        <DateInput />\n        <div className=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 end-0 z-10 flex items-center justify-center pe-3\">\n          <ClockIcon size={16} aria-hidden=\"true\" />\n        </div>\n      </div>\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Built with{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://react-spectrum.adobe.com/react-aria/DateField.html\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React Aria\n        </a>\n      </p>\n    </TimeField>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-39.vue",
          "target": "components/ui/input-39.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ClockIcon } from 'lucide-vue-next'\nimport { DateInput } from '@timui/vue'\nimport { Label } from '@timui/vue'\nimport { TimeField } from '@timui/vue'\n</script>\n\n<template>\n  <TimeField class=\"*:not-first:mt-2\">\n    <Label class=\"text-foreground text-sm font-medium\">Time input with end icon</Label>\n    <div class=\"relative\">\n      <DateInput />\n      <div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 end-0 z-10 flex items-center justify-center pe-3\">\n        <ClockIcon :size=\"16\" aria-hidden=\"true\" />\n      </div>\n    </div>\n    <p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n      Built with\n      <a\n        class=\"hover:text-foreground underline\"\n        href=\"https://react-spectrum.adobe.com/react-aria/DateField.html\"\n        target=\"_blank\"\n        rel=\"noopener nofollow\"\n      >\n        React Aria\n      </a>\n    </p>\n  </TimeField>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-39.html",
          "target": "components/ui/input-39.html",
          "type": "registry:component",
          "content": "<template>\n  <TimeField class=\"*:not-first:mt-2\"><Label class=\"text-foreground text-sm font-medium\">Time input with end icon</Label><div class=\"relative\"><DateInput /><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 end-0 z-10 flex items-center justify-center pe-3\"><ClockIcon size=\"${16}\" aria-hidden=\"true\" /></div></div><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with${' '}<a class=\"hover:text-foreground underline\" href=\"https://react-spectrum.adobe.com/react-aria/DateField.html\" target=\"_blank\" rel=\"noopener nofollow\">React Aria\n        </a></p></TimeField>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-39.wxml",
          "target": "components/ui/input-39/input-39.wxml",
          "type": "registry:component",
          "content": "<view>\n  <timefield class=\"*:not-first:mt-2\"><label class=\"text-foreground text-sm font-medium\">Time input with end icon</label><view class=\"relative\"><dateinput /><view class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 end-0 z-10 flex items-center justify-center pe-3\"><clockicon size=\"{{16}}\" aria-hidden=\"true\" /></view></view><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://react-spectrum.adobe.com/react-aria/DateField.html\" target=\"_blank\" rel=\"noopener nofollow\">React Aria\n        </a></text></timefield>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "date",
          "react aria"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-39",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-39",
              "path": "registry/default/components/input/input-39.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-39",
              "path": "registry/default/components/input/input-39.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-39",
              "path": "registry/default/components/input/input-39.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-39",
              "path": "registry/default/components/input/input-39.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-40",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/datefield-rac.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-40.tsx",
          "type": "registry:component",
          "target": "components/ui/input-40.tsx",
          "content": "'use client'\n\nimport { DateField, DateInput, Label } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <DateField className=\"*:not-first:mt-2\" granularity=\"minute\" hourCycle={24}>\n      <Label className=\"text-foreground text-sm font-medium\">Date and time input</Label>\n      <DateInput />\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Built with{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://react-spectrum.adobe.com/react-aria/DateField.html\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React Aria\n        </a>\n      </p>\n    </DateField>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-40.vue",
          "target": "components/ui/input-40.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { DateField } from '@timui/vue'\nimport { DateInput } from '@timui/vue'\nimport { Label } from '@timui/vue'\n</script>\n\n<template>\n  <DateField class=\"*:not-first:mt-2\" granularity=\"minute\" :hourCycle=\"24\">\n    <Label class=\"text-foreground text-sm font-medium\">Date and time input</Label>\n    <DateInput />\n    <p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n      Built with\n      <a\n        class=\"hover:text-foreground underline\"\n        href=\"https://react-spectrum.adobe.com/react-aria/DateField.html\"\n        target=\"_blank\"\n        rel=\"noopener nofollow\"\n      >\n        React Aria\n      </a>\n    </p>\n  </DateField>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-40.html",
          "target": "components/ui/input-40.html",
          "type": "registry:component",
          "content": "<template>\n  <DateField class=\"*:not-first:mt-2\" granularity=\"minute\" hourcycle=\"${24}\"><Label class=\"text-foreground text-sm font-medium\">Date and time input</Label><DateInput /><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with${' '}<a class=\"hover:text-foreground underline\" href=\"https://react-spectrum.adobe.com/react-aria/DateField.html\" target=\"_blank\" rel=\"noopener nofollow\">React Aria\n        </a></p></DateField>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-40.wxml",
          "target": "components/ui/input-40/input-40.wxml",
          "type": "registry:component",
          "content": "<view>\n  <datefield class=\"*:not-first:mt-2\" granularity=\"minute\" hourcycle=\"{{24}}\"><label class=\"text-foreground text-sm font-medium\">Date and time input</label><dateinput /><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://react-spectrum.adobe.com/react-aria/DateField.html\" target=\"_blank\" rel=\"noopener nofollow\">React Aria\n        </a></text></datefield>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "date",
          "react aria"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-40",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-40",
              "path": "registry/default/components/input/input-40.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-40",
              "path": "registry/default/components/input/input-40.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-40",
              "path": "registry/default/components/input/input-40.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-40",
              "path": "registry/default/components/input/input-40.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "calendar-date-picker-25",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/calendar-rac.json",
        "https://ui.timkit.cn/r/datefield-rac.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-25.tsx",
          "type": "registry:component",
          "target": "components/ui/calendar-date-picker-25.tsx",
          "content": "'use client'\n\nimport { DatePicker, Label } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label className=\"text-foreground text-sm font-medium\">Date picker</Label>\n      <DatePicker />\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Built with TimUI atomic components + core Zag machine\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-25.vue",
          "target": "components/ui/calendar-date-picker-25.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { DatePicker } from '@timui/vue'\nimport { Label } from '@timui/vue'\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\">\n    <Label class=\"text-foreground text-sm font-medium\">Date picker</Label>\n    <DatePicker />\n\n    <p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n      Built with\n      <a\n        class=\"hover:text-foreground underline\"\n        href=\"https://react-spectrum.adobe.com/react-aria/DatePicker.html\"\n        target=\"_blank\"\n        rel=\"noopener nofollow\"\n      >\n        React Aria\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-25.html",
          "target": "components/ui/calendar-date-picker-25.html",
          "type": "registry:component",
          "content": "<template>\n  <DatePicker class=\"*:not-first:mt-2\"><Label class=\"text-foreground text-sm font-medium\">Date picker</Label><div class=\"flex\"><Group class=\"w-full\"><DateInput class=\"pe-9\" /></Group><Button class=\"text-muted-foreground/80 hover:text-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 z-10 -ms-9 -me-px flex w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none data-focus-visible:ring-[3px]\"><CalendarIcon size=\"${16}\" /></Button></div><Popover class=\"bg-background text-popover-foreground data-entering:animate-in data-exiting:animate-out data-[entering]:fade-in-0 data-[exiting]:fade-out-0 data-[entering]:zoom-in-95 data-[exiting]:zoom-out-95 data-[placement=bottom]:slide-in-from-top-2 data-[placement=left]:slide-in-from-right-2 data-[placement=right]:slide-in-from-left-2 data-[placement=top]:slide-in-from-bottom-2 z-50 rounded-lg border shadow-lg outline-hidden\" offset=\"${4}\"><Dialog class=\"max-h-[inherit] overflow-auto p-2\"><CalendarRAC /></Dialog></Popover><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with${' '}<a class=\"hover:text-foreground underline\" href=\"https://react-spectrum.adobe.com/react-aria/DatePicker.html\" target=\"_blank\" rel=\"noopener nofollow\">React Aria\n        </a></p></DatePicker>\n</template>"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-25.wxml",
          "target": "components/ui/calendar-date-picker-25/calendar-date-picker-25.wxml",
          "type": "registry:component",
          "content": "<view>\n  <datepicker class=\"*:not-first:mt-2\"><label class=\"text-foreground text-sm font-medium\">Date picker</label><view class=\"flex\"><group class=\"w-full\"><dateinput class=\"pe-9\" /></group><button class=\"text-muted-foreground/80 hover:text-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 z-10 -ms-9 -me-px flex w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none data-focus-visible:ring-[3px]\"><calendaricon size=\"{{16}}\" /></button></view><popover class=\"bg-background text-popover-foreground data-entering:animate-in data-exiting:animate-out data-[entering]:fade-in-0 data-[exiting]:fade-out-0 data-[entering]:zoom-in-95 data-[exiting]:zoom-out-95 data-[placement=bottom]:slide-in-from-top-2 data-[placement=left]:slide-in-from-right-2 data-[placement=right]:slide-in-from-left-2 data-[placement=top]:slide-in-from-bottom-2 z-50 rounded-lg border shadow-lg outline-hidden\" offset=\"{{4}}\"><dialog class=\"max-h-[inherit] overflow-auto p-2\"><calendarrac /></dialog></popover><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://react-spectrum.adobe.com/react-aria/DatePicker.html\" target=\"_blank\" rel=\"noopener nofollow\">React Aria\n        </a></text></datepicker>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "date",
          "calendar",
          "picker",
          "react aria"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "calendar-date-picker-25",
          "group": "calendar-date-picker",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-25",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-25.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-25",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-25.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-25",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-25.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-25",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-25.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "date-picker",
        "title": "Calendar Date Picker · Date picker"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "date-picker",
        "input"
      ]
    },
    {
      "name": "calendar-date-picker-26",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/calendar-rac.json",
        "https://ui.timkit.cn/r/datefield-rac.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-26.tsx",
          "type": "registry:component",
          "target": "components/ui/calendar-date-picker-26.tsx",
          "content": "'use client'\n\nimport { DatePicker, Label } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label className=\"text-foreground text-sm font-medium\">Date range picker</Label>\n      <DatePicker mode=\"range\" />\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Built with TimUI atomic components + core Zag machine\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-26.vue",
          "target": "components/ui/calendar-date-picker-26.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn } from '@timui/core'\nimport { CalendarIcon } from 'lucide-vue-next'\nimport { DateInput } from '@timui/vue'\nimport { DateRangePicker } from '@timui/vue'\nimport { DateRangePickerContent } from '@timui/vue'\nimport { DateRangePickerTrigger } from '@timui/vue'\nimport { Group } from '@timui/vue'\nimport { Label } from '@timui/vue'\nimport { RangeCalendar } from '@timui/vue'\n\nconst dateInputStyle =\n  'relative inline-flex h-9 w-full items-center overflow-hidden whitespace-nowrap rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none data-focus-within:border-ring data-focus-within:ring-ring/50 data-focus-within:ring-[3px] data-focus-within:has-aria-invalid:ring-destructive/20 dark:data-focus-within:has-aria-invalid:ring-destructive/40 data-focus-within:has-aria-invalid:border-destructive'\n</script>\n\n<template>\n  <DateRangePicker class=\"*:not-first:mt-2\">\n    <Label class=\"text-foreground text-sm font-medium\">Date range picker</Label>\n\n    <div class=\"flex\">\n      <Group :class=\"cn(dateInputStyle, 'pe-9')\">\n        <DateInput data-slot=\"start\" unstyled />\n        <span aria-hidden=\"true\" class=\"text-muted-foreground/70 px-2\">-</span>\n        <DateInput data-slot=\"end\" unstyled />\n      </Group>\n\n      <DateRangePickerTrigger\n        class=\"text-muted-foreground/80 hover:text-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 z-10 -ms-9 -me-px flex w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none data-focus-visible:ring-[3px]\"\n      >\n        <CalendarIcon :size=\"16\" />\n      </DateRangePickerTrigger>\n    </div>\n\n    <DateRangePickerContent\n      class=\"bg-background text-popover-foreground data-entering:animate-in data-exiting:animate-out data-[entering]:fade-in-0 data-[exiting]:fade-out-0 data-[entering]:zoom-in-95 data-[exiting]:zoom-out-95 data-[placement=bottom]:slide-in-from-top-2 data-[placement=left]:slide-in-from-right-2 data-[placement=right]:slide-in-from-left-2 data-[placement=top]:slide-in-from-bottom-2 z-50 rounded-md border shadow-lg outline-hidden\"\n    >\n      <div class=\"max-h-[inherit] overflow-auto p-2\">\n        <RangeCalendar />\n      </div>\n    </DateRangePickerContent>\n\n    <p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n      Built with\n      <a\n        class=\"hover:text-foreground underline\"\n        href=\"https://react-spectrum.adobe.com/react-aria/DateRangePicker.html\"\n        target=\"_blank\"\n        rel=\"noopener nofollow\"\n      >\n        React Aria\n      </a>\n    </p>\n  </DateRangePicker>\n</template>\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-26.html",
          "target": "components/ui/calendar-date-picker-26.html",
          "type": "registry:component",
          "content": "<template>\n  <DateRangePicker class=\"*:not-first:mt-2\"><Label class=\"text-foreground text-sm font-medium\">Date range picker</Label><div class=\"flex\"><Group class=\"${cn(dateInputStyle, 'pe-9')}\"><DateInput slot=\"start\" unstyled /><span aria-hidden=\"true\" class=\"text-muted-foreground/70 px-2\">-\n          </span><DateInput slot=\"end\" unstyled /></Group><Button class=\"text-muted-foreground/80 hover:text-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 z-10 -ms-9 -me-px flex w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none data-focus-visible:ring-[3px]\"><CalendarIcon size=\"${16}\" /></Button></div><Popover class=\"bg-background text-popover-foreground data-entering:animate-in data-exiting:animate-out data-[entering]:fade-in-0 data-[exiting]:fade-out-0 data-[entering]:zoom-in-95 data-[exiting]:zoom-out-95 data-[placement=bottom]:slide-in-from-top-2 data-[placement=left]:slide-in-from-right-2 data-[placement=right]:slide-in-from-left-2 data-[placement=top]:slide-in-from-bottom-2 z-50 rounded-md border shadow-lg outline-hidden\" offset=\"${4}\"><Dialog class=\"max-h-[inherit] overflow-auto p-2\"><RangeCalendar /></Dialog></Popover><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with${' '}<a class=\"hover:text-foreground underline\" href=\"https://react-spectrum.adobe.com/react-aria/DateRangePicker.html\" target=\"_blank\" rel=\"noopener nofollow\">React Aria\n        </a></p></DateRangePicker>\n</template>"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-26.wxml",
          "target": "components/ui/calendar-date-picker-26/calendar-date-picker-26.wxml",
          "type": "registry:component",
          "content": "<view>\n  <daterangepicker class=\"*:not-first:mt-2\"><label class=\"text-foreground text-sm font-medium\">Date range picker</label><view class=\"flex\"><group class=\"{{cn(dateInputStyle, 'pe-9')}}\"><dateinput slot=\"start\" unstyled /><text aria-hidden=\"true\" class=\"text-muted-foreground/70 px-2\">-\n          </text><dateinput slot=\"end\" unstyled /></group><button class=\"text-muted-foreground/80 hover:text-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 z-10 -ms-9 -me-px flex w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none data-focus-visible:ring-[3px]\"><calendaricon size=\"{{16}}\" /></button></view><popover class=\"bg-background text-popover-foreground data-entering:animate-in data-exiting:animate-out data-[entering]:fade-in-0 data-[exiting]:fade-out-0 data-[entering]:zoom-in-95 data-[exiting]:zoom-out-95 data-[placement=bottom]:slide-in-from-top-2 data-[placement=left]:slide-in-from-right-2 data-[placement=right]:slide-in-from-left-2 data-[placement=top]:slide-in-from-bottom-2 z-50 rounded-md border shadow-lg outline-hidden\" offset=\"{{4}}\"><dialog class=\"max-h-[inherit] overflow-auto p-2\"><rangecalendar /></dialog></popover><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://react-spectrum.adobe.com/react-aria/DateRangePicker.html\" target=\"_blank\" rel=\"noopener nofollow\">React Aria\n        </a></text></daterangepicker>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "date",
          "calendar",
          "range calendar",
          "picker",
          "react aria"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "calendar-date-picker-26",
          "group": "calendar-date-picker",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-26",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-26.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-26",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-26.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-26",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-26.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-26",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-26.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "date-picker",
        "title": "Calendar Date Picker · Date range picker"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "date-picker",
        "input"
      ]
    },
    {
      "name": "input-43",
      "type": "registry:component",
      "dependencies": [
        "@timui/react"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/calendar-rac.json",
        "https://ui.timkit.cn/r/datefield-rac.json"
      ],
      "optionalPeerDependencies": [
        "@internationalized/date",
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-43.tsx",
          "type": "registry:component",
          "target": "components/ui/input-43.tsx",
          "content": "'use client'\n\nimport { DatePicker, Label } from '@timui/react'\n\nexport default function Component() {\n  const now = new Date()\n  const today = new Date(now.getFullYear(), now.getMonth(), now.getDate())\n  const disabledRanges = [\n    [new Date(today), new Date(today.getFullYear(), today.getMonth(), today.getDate() + 5)],\n    [\n      new Date(today.getFullYear(), today.getMonth(), today.getDate() + 14),\n      new Date(today.getFullYear(), today.getMonth(), today.getDate() + 16),\n    ],\n    [\n      new Date(today.getFullYear(), today.getMonth(), today.getDate() + 23),\n      new Date(today.getFullYear(), today.getMonth(), today.getDate() + 24),\n    ],\n  ]\n\n  const isDateUnavailable = (date: Date) =>\n    date.getDay() === 0 ||\n    date.getDay() === 6 ||\n    disabledRanges.some(\n      (interval) =>\n        date.getTime() >= interval[0].getTime() && date.getTime() <= interval[1].getTime()\n    )\n\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label className=\"text-foreground text-sm font-medium\">\n        Date range picker (unavailable dates)\n      </Label>\n      <DatePicker\n        mode=\"range\"\n        calendarProps={{\n          disabled: [{ before: today }, isDateUnavailable],\n        }}\n      />\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Built with TimUI atomic components + core Zag machine\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-43.vue",
          "target": "components/ui/input-43.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport { cn } from '@timui/core'\nimport { CalendarIcon } from 'lucide-vue-next'\nimport { DateInput } from '@timui/vue'\nimport { DateRangePicker } from '@timui/vue'\nimport { DateRangePickerContent } from '@timui/vue'\nimport { DateRangePickerTrigger } from '@timui/vue'\nimport { Group } from '@timui/vue'\nimport { Label } from '@timui/vue'\nimport { RangeCalendar } from '@timui/vue'\n\nconst dateInputStyle =\n  'relative inline-flex h-9 w-full items-center overflow-hidden whitespace-nowrap rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none data-focus-within:border-ring data-focus-within:ring-ring/50 data-focus-within:ring-[3px] data-focus-within:has-aria-invalid:ring-destructive/20 dark:data-focus-within:has-aria-invalid:ring-destructive/40 data-focus-within:has-aria-invalid:border-destructive'\n\nconst startOfDay = (date: Date) => new Date(date.getFullYear(), date.getMonth(), date.getDate())\nconst addDays = (date: Date, days: number) => {\n  const next = new Date(date)\n  next.setDate(next.getDate() + days)\n  return startOfDay(next)\n}\n\nconst now = startOfDay(new Date())\nconst disabledRanges: Array<[Date, Date]> = [\n  [now, addDays(now, 5)],\n  [addDays(now, 14), addDays(now, 16)],\n  [addDays(now, 23), addDays(now, 24)],\n]\n\nconst rangeValue = ref<{ from?: Date; to?: Date } | undefined>(undefined)\n\nfunction isDateUnavailable(date: Date) {\n  const target = startOfDay(date).getTime()\n  const day = date.getDay()\n  const isWeekend = day === 0 || day === 6\n  return (\n    isWeekend ||\n    disabledRanges.some(\n      ([start, end]) => target >= start.getTime() && target <= end.getTime()\n    )\n  )\n}\n\nfunction setRange(next: Date | { from?: Date; to?: Date } | undefined) {\n  rangeValue.value = next && !(next instanceof Date) ? next : undefined\n}\n\nconst validationMessage = computed(() => {\n  const value = rangeValue.value\n  if (!value?.from || !value?.to) return null\n\n  const start = startOfDay(value.from).getTime()\n  const end = startOfDay(value.to).getTime()\n\n  const hasUnavailable = disabledRanges.some(\n    ([rangeStart, rangeEnd]) =>\n      end >= rangeStart.getTime() && start <= rangeEnd.getTime()\n  )\n\n  return hasUnavailable ? 'Selected date range may not include unavailable dates.' : null\n})\n</script>\n\n<template>\n  <DateRangePicker\n    class=\"*:not-first:mt-2\"\n    :modelValue=\"rangeValue\"\n    :isDateUnavailable=\"isDateUnavailable\"\n    :minDate=\"now\"\n    @update:modelValue=\"setRange\"\n  >\n    <Label class=\"text-foreground text-sm font-medium\">Date range picker (unavailable dates)</Label>\n\n    <div class=\"flex\">\n      <Group :class=\"cn(dateInputStyle, 'pe-9')\">\n        <DateInput data-slot=\"start\" unstyled />\n        <span aria-hidden=\"true\" class=\"text-muted-foreground/70 px-2\">-</span>\n        <DateInput data-slot=\"end\" unstyled />\n      </Group>\n\n      <DateRangePickerTrigger\n        class=\"text-muted-foreground/80 hover:text-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 z-10 -ms-9 -me-px flex w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none data-focus-visible:ring-[3px]\"\n      >\n        <CalendarIcon :size=\"16\" />\n      </DateRangePickerTrigger>\n    </div>\n\n    <DateRangePickerContent\n      class=\"bg-background text-popover-foreground data-entering:animate-in data-exiting:animate-out data-[entering]:fade-in-0 data-[exiting]:fade-out-0 data-[entering]:zoom-in-95 data-[exiting]:zoom-out-95 data-[placement=bottom]:slide-in-from-top-2 data-[placement=left]:slide-in-from-right-2 data-[placement=right]:slide-in-from-left-2 data-[placement=top]:slide-in-from-bottom-2 z-50 rounded-md border shadow-lg outline-hidden\"\n    >\n      <div class=\"max-h-[inherit] overflow-auto p-2\">\n        <RangeCalendar />\n      </div>\n    </DateRangePickerContent>\n\n    <p v-if=\"validationMessage\" class=\"text-destructive mt-1 text-xs\" role=\"alert\">\n      {{ validationMessage }}\n    </p>\n\n    <p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n      Built with\n      <a\n        class=\"hover:text-foreground underline\"\n        href=\"https://react-spectrum.adobe.com/react-aria/DateRangePicker.html\"\n        target=\"_blank\"\n        rel=\"noopener nofollow\"\n      >\n        React Aria\n      </a>\n    </p>\n  </DateRangePicker>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-43.html",
          "target": "components/ui/input-43.html",
          "type": "registry:component",
          "content": "<template>\n  <DateRangePicker class=\"*:not-first:mt-2\" isdateunavailable=\"${isDateUnavailable}\" validate=\"${validate}\"><Label class=\"text-foreground text-sm font-medium\">Date range picker (unavailable dates)\n      </Label><div class=\"flex\"><Group class=\"${cn(dateInputStyle, 'pe-9')}\"><DateInput slot=\"start\" unstyled /><span aria-hidden=\"true\" class=\"text-muted-foreground/70 px-2\">-\n          </span><DateInput slot=\"end\" unstyled /></Group><Button class=\"text-muted-foreground/80 hover:text-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 z-10 -ms-9 -me-px flex w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none data-focus-visible:ring-[3px]\"><CalendarIcon size=\"${16}\" /></Button></div><Popover class=\"bg-background text-popover-foreground data-entering:animate-in data-exiting:animate-out data-[entering]:fade-in-0 data-[exiting]:fade-out-0 data-[entering]:zoom-in-95 data-[exiting]:zoom-out-95 data-[placement=bottom]:slide-in-from-top-2 data-[placement=left]:slide-in-from-right-2 data-[placement=right]:slide-in-from-left-2 data-[placement=top]:slide-in-from-bottom-2 z-50 rounded-md border shadow-lg outline-hidden\" offset=\"${4}\"><Dialog class=\"max-h-[inherit] overflow-auto p-2\"><RangeCalendar minvalue=\"${now}\" isdateunavailable=\"${isDateUnavailable}\" /></Dialog></Popover><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with${' '}<a class=\"hover:text-foreground underline\" href=\"https://react-spectrum.adobe.com/react-aria/DateRangePicker.html\" target=\"_blank\" rel=\"noopener nofollow\">React Aria\n        </a></p></DateRangePicker>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-43.wxml",
          "target": "components/ui/input-43/input-43.wxml",
          "type": "registry:component",
          "content": "<view>\n  <daterangepicker class=\"*:not-first:mt-2\" isdateunavailable=\"{{isDateUnavailable}}\" validate=\"{{validate}}\"><label class=\"text-foreground text-sm font-medium\">Date range picker (unavailable dates)\n      </label><view class=\"flex\"><group class=\"{{cn(dateInputStyle, 'pe-9')}}\"><dateinput slot=\"start\" unstyled /><text aria-hidden=\"true\" class=\"text-muted-foreground/70 px-2\">-\n          </text><dateinput slot=\"end\" unstyled /></group><button class=\"text-muted-foreground/80 hover:text-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 z-10 -ms-9 -me-px flex w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none data-focus-visible:ring-[3px]\"><calendaricon size=\"{{16}}\" /></button></view><popover class=\"bg-background text-popover-foreground data-entering:animate-in data-exiting:animate-out data-[entering]:fade-in-0 data-[exiting]:fade-out-0 data-[entering]:zoom-in-95 data-[exiting]:zoom-out-95 data-[placement=bottom]:slide-in-from-top-2 data-[placement=left]:slide-in-from-right-2 data-[placement=right]:slide-in-from-left-2 data-[placement=top]:slide-in-from-bottom-2 z-50 rounded-md border shadow-lg outline-hidden\" offset=\"{{4}}\"><dialog class=\"max-h-[inherit] overflow-auto p-2\"><rangecalendar minvalue=\"{{now}}\" isdateunavailable=\"{{isDateUnavailable}}\" /></dialog></popover><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://react-spectrum.adobe.com/react-aria/DateRangePicker.html\" target=\"_blank\" rel=\"noopener nofollow\">React Aria\n        </a></text></daterangepicker>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "date",
          "calendar",
          "range calendar",
          "picker",
          "react aria"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-43",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-43",
              "path": "registry/default/components/input/input-43.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-43",
              "path": "registry/default/components/input/input-43.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-43",
              "path": "registry/default/components/input/input-43.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-43",
              "path": "registry/default/components/input/input-43.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ]
    },
    {
      "name": "input-44",
      "type": "registry:component",
      "dependencies": [
        "@timui/core",
        "@timui/react",
        "input-otp"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-44.tsx",
          "type": "registry:component",
          "target": "components/ui/input-44.tsx",
          "content": "'use client'\n\nimport { useId } from 'react'\nimport { cn } from '@timui/core'\nimport { Label } from '@timui/react'\nimport { OTPInput, SlotProps } from 'input-otp'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>OTP input single</Label>\n      <OTPInput\n        id={id}\n        containerClassName=\"flex items-center gap-3 has-disabled:opacity-50\"\n        maxLength={4}\n        render={({ slots }) => (\n          <div className=\"flex\">\n            {slots.map((slot, idx) => (\n              <Slot key={idx} {...slot} />\n            ))}\n          </div>\n        )}\n      />\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Built with{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://github.com/guilhermerodz/input-otp\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          Input OTP\n        </a>\n      </p>\n    </div>\n  )\n}\n\nfunction Slot(props: SlotProps) {\n  return (\n    <div\n      className={cn(\n        'border-input bg-background text-foreground relative -ms-px flex size-9 items-center justify-center border font-medium shadow-xs transition-[color,box-shadow] first:ms-0 first:rounded-s-md last:rounded-e-md',\n        { 'border-ring ring-ring/50 z-10 ring-[3px]': props.isActive }\n      )}\n    >\n      {props.char !== null && <div>{props.char}</div>}\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-44.vue",
          "target": "components/ui/input-44.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { Label } from '@timui/vue'\n\nconst id = 'input-44'\nconst digits = ref(['', '', '', ''])\nconst inputRefs = ref<Array<HTMLInputElement | null>>([])\n\nfunction setInputRef(index: number, el: HTMLInputElement | null) {\n  inputRefs.value[index] = el\n}\n\nfunction handleInput(index: number, event: Event) {\n  const target = event.target as HTMLInputElement\n  const value = target.value.replace(/\\D/g, '').slice(-1)\n  digits.value[index] = value\n  target.value = value\n  if (value && index < digits.value.length - 1) {\n    inputRefs.value[index + 1]?.focus()\n  }\n}\n\nfunction handleKeydown(index: number, event: KeyboardEvent) {\n  if (event.key === 'Backspace' && !digits.value[index] && index > 0) {\n    inputRefs.value[index - 1]?.focus()\n  }\n}\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\">\n    <Label :htmlFor=\"id\">OTP input single</Label>\n    <div class=\"flex\">\n      <input\n        v-for=\"(_, index) in digits\"\n        :key=\"`${id}-${index}`\"\n        :id=\"index === 0 ? id : `${id}-${index}`\"\n        :ref=\"(el) => setInputRef(index, el as HTMLInputElement | null)\"\n        class=\"border-input bg-background text-foreground relative -ms-px flex size-9 items-center justify-center border text-center font-medium shadow-xs transition-[color,box-shadow] first:ms-0 first:rounded-s-md last:rounded-e-md focus:z-10 focus:outline-none focus:ring-2 focus:ring-ring/50\"\n        inputmode=\"numeric\"\n        pattern=\"[0-9]*\"\n        maxlength=\"1\"\n        autocomplete=\"one-time-code\"\n        @input=\"(event) => handleInput(index, event)\"\n        @keydown=\"(event) => handleKeydown(index, event)\"\n      />\n    </div>\n    <p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n      Built with\n      <a\n        class=\"hover:text-foreground underline\"\n        href=\"https://github.com/guilhermerodz/input-otp\"\n        target=\"_blank\"\n        rel=\"noopener nofollow\"\n      >\n        Input OTP\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-44.html",
          "target": "components/ui/input-44.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">OTP input single</Label><OTPInput id=\"${id}\" containerclassname=\"flex items-center gap-3 has-disabled:opacity-50\" maxlength=\"${4}\" render=\"${({ slots }) => (\n          <div className=\"flex\">\n            {slots.map((slot, idx) => (\n              <Slot key={idx} {...slot} />\n            ))}\n          </div>\n        )}\" /><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with${' '}<a class=\"hover:text-foreground underline\" href=\"https://github.com/guilhermerodz/input-otp\" target=\"_blank\" rel=\"noopener nofollow\">Input OTP\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-44.wxml",
          "target": "components/ui/input-44/input-44.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">OTP input single</label><otpinput id=\"{{id}}\" containerclassname=\"flex items-center gap-3 has-disabled:opacity-50\" maxlength=\"{{4}}\" render=\"{{({ slots }) => (\n          <div className=\"flex\">\n            {slots.map((slot, idx) => (\n              <Slot key={idx} {...slot} />\n            ))}\n          </div>\n        )}}\" /><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://github.com/guilhermerodz/input-otp\" target=\"_blank\" rel=\"noopener nofollow\">Input OTP\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "otp"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-44",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-44",
              "path": "registry/default/components/input/input-44.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-44",
              "path": "registry/default/components/input/input-44.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-44",
              "path": "registry/default/components/input/input-44.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-44",
              "path": "registry/default/components/input/input-44.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@timui/react",
              "input-otp"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ]
    },
    {
      "name": "input-45",
      "type": "registry:component",
      "dependencies": [
        "@timui/core",
        "@timui/react",
        "input-otp"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-45.tsx",
          "type": "registry:component",
          "target": "components/ui/input-45.tsx",
          "content": "'use client'\n\nimport { useId } from 'react'\nimport { cn } from '@timui/core'\nimport { Label } from '@timui/react'\nimport { OTPInput, SlotProps } from 'input-otp'\nimport { MinusIcon } from 'lucide-react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>OTP input double</Label>\n      <OTPInput\n        id={id}\n        containerClassName=\"flex items-center gap-3 has-disabled:opacity-50\"\n        maxLength={6}\n        render={({ slots }) => (\n          <>\n            <div className=\"flex\">\n              {slots.slice(0, 3).map((slot, idx) => (\n                <Slot key={idx} {...slot} />\n              ))}\n            </div>\n\n            <div className=\"text-muted-foreground/80\">\n              <MinusIcon size={16} aria-hidden=\"true\" />\n            </div>\n\n            <div className=\"flex\">\n              {slots.slice(3).map((slot, idx) => (\n                <Slot key={idx} {...slot} />\n              ))}\n            </div>\n          </>\n        )}\n      />\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Built with{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://github.com/guilhermerodz/input-otp\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          Input OTP\n        </a>\n      </p>\n    </div>\n  )\n}\n\nfunction Slot(props: SlotProps) {\n  return (\n    <div\n      className={cn(\n        'border-input bg-background text-foreground relative -ms-px flex size-9 items-center justify-center border font-medium shadow-xs transition-[color,box-shadow] first:ms-0 first:rounded-s-md last:rounded-e-md',\n        { 'border-ring ring-ring/50 z-10 ring-[3px]': props.isActive }\n      )}\n    >\n      {props.char !== null && <div>{props.char}</div>}\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-45.vue",
          "target": "components/ui/input-45.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { MinusIcon } from 'lucide-vue-next'\nimport { Label } from '@timui/vue'\n\nconst id = 'input-45'\nconst digits = ref(['', '', '', '', '', ''])\nconst inputRefs = ref<Array<HTMLInputElement | null>>([])\n\nfunction setInputRef(index: number, el: HTMLInputElement | null) {\n  inputRefs.value[index] = el\n}\n\nfunction handleInput(index: number, event: Event) {\n  const target = event.target as HTMLInputElement\n  const value = target.value.replace(/\\D/g, '').slice(-1)\n  digits.value[index] = value\n  target.value = value\n  if (value && index < digits.value.length - 1) {\n    inputRefs.value[index + 1]?.focus()\n  }\n}\n\nfunction handleKeydown(index: number, event: KeyboardEvent) {\n  if (event.key === 'Backspace' && !digits.value[index] && index > 0) {\n    inputRefs.value[index - 1]?.focus()\n  }\n}\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\">\n    <Label :htmlFor=\"id\">OTP input double</Label>\n    <div class=\"flex items-center gap-3 has-disabled:opacity-50\">\n      <div class=\"flex\">\n        <input\n          v-for=\"(_, index) in digits.slice(0, 3)\"\n          :key=\"`${id}-${index}`\"\n          :id=\"index === 0 ? id : `${id}-${index}`\"\n          :ref=\"(el) => setInputRef(index, el as HTMLInputElement | null)\"\n          class=\"border-input bg-background text-foreground relative -ms-px flex size-9 items-center justify-center border text-center font-medium shadow-xs transition-[color,box-shadow] first:ms-0 first:rounded-s-md last:rounded-e-md focus:z-10 focus:outline-none focus:ring-2 focus:ring-ring/50\"\n          inputmode=\"numeric\"\n          pattern=\"[0-9]*\"\n          maxlength=\"1\"\n          autocomplete=\"one-time-code\"\n          @input=\"(event) => handleInput(index, event)\"\n          @keydown=\"(event) => handleKeydown(index, event)\"\n        />\n      </div>\n      <div class=\"text-muted-foreground/80\">\n        <MinusIcon :size=\"16\" aria-hidden=\"true\" />\n      </div>\n      <div class=\"flex\">\n        <input\n          v-for=\"(_, index) in digits.slice(3)\"\n          :key=\"`${id}-${index + 3}`\"\n          :id=\"`${id}-${index + 3}`\"\n          :ref=\"(el) => setInputRef(index + 3, el as HTMLInputElement | null)\"\n          class=\"border-input bg-background text-foreground relative -ms-px flex size-9 items-center justify-center border text-center font-medium shadow-xs transition-[color,box-shadow] first:ms-0 first:rounded-s-md last:rounded-e-md focus:z-10 focus:outline-none focus:ring-2 focus:ring-ring/50\"\n          inputmode=\"numeric\"\n          pattern=\"[0-9]*\"\n          maxlength=\"1\"\n          autocomplete=\"one-time-code\"\n          @input=\"(event) => handleInput(index + 3, event)\"\n          @keydown=\"(event) => handleKeydown(index + 3, event)\"\n        />\n      </div>\n    </div>\n    <p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n      Built with\n      <a\n        class=\"hover:text-foreground underline\"\n        href=\"https://github.com/guilhermerodz/input-otp\"\n        target=\"_blank\"\n        rel=\"noopener nofollow\"\n      >\n        Input OTP\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-45.html",
          "target": "components/ui/input-45.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">OTP input double</Label><OTPInput id=\"${id}\" containerclassname=\"flex items-center gap-3 has-disabled:opacity-50\" maxlength=\"${6}\" render=\"${({ slots }) => (\n          <>\n            <div className=\"flex\">\n              {slots.slice(0, 3).map((slot, idx) => (\n                <Slot key={idx} {...slot} />\n              ))}\n            </div>\n\n            <div className=\"text-muted-foreground/80\">\n              <MinusIcon size={16} aria-hidden=\"true\" />\n            </div>\n\n            <div className=\"flex\">\n              {slots.slice(3).map((slot, idx) => (\n                <Slot key={idx} {...slot} />\n              ))}\n            </div>\n          </>\n        )}\" /><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with${' '}<a class=\"hover:text-foreground underline\" href=\"https://github.com/guilhermerodz/input-otp\" target=\"_blank\" rel=\"noopener nofollow\">Input OTP\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-45.wxml",
          "target": "components/ui/input-45/input-45.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">OTP input double</label><otpinput id=\"{{id}}\" containerclassname=\"flex items-center gap-3 has-disabled:opacity-50\" maxlength=\"{{6}}\" render=\"{{({ slots }) => (\n          <>\n            <div className=\"flex\">\n              {slots.slice(0, 3).map((slot, idx) => (\n                <Slot key={idx} {...slot} />\n              ))}\n            </div>\n\n            <div className=\"text-muted-foreground/80\">\n              <MinusIcon size={16} aria-hidden=\"true\" />\n            </div>\n\n            <div className=\"flex\">\n              {slots.slice(3).map((slot, idx) => (\n                <Slot key={idx} {...slot} />\n              ))}\n            </div>\n          </>\n        )}}\" /><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://github.com/guilhermerodz/input-otp\" target=\"_blank\" rel=\"noopener nofollow\">Input OTP\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "otp"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-45",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-45",
              "path": "registry/default/components/input/input-45.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-45",
              "path": "registry/default/components/input/input-45.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-45",
              "path": "registry/default/components/input/input-45.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-45",
              "path": "registry/default/components/input/input-45.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@timui/react",
              "input-otp"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ]
    },
    {
      "name": "input-47",
      "type": "registry:component",
      "dependencies": [
        "@timui/core",
        "@timui/react",
        "react-phone-number-input",
        "react-phone-number-input/flags"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-47.tsx",
          "type": "registry:component",
          "target": "components/ui/input-47.tsx",
          "content": "'use client'\n\nimport React, { useId, useState } from 'react'\nimport { cn } from '@timui/core'\nimport { Input, Label } from '@timui/react'\nimport { ChevronDownIcon, PhoneIcon } from 'lucide-react'\nimport * as RPNInput from 'react-phone-number-input'\nimport flags from 'react-phone-number-input/flags'\n\nexport default function Component() {\n  const id = useId()\n  const [value, setValue] = useState('')\n\n  return (\n    <div className=\"*:not-first:mt-2\" dir=\"ltr\">\n      <Label htmlFor={id}>PhoneIcon number input</Label>\n      <RPNInput.default\n        className=\"flex rounded-md shadow-xs\"\n        international\n        flagComponent={FlagComponent}\n        countrySelectComponent={CountrySelect}\n        inputComponent={PhoneInput}\n        id={id}\n        placeholder=\"Enter phone number\"\n        value={value}\n        onChange={(newValue) => setValue(newValue ?? '')}\n      />\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Built with{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://gitlab.com/catamphetamine/react-phone-number-input\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          react-phone-number-input\n        </a>\n      </p>\n    </div>\n  )\n}\n\nconst PhoneInput = ({ className, ...props }: React.ComponentProps<'input'>) => {\n  return (\n    <Input\n      data-slot=\"phone-input\"\n      className={cn('-ms-px rounded-s-none shadow-none focus-visible:z-10', className)}\n      {...props}\n    />\n  )\n}\n\nPhoneInput.displayName = 'PhoneInput'\n\ntype CountrySelectProps = {\n  disabled?: boolean\n  value: RPNInput.Country\n  onChange: (value: RPNInput.Country) => void\n  options: { label: string; value: RPNInput.Country | undefined }[]\n}\n\nconst CountrySelect = ({ disabled, value, onChange, options }: CountrySelectProps) => {\n  const handleSelect = (event: React.ChangeEvent<HTMLSelectElement>) => {\n    onChange(event.target.value as RPNInput.Country)\n  }\n\n  return (\n    <div className=\"border-input bg-background text-muted-foreground focus-within:border-ring focus-within:ring-ring/50 hover:bg-accent hover:text-foreground has-aria-invalid:border-destructive/60 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40 relative inline-flex items-center self-stretch rounded-s-md border py-2 ps-3 pe-2 transition-[color,box-shadow] outline-none focus-within:z-10 focus-within:ring-[3px] has-disabled:pointer-events-none has-disabled:opacity-50\">\n      <div className=\"inline-flex items-center gap-1\" aria-hidden=\"true\">\n        <FlagComponent country={value} countryName={value} aria-hidden=\"true\" />\n        <span className=\"text-muted-foreground/80\">\n          <ChevronDownIcon size={16} aria-hidden=\"true\" />\n        </span>\n      </div>\n      <select\n        disabled={disabled}\n        value={value}\n        onChange={handleSelect}\n        className=\"absolute inset-0 text-sm opacity-0\"\n        aria-label=\"Select country\"\n      >\n        <option key=\"default\" value=\"\">\n          Select a country\n        </option>\n        {options\n          .filter((x) => x.value)\n          .map((option, i) => (\n            <option key={option.value ?? `empty-${i}`} value={option.value}>\n              {option.label} {option.value && `+${RPNInput.getCountryCallingCode(option.value)}`}\n            </option>\n          ))}\n      </select>\n    </div>\n  )\n}\n\nconst FlagComponent = ({ country, countryName }: RPNInput.FlagProps) => {\n  const Flag = flags[country]\n\n  return (\n    <span className=\"w-5 overflow-hidden rounded-sm\">\n      {Flag ? <Flag title={countryName} /> : <PhoneIcon size={16} aria-hidden=\"true\" />}\n    </span>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-47.vue",
          "target": "components/ui/input-47.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { cn } from '@timui/core';\nimport { ChevronDownIcon, PhoneIcon } from 'lucide-vue-next';\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\nconst id = 'input-47';\nconst country = ref('US');\nconst localNumber = ref('');\n\nconst countryOptions = [\n  { value: 'US', label: 'United States', dialCode: '1' },\n  { value: 'CN', label: 'China', dialCode: '86' },\n  { value: 'GB', label: 'United Kingdom', dialCode: '44' },\n  { value: 'JP', label: 'Japan', dialCode: '81' },\n];\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\" dir=\"ltr\">\n    <Label :htmlFor=\"id\">Phone number input</Label>\n    <div class=\"flex rounded-md shadow-xs\">\n      <div class=\"border-input bg-background text-muted-foreground focus-within:border-ring focus-within:ring-ring/50 hover:bg-accent hover:text-foreground relative inline-flex items-center self-stretch rounded-s-md border py-2 ps-3 pe-2 transition-[color,box-shadow] outline-none focus-within:z-10 focus-within:ring-[3px]\">\n        <div class=\"inline-flex items-center gap-1\" aria-hidden=\"true\">\n          <PhoneIcon :size=\"16\" aria-hidden=\"true\" />\n          <span class=\"text-muted-foreground/80\"><ChevronDownIcon :size=\"16\" aria-hidden=\"true\" /></span>\n        </div>\n        <select v-model=\"country\" class=\"absolute inset-0 text-sm opacity-0\" aria-label=\"Select country\">\n          <option v-for=\"option in countryOptions\" :key=\"option.value\" :value=\"option.value\">\n            {{ option.label }} +{{ option.dialCode }}\n          </option>\n        </select>\n      </div>\n\n      <Input\n        :id=\"id\"\n        class=\"-ms-px rounded-s-none shadow-none focus-visible:z-10\"\n        placeholder=\"Enter phone number\"\n        type=\"tel\"\n        inputMode=\"tel\"\n        v-model=\"localNumber\"\n      />\n    </div>\n\n    <p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n      Built with a Timkit Vue-compatible phone input layout.\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-47.html",
          "target": "components/ui/input-47.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\" dir=\"ltr\"><Label htmlfor=\"${id}\">PhoneIcon number input</Label><RPNInput.default class=\"flex rounded-md shadow-xs\" international flagcomponent=\"${FlagComponent}\" countryselectcomponent=\"${CountrySelect}\" inputcomponent=\"${PhoneInput}\" id=\"${id}\" placeholder=\"Enter phone number\" value=\"${value}\" onchange=\"${(newValue) => setValue(newValue ?? '')}\" /><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with${' '}<a class=\"hover:text-foreground underline\" href=\"https://gitlab.com/catamphetamine/react-phone-number-input\" target=\"_blank\" rel=\"noopener nofollow\">react-phone-number-input\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-47.wxml",
          "target": "components/ui/input-47/input-47.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\" dir=\"ltr\"><label htmlfor=\"{{id}}\">PhoneIcon number input</label><rpninput.default class=\"flex rounded-md shadow-xs\" international flagcomponent=\"{{FlagComponent}}\" countryselectcomponent=\"{{CountrySelect}}\" inputcomponent=\"{{PhoneInput}}\" id=\"{{id}}\" placeholder=\"Enter phone number\" value=\"{{value}}\" onchange=\"{{(newValue) => setValue(newValue ?? '')}}\" /><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://gitlab.com/catamphetamine/react-phone-number-input\" target=\"_blank\" rel=\"noopener nofollow\">react-phone-number-input\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "phone"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-47",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-47",
              "path": "registry/default/components/input/input-47.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-47",
              "path": "registry/default/components/input/input-47.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-47",
              "path": "registry/default/components/input/input-47.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-47",
              "path": "registry/default/components/input/input-47.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@timui/react",
              "react-phone-number-input",
              "react-phone-number-input/flags"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ]
    },
    {
      "name": "input-48",
      "type": "registry:component",
      "dependencies": [
        "@timui/react",
        "react-payment-inputs"
      ],
      "devDependencies": [
        "@types/react-payment-inputs"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-48.tsx",
          "type": "registry:component",
          "target": "components/ui/input-48.tsx",
          "content": "'use client'\n\nimport { useId } from 'react'\nimport { Input, Label } from '@timui/react'\nimport { CreditCardIcon } from 'lucide-react'\nimport { usePaymentInputs } from 'react-payment-inputs'\n\nexport default function Component() {\n  const id = useId()\n  const { getCardNumberProps } = usePaymentInputs()\n\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={`number-${id}`}>Card Number</Label>\n      <div className=\"relative\">\n        <Input\n          {...getCardNumberProps()}\n          id={`number-${id}`}\n          className=\"peer ps-9 [direction:inherit]\"\n        />\n        <div className=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\">\n          <CreditCardIcon size={16} aria-hidden=\"true\" />\n        </div>\n      </div>\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Built with{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://github.com/medipass/react-payment-inputs\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React Payment Inputs\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-48.vue",
          "target": "components/ui/input-48.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { CreditCardIcon } from 'lucide-vue-next'\nimport { Input } from '@timui/vue'\nimport { Label } from '@timui/vue'\n\nconst id = 'input-48'\nconst cardNumber = ref('')\n\nfunction formatCardNumber(value: string) {\n  const digits = value.replace(/\\D/g, '').slice(0, 19)\n  return digits.replace(/(.{4})/g, '$1 ').trim()\n}\n\nfunction onCardNumberChange(value: string | number) {\n  cardNumber.value = formatCardNumber(String(value ?? ''))\n}\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\">\n    <Label :htmlFor=\"`number-${id}`\">Card Number</Label>\n    <div class=\"relative\">\n      <Input\n        :id=\"`number-${id}`\"\n        class=\"peer ps-9 [direction:inherit]\"\n        inputmode=\"numeric\"\n        autocomplete=\"cc-number\"\n        :modelValue=\"cardNumber\"\n        @update:modelValue=\"onCardNumberChange\"\n      />\n      <div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\">\n        <CreditCardIcon :size=\"16\" aria-hidden=\"true\" />\n      </div>\n    </div>\n    <p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n      Built with\n      <a\n        class=\"hover:text-foreground underline\"\n        href=\"https://github.com/medipass/react-payment-inputs\"\n        target=\"_blank\"\n        rel=\"noopener nofollow\"\n      >\n        React Payment Inputs\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-48.html",
          "target": "components/ui/input-48.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${`number-${id}`}\">Card Number</Label><div class=\"relative\"><Input id=\"${`number-${id}`}\" class=\"peer ps-9 [direction:inherit]\" /><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\"><CreditCardIcon size=\"${16}\" aria-hidden=\"true\" /></div></div><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with${' '}<a class=\"hover:text-foreground underline\" href=\"https://github.com/medipass/react-payment-inputs\" target=\"_blank\" rel=\"noopener nofollow\">React Payment Inputs\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-48.wxml",
          "target": "components/ui/input-48/input-48.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{`number-${id}`}}\">Card Number</label><view class=\"relative\"><input id=\"{{`number-${id}`}}\" class=\"peer ps-9 [direction:inherit]\" /><view class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\"><creditcardicon size=\"{{16}}\" aria-hidden=\"true\" /></view></view><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://github.com/medipass/react-payment-inputs\" target=\"_blank\" rel=\"noopener nofollow\">React Payment Inputs\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "checkout",
          "payment",
          "credit card",
          "form"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-48",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-48",
              "path": "registry/default/components/input/input-48.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-48",
              "path": "registry/default/components/input/input-48.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-48",
              "path": "registry/default/components/input/input-48.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-48",
              "path": "registry/default/components/input/input-48.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react",
              "react-payment-inputs"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ]
    },
    {
      "name": "input-49",
      "type": "registry:component",
      "dependencies": [
        "@timui/react",
        "react-payment-inputs"
      ],
      "devDependencies": [
        "@types/react-payment-inputs"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-49.tsx",
          "type": "registry:component",
          "target": "components/ui/input-49.tsx",
          "content": "'use client'\n\nimport { useId } from 'react'\nimport { Input, Label } from '@timui/react'\nimport { usePaymentInputs } from 'react-payment-inputs'\n\nexport default function Component() {\n  const id = useId()\n  const { getExpiryDateProps } = usePaymentInputs()\n\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={`expiry-${id}`}>Expiry date</Label>\n      <Input {...getExpiryDateProps()} id={`expiry-${id}`} className=\"[direction:inherit]\" />\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Built with{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://github.com/medipass/react-payment-inputs\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React Payment Inputs\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-49.vue",
          "target": "components/ui/input-49.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { Input } from '@timui/vue'\nimport { Label } from '@timui/vue'\n\nconst id = 'input-49'\nconst expiry = ref('')\n\nfunction formatExpiry(value: string) {\n  const digits = value.replace(/\\D/g, '').slice(0, 4)\n  if (digits.length <= 2) return digits\n  return `${digits.slice(0, 2)}/${digits.slice(2)}`\n}\n\nfunction onExpiryChange(value: string | number) {\n  expiry.value = formatExpiry(String(value ?? ''))\n}\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\">\n    <Label :htmlFor=\"`expiry-${id}`\">Expiry date</Label>\n    <Input\n      :id=\"`expiry-${id}`\"\n      class=\"[direction:inherit]\"\n      inputmode=\"numeric\"\n      autocomplete=\"cc-exp\"\n      placeholder=\"MM/YY\"\n      :modelValue=\"expiry\"\n      @update:modelValue=\"onExpiryChange\"\n    />\n    <p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n      Built with\n      <a\n        class=\"hover:text-foreground underline\"\n        href=\"https://github.com/medipass/react-payment-inputs\"\n        target=\"_blank\"\n        rel=\"noopener nofollow\"\n      >\n        React Payment Inputs\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-49.html",
          "target": "components/ui/input-49.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${`expiry-${id}`}\">Expiry date</Label><Input id=\"${`expiry-${id}`}\" class=\"[direction:inherit]\" /><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with${' '}<a class=\"hover:text-foreground underline\" href=\"https://github.com/medipass/react-payment-inputs\" target=\"_blank\" rel=\"noopener nofollow\">React Payment Inputs\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-49.wxml",
          "target": "components/ui/input-49/input-49.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{`expiry-${id}`}}\">Expiry date</label><input id=\"{{`expiry-${id}`}}\" class=\"[direction:inherit]\" /><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://github.com/medipass/react-payment-inputs\" target=\"_blank\" rel=\"noopener nofollow\">React Payment Inputs\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "checkout",
          "payment",
          "credit card",
          "form"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-49",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-49",
              "path": "registry/default/components/input/input-49.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-49",
              "path": "registry/default/components/input/input-49.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-49",
              "path": "registry/default/components/input/input-49.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-49",
              "path": "registry/default/components/input/input-49.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react",
              "react-payment-inputs"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ]
    },
    {
      "name": "input-50",
      "type": "registry:component",
      "dependencies": [
        "@timui/react",
        "react-payment-inputs"
      ],
      "devDependencies": [
        "@types/react-payment-inputs"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-50.tsx",
          "type": "registry:component",
          "target": "components/ui/input-50.tsx",
          "content": "'use client'\n\nimport { useId } from 'react'\nimport { Input, Label } from '@timui/react'\nimport { usePaymentInputs } from 'react-payment-inputs'\n\nexport default function Component() {\n  const id = useId()\n  const { getCVCProps } = usePaymentInputs()\n\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={`cvc-${id}`}>Code</Label>\n      <Input {...getCVCProps()} id={`cvc-${id}`} className=\"[direction:inherit]\" />\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Built with{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://github.com/medipass/react-payment-inputs\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React Payment Inputs\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-50.vue",
          "target": "components/ui/input-50.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { Input } from '@timui/vue'\nimport { Label } from '@timui/vue'\n\nconst id = 'input-50'\nconst cvc = ref('')\n\nfunction onCvcChange(value: string | number) {\n  cvc.value = String(value ?? '').replace(/\\D/g, '').slice(0, 4)\n}\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\">\n    <Label :htmlFor=\"`cvc-${id}`\">Code</Label>\n    <Input\n      :id=\"`cvc-${id}`\"\n      class=\"[direction:inherit]\"\n      inputmode=\"numeric\"\n      autocomplete=\"cc-csc\"\n      :modelValue=\"cvc\"\n      @update:modelValue=\"onCvcChange\"\n    />\n    <p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n      Built with\n      <a\n        class=\"hover:text-foreground underline\"\n        href=\"https://github.com/medipass/react-payment-inputs\"\n        target=\"_blank\"\n        rel=\"noopener nofollow\"\n      >\n        React Payment Inputs\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-50.html",
          "target": "components/ui/input-50.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${`cvc-${id}`}\">Code</Label><Input id=\"${`cvc-${id}`}\" class=\"[direction:inherit]\" /><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with${' '}<a class=\"hover:text-foreground underline\" href=\"https://github.com/medipass/react-payment-inputs\" target=\"_blank\" rel=\"noopener nofollow\">React Payment Inputs\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-50.wxml",
          "target": "components/ui/input-50/input-50.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{`cvc-${id}`}}\">Code</label><input id=\"{{`cvc-${id}`}}\" class=\"[direction:inherit]\" /><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://github.com/medipass/react-payment-inputs\" target=\"_blank\" rel=\"noopener nofollow\">React Payment Inputs\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "checkout",
          "payment",
          "credit card",
          "form"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-50",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-50",
              "path": "registry/default/components/input/input-50.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-50",
              "path": "registry/default/components/input/input-50.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-50",
              "path": "registry/default/components/input/input-50.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-50",
              "path": "registry/default/components/input/input-50.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react",
              "react-payment-inputs"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ]
    },
    {
      "name": "input-51",
      "type": "registry:component",
      "dependencies": [
        "@timui/react",
        "react-payment-inputs",
        "react-payment-inputs/images"
      ],
      "devDependencies": [
        "@types/react-payment-inputs"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-51.tsx",
          "type": "registry:component",
          "target": "components/ui/input-51.tsx",
          "content": "'use client'\n\nimport { useId } from 'react'\nimport { Input } from '@timui/react'\nimport { CreditCardIcon } from 'lucide-react'\nimport { usePaymentInputs } from 'react-payment-inputs'\nimport images, { type CardImages } from 'react-payment-inputs/images'\n\nexport default function Component() {\n  const id = useId()\n  const { meta, getCardNumberProps, getExpiryDateProps, getCVCProps, getCardImageProps } =\n    usePaymentInputs()\n\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <legend className=\"text-foreground text-sm font-medium\">Card Details</legend>\n      <div className=\"rounded-md shadow-xs\">\n        <div className=\"relative focus-within:z-10\">\n          <Input\n            className=\"peer rounded-b-none pe-9 shadow-none [direction:inherit]\"\n            {...getCardNumberProps()}\n            id={`number-${id}`}\n          />\n          <div className=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 peer-disabled:opacity-50\">\n            {meta.cardType ? (\n              <svg\n                className=\"overflow-hidden rounded-sm\"\n                {...getCardImageProps({\n                  images: images as unknown as CardImages,\n                })}\n                width={20}\n              />\n            ) : (\n              <CreditCardIcon size={16} aria-hidden=\"true\" />\n            )}\n          </div>\n        </div>\n        <div className=\"-mt-px flex\">\n          <div className=\"min-w-0 flex-1 focus-within:z-10\">\n            <Input\n              className=\"rounded-e-none rounded-t-none shadow-none [direction:inherit]\"\n              {...getExpiryDateProps()}\n              id={`expiry-${id}`}\n            />\n          </div>\n          <div className=\"-ms-px min-w-0 flex-1 focus-within:z-10\">\n            <Input\n              className=\"rounded-s-none rounded-t-none shadow-none [direction:inherit]\"\n              {...getCVCProps()}\n              id={`cvc-${id}`}\n            />\n          </div>\n        </div>\n      </div>\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Built with{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://github.com/medipass/react-payment-inputs\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React Payment Inputs\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-51.vue",
          "target": "components/ui/input-51.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport { CreditCardIcon } from 'lucide-vue-next'\nimport { Input } from '@timui/vue'\n\nconst id = 'input-51'\nconst cardNumber = ref('')\nconst expiry = ref('')\nconst cvc = ref('')\n\nfunction formatCardNumber(value: string) {\n  const digits = value.replace(/\\D/g, '').slice(0, 19)\n  return digits.replace(/(.{4})/g, '$1 ').trim()\n}\n\nfunction formatExpiry(value: string) {\n  const digits = value.replace(/\\D/g, '').slice(0, 4)\n  if (digits.length <= 2) return digits\n  return `${digits.slice(0, 2)}/${digits.slice(2)}`\n}\n\nfunction detectCardType(value: string) {\n  const digits = value.replace(/\\D/g, '')\n  if (/^4/.test(digits)) return 'visa'\n  if (/^(5[1-5]|2[2-7])/.test(digits)) return 'mastercard'\n  if (/^3[47]/.test(digits)) return 'amex'\n  if (/^6(011|5)/.test(digits)) return 'discover'\n  return null\n}\n\nconst cardType = computed(() => detectCardType(cardNumber.value))\nconst cardTypeLabel = computed(() => {\n  if (!cardType.value) return ''\n  if (cardType.value === 'mastercard') return 'MC'\n  if (cardType.value === 'discover') return 'DISC'\n  return cardType.value.toUpperCase()\n})\n\nfunction onCardNumberChange(value: string | number) {\n  cardNumber.value = formatCardNumber(String(value ?? ''))\n}\n\nfunction onExpiryChange(value: string | number) {\n  expiry.value = formatExpiry(String(value ?? ''))\n}\n\nfunction onCvcChange(value: string | number) {\n  cvc.value = String(value ?? '').replace(/\\D/g, '').slice(0, 4)\n}\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\">\n    <legend class=\"text-foreground text-sm font-medium\">Card Details</legend>\n    <div class=\"rounded-md shadow-xs\">\n      <div class=\"relative focus-within:z-10\">\n        <Input\n          class=\"peer rounded-b-none pe-9 shadow-none [direction:inherit]\"\n          :id=\"`number-${id}`\"\n          inputmode=\"numeric\"\n          autocomplete=\"cc-number\"\n          :modelValue=\"cardNumber\"\n          @update:modelValue=\"onCardNumberChange\"\n        />\n        <div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 peer-disabled:opacity-50\">\n          <span v-if=\"cardTypeLabel\" class=\"text-[10px] font-medium tracking-wide\">{{ cardTypeLabel }}</span>\n          <CreditCardIcon v-else :size=\"16\" aria-hidden=\"true\" />\n        </div>\n      </div>\n\n      <div class=\"-mt-px flex\">\n        <div class=\"min-w-0 flex-1 focus-within:z-10\">\n          <Input\n            class=\"rounded-e-none rounded-t-none shadow-none [direction:inherit]\"\n            :id=\"`expiry-${id}`\"\n            inputmode=\"numeric\"\n            autocomplete=\"cc-exp\"\n            placeholder=\"MM/YY\"\n            :modelValue=\"expiry\"\n            @update:modelValue=\"onExpiryChange\"\n          />\n        </div>\n        <div class=\"-ms-px min-w-0 flex-1 focus-within:z-10\">\n          <Input\n            class=\"rounded-s-none rounded-t-none shadow-none [direction:inherit]\"\n            :id=\"`cvc-${id}`\"\n            inputmode=\"numeric\"\n            autocomplete=\"cc-csc\"\n            :modelValue=\"cvc\"\n            @update:modelValue=\"onCvcChange\"\n          />\n        </div>\n      </div>\n    </div>\n\n    <p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n      Built with\n      <a\n        class=\"hover:text-foreground underline\"\n        href=\"https://github.com/medipass/react-payment-inputs\"\n        target=\"_blank\"\n        rel=\"noopener nofollow\"\n      >\n        React Payment Inputs\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-51.html",
          "target": "components/ui/input-51.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><legend class=\"text-foreground text-sm font-medium\">Card Details</legend><div class=\"rounded-md shadow-xs\"><div class=\"relative focus-within:z-10\"><Input class=\"peer rounded-b-none pe-9 shadow-none [direction:inherit]\" id=\"${`number-${id}`}\" /><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 peer-disabled:opacity-50\"><!-- if meta.cardType -->\n<svg class=\"overflow-hidden rounded-sm\" width=\"${20}\" />\n<!-- else -->\n<CreditCardIcon size=\"${16}\" aria-hidden=\"true\" />\n<!-- endif --></div></div><div class=\"-mt-px flex\"><div class=\"min-w-0 flex-1 focus-within:z-10\"><Input class=\"rounded-e-none rounded-t-none shadow-none [direction:inherit]\" id=\"${`expiry-${id}`}\" /></div><div class=\"-ms-px min-w-0 flex-1 focus-within:z-10\"><Input class=\"rounded-s-none rounded-t-none shadow-none [direction:inherit]\" id=\"${`cvc-${id}`}\" /></div></div></div><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with${' '}<a class=\"hover:text-foreground underline\" href=\"https://github.com/medipass/react-payment-inputs\" target=\"_blank\" rel=\"noopener nofollow\">React Payment Inputs\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-51.wxml",
          "target": "components/ui/input-51/input-51.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><legend class=\"text-foreground text-sm font-medium\">Card Details</legend><view class=\"rounded-md shadow-xs\"><view class=\"relative focus-within:z-10\"><input class=\"peer rounded-b-none pe-9 shadow-none [direction:inherit]\" id=\"{{`number-${id}`}}\" /><view class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 peer-disabled:opacity-50\"><block wx:if=\"{{meta.cardType}}\">\n<svg class=\"overflow-hidden rounded-sm\" width=\"{{20}}\" />\n</block>\n<block wx:else>\n<creditcardicon size=\"{{16}}\" aria-hidden=\"true\" />\n</block></view></view><view class=\"-mt-px flex\"><view class=\"min-w-0 flex-1 focus-within:z-10\"><input class=\"rounded-e-none rounded-t-none shadow-none [direction:inherit]\" id=\"{{`expiry-${id}`}}\" /></view><view class=\"-ms-px min-w-0 flex-1 focus-within:z-10\"><input class=\"rounded-s-none rounded-t-none shadow-none [direction:inherit]\" id=\"{{`cvc-${id}`}}\" /></view></view></view><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://github.com/medipass/react-payment-inputs\" target=\"_blank\" rel=\"noopener nofollow\">React Payment Inputs\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "checkout",
          "payment",
          "credit card",
          "form"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-51",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-51",
              "path": "registry/default/components/input/input-51.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-51",
              "path": "registry/default/components/input/input-51.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-51",
              "path": "registry/default/components/input/input-51.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-51",
              "path": "registry/default/components/input/input-51.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react",
              "react-payment-inputs",
              "react-payment-inputs/images"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · Disabled state"
      },
      "categories": [
        "inputs",
        "input"
      ]
    },
    {
      "name": "input-52",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-52.tsx",
          "type": "registry:component",
          "target": "components/ui/input-52.tsx",
          "content": "'use client'\n\nimport { useId, useMemo, useState } from 'react'\nimport { Input, Label } from '@timui/react'\nimport { CheckIcon, EyeIcon, EyeOffIcon, XIcon } from 'lucide-react'\n\nexport default function Component() {\n  const id = useId()\n  const [password, setPassword] = useState('')\n  const [isVisible, setIsVisible] = useState<boolean>(false)\n\n  const toggleVisibility = () => setIsVisible((prevState) => !prevState)\n\n  const checkStrength = (pass: string) => {\n    const requirements = [\n      { regex: /.{8,}/, text: 'At least 8 characters' },\n      { regex: /[0-9]/, text: 'At least 1 number' },\n      { regex: /[a-z]/, text: 'At least 1 lowercase letter' },\n      { regex: /[A-Z]/, text: 'At least 1 uppercase letter' },\n    ]\n\n    return requirements.map((req) => ({\n      met: req.regex.test(pass),\n      text: req.text,\n    }))\n  }\n\n  const strength = checkStrength(password)\n\n  const strengthScore = useMemo(() => {\n    return strength.filter((req) => req.met).length\n  }, [strength])\n\n  const getStrengthColor = (score: number) => {\n    if (score === 0) return 'bg-border'\n    if (score <= 1) return 'bg-red-500'\n    if (score <= 2) return 'bg-orange-500'\n    if (score === 3) return 'bg-amber-500'\n    return 'bg-emerald-500'\n  }\n\n  const getStrengthText = (score: number) => {\n    if (score === 0) return 'Enter a password'\n    if (score <= 2) return 'Weak password'\n    if (score === 3) return 'Medium password'\n    return 'Strong password'\n  }\n\n  return (\n    <div>\n      {/* Password input field with toggle visibility button */}\n      <div className=\"*:not-first:mt-2\">\n        <Label htmlFor={id}>Input with password strength indicator</Label>\n        <div className=\"relative\">\n          <Input\n            id={id}\n            className=\"pe-9\"\n            placeholder=\"Password\"\n            type={isVisible ? 'text' : 'password'}\n            value={password}\n            onChange={(e) => setPassword(e.target.value)}\n            aria-describedby={`${id}-description`}\n          />\n          <button\n            className=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\"\n            type=\"button\"\n            onClick={toggleVisibility}\n            aria-label={isVisible ? 'Hide password' : 'Show password'}\n            aria-pressed={isVisible}\n            aria-controls=\"password\"\n          >\n            {isVisible ? (\n              <EyeOffIcon size={16} aria-hidden=\"true\" />\n            ) : (\n              <EyeIcon size={16} aria-hidden=\"true\" />\n            )}\n          </button>\n        </div>\n      </div>\n\n      {/* Password strength indicator */}\n      <div\n        className=\"bg-border mt-3 mb-4 h-1 w-full overflow-hidden rounded-full\"\n        role=\"progressbar\"\n        aria-valuenow={strengthScore}\n        aria-valuemin={0}\n        aria-valuemax={4}\n        aria-label=\"Password strength\"\n      >\n        <div\n          className={`h-full ${getStrengthColor(strengthScore)} transition-all duration-500 ease-out`}\n          style={{ width: `${(strengthScore / 4) * 100}%` }}\n        ></div>\n      </div>\n\n      {/* Password strength description */}\n      <p id={`${id}-description`} className=\"text-foreground mb-2 text-sm font-medium\">\n        {getStrengthText(strengthScore)}. Must contain:\n      </p>\n\n      {/* Password requirements list */}\n      <ul className=\"space-y-1.5\" aria-label=\"Password requirements\">\n        {strength.map((req, index) => (\n          <li key={index} className=\"flex items-center gap-2\">\n            {req.met ? (\n              <CheckIcon size={16} className=\"text-emerald-500\" aria-hidden=\"true\" />\n            ) : (\n              <XIcon size={16} className=\"text-muted-foreground/80\" aria-hidden=\"true\" />\n            )}\n            <span className={`text-xs ${req.met ? 'text-emerald-600' : 'text-muted-foreground'}`}>\n              {req.text}\n              <span className=\"sr-only\">\n                {req.met ? ' - Requirement met' : ' - Requirement not met'}\n              </span>\n            </span>\n          </li>\n        ))}\n      </ul>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-52.vue",
          "target": "components/ui/input-52.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, ref } from 'vue';\nimport { CheckIcon, EyeIcon, EyeOffIcon, XIcon } from 'lucide-vue-next';\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\nconst password = ref('');\nconst isVisible = ref<boolean>(false);\nconst id = 'input-52';\n\nfunction toggleVisibility() {\n  isVisible.value = !isVisible.value;\n}\n\nconst strength = computed(() => checkStrength(password.value));\nconst strengthScore = computed(() => strength.value.filter((req) => req.met).length);\n\nfunction checkStrength(pass: string) {\n  const requirements = [\n    { regex: /.{8,}/, text: 'At least 8 characters' },\n    { regex: /[0-9]/, text: 'At least 1 number' },\n    { regex: /[a-z]/, text: 'At least 1 lowercase letter' },\n    { regex: /[A-Z]/, text: 'At least 1 uppercase letter' },\n  ];\n\n  return requirements.map((req) => ({\n    met: req.regex.test(pass),\n    text: req.text,\n  }));\n}\n\nfunction getStrengthColor(score: number) {\n  if (score === 0) return 'bg-border';\n  if (score <= 1) return 'bg-red-500';\n  if (score <= 2) return 'bg-orange-500';\n  if (score === 3) return 'bg-amber-500';\n  return 'bg-emerald-500';\n}\n\nfunction getStrengthText(score: number) {\n  if (score === 0) return 'Enter a password';\n  if (score <= 2) return 'Weak password';\n  if (score === 3) return 'Medium password';\n  return 'Strong password';\n}\n</script>\n\n<template>\n  <div>\n    <div class=\"*:not-first:mt-2\">\n      <Label :htmlFor=\"id\">Input with password strength indicator</Label>\n      <div class=\"relative\">\n        <Input\n          :id=\"id\"\n          class=\"pe-9\"\n          placeholder=\"Password\"\n          :type=\"isVisible ? 'text' : 'password'\"\n          v-model=\"password\"\n          :aria-describedby=\"`${id}-description`\"\n        />\n        <button\n          class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\"\n          type=\"button\"\n          @click=\"toggleVisibility\"\n          :aria-label=\"isVisible ? 'Hide password' : 'Show password'\"\n          :aria-pressed=\"isVisible\"\n          aria-controls=\"password\"\n        >\n          <template v-if=\"isVisible\"><EyeOffIcon :size=\"16\" aria-hidden=\"true\" /></template>\n          <template v-else><EyeIcon :size=\"16\" aria-hidden=\"true\" /></template>\n        </button>\n      </div>\n    </div>\n\n    <div class=\"bg-border mt-3 mb-4 h-1 w-full overflow-hidden rounded-full\" role=\"progressbar\" :aria-valuenow=\"strengthScore\" :aria-valuemin=\"0\" :aria-valuemax=\"4\" aria-label=\"Password strength\">\n      <div :class=\"`h-full ${getStrengthColor(strengthScore)} transition-all duration-500 ease-out`\" :style=\"{ width: `${(strengthScore / 4) * 100}%` }\"></div>\n    </div>\n\n    <p :id=\"`${id}-description`\" class=\"text-foreground mb-2 text-sm font-medium\">{{ getStrengthText(strengthScore) }}. Must contain:</p>\n    <ul class=\"space-y-1.5\" aria-label=\"Password requirements\">\n      <li v-for=\"(req, index) in strength\" :key=\"index\" class=\"flex items-center gap-2\">\n        <template v-if=\"req.met\"><CheckIcon :size=\"16\" class=\"text-emerald-500\" aria-hidden=\"true\" /></template>\n        <template v-else><XIcon :size=\"16\" class=\"text-muted-foreground/80\" aria-hidden=\"true\" /></template>\n        <span :class=\"`text-xs ${req.met ? 'text-emerald-600' : 'text-muted-foreground'}`\">\n          {{ req.text }}\n          <span class=\"sr-only\">{{ req.met ? ' - Requirement met' : ' - Requirement not met' }}</span>\n        </span>\n      </li>\n    </ul>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-52.html",
          "target": "components/ui/input-52.html",
          "type": "registry:component",
          "content": "<template>\n  <div><div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Input with password strength indicator</Label><div class=\"relative\"><Input id=\"${id}\" class=\"pe-9\" placeholder=\"Password\" type=\"${isVisible ? 'text' : 'password'}\" value=\"${password}\" onchange=\"${(e) => setPassword(e.target.value)}\" aria-describedby=\"${`${id}-description`}\" /><button class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\" type=\"button\" on-click=\"${toggleVisibility}\" aria-label=\"${isVisible ? 'Hide password' : 'Show password'}\" aria-pressed=\"${isVisible}\" aria-controls=\"password\"><!-- if isVisible -->\n<EyeOffIcon size=\"${16}\" aria-hidden=\"true\" />\n<!-- else -->\n<EyeIcon size=\"${16}\" aria-hidden=\"true\" />\n<!-- endif --></button></div></div><div class=\"bg-border mt-3 mb-4 h-1 w-full overflow-hidden rounded-full\" role=\"progressbar\" aria-valuenow=\"${strengthScore}\" aria-valuemin=\"${0}\" aria-valuemax=\"${4}\" aria-label=\"Password strength\"><div class=\"${`h-full ${getStrengthColor(strengthScore)} transition-all duration-500 ease-out`}\" style=\"${{ width: `${(strengthScore / 4) * 100}%` }}\"></div></div><p id=\"${`${id}-description`}\" class=\"text-foreground mb-2 text-sm font-medium\">${getStrengthText(strengthScore)}. Must contain:\n      </p><ul class=\"space-y-1.5\" aria-label=\"Password requirements\"><!-- Loop strength -->\n<li key=\"${index}\" class=\"flex items-center gap-2\"><!-- if req.met -->\n<CheckIcon size=\"${16}\" class=\"text-emerald-500\" aria-hidden=\"true\" />\n<!-- else -->\n<XIcon size=\"${16}\" class=\"text-muted-foreground/80\" aria-hidden=\"true\" />\n<!-- endif --><span class=\"${`text-xs ${req.met ? 'text-emerald-600' : 'text-muted-foreground'}`}\">${req.text}<span class=\"sr-only\"><!-- if req.met -->\n${' - Requirement met'}\n<!-- else -->\n${' - Requirement not met'}\n<!-- endif --></span></span></li>\n<!-- End Loop --></ul></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-52.wxml",
          "target": "components/ui/input-52/input-52.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Input with password strength indicator</label><view class=\"relative\"><input id=\"{{id}}\" class=\"pe-9\" placeholder=\"Password\" type=\"{{isVisible ? 'text' : 'password'}}\" value=\"{{password}}\" onchange=\"{{(e) => setPassword(e.target.value)}}\" aria-describedby=\"{{`${id}-description`}}\" /><button class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\" type=\"button\" bindtap=\"toggleVisibility\" aria-label=\"{{isVisible ? 'Hide password' : 'Show password'}}\" aria-pressed=\"{{isVisible}}\" aria-controls=\"password\"><block wx:if=\"{{isVisible}}\">\n<eyeofficon size=\"{{16}}\" aria-hidden=\"true\" />\n</block>\n<block wx:else>\n<eyeicon size=\"{{16}}\" aria-hidden=\"true\" />\n</block></button></view></view><view class=\"bg-border mt-3 mb-4 h-1 w-full overflow-hidden rounded-full\" role=\"progressbar\" aria-valuenow=\"{{strengthScore}}\" aria-valuemin=\"{{0}}\" aria-valuemax=\"{{4}}\" aria-label=\"Password strength\"><view class=\"{{`h-full ${getStrengthColor(strengthScore)} transition-all duration-500 ease-out`}}\" style=\"{{{ width: `${(strengthScore / 4) * 100}%` }}}\"></view></view><text id=\"{{`${id}-description`}}\" class=\"text-foreground mb-2 text-sm font-medium\">{{ getStrengthText(strengthScore) }}. Must contain:\n      </text><ul class=\"space-y-1.5\" aria-label=\"Password requirements\"><li wx:for=\"{{strength}}\" wx:for-item=\"req\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{index}}\" class=\"flex items-center gap-2\"><block wx:if=\"{{req.met}}\">\n<checkicon size=\"{{16}}\" class=\"text-emerald-500\" aria-hidden=\"true\" />\n</block>\n<block wx:else>\n<xicon size=\"{{16}}\" class=\"text-muted-foreground/80\" aria-hidden=\"true\" />\n</block><text class=\"{{`text-xs ${req.met ? 'text-emerald-600' : 'text-muted-foreground'}`}}\">{{ req.text }}<text class=\"sr-only\"><block wx:if=\"{{req.met}}\">\n{{ ' - Requirement met' }}\n</block>\n<block wx:else>\n{{ ' - Requirement not met' }}\n</block></text></text></li></ul></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "password"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-52",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-52",
              "path": "registry/default/components/input/input-52.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-52",
              "path": "registry/default/components/input/input-52.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-52",
              "path": "registry/default/components/input/input-52.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-52",
              "path": "registry/default/components/input/input-52.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-53",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-53.tsx",
          "type": "registry:component",
          "target": "components/ui/input-53.tsx",
          "content": "import { useId } from 'react'\nimport { Input, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Read-only input</Label>\n      <Input\n        id={id}\n        className=\"read-only:bg-muted\"\n        defaultValue=\"This is a read-only input\"\n        readOnly\n        placeholder=\"Email\"\n        type=\"email\"\n      />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-53.vue",
          "target": "components/ui/input-53.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'input-53';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Read-only input</Label><Input :id=\"id\" class=\"read-only:bg-muted\" default-value=\"This is a read-only input\" readOnly placeholder=\"Email\" type=\"email\" /></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-53.html",
          "target": "components/ui/input-53.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Read-only input</Label><Input id=\"${id}\" class=\"read-only:bg-muted\" default-value=\"This is a read-only input\" readonly placeholder=\"Email\" type=\"email\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-53.wxml",
          "target": "components/ui/input-53/input-53.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Read-only input</label><input id=\"{{id}}\" class=\"read-only:bg-muted\" default-value=\"This is a read-only input\" readonly placeholder=\"Email\" type=\"email\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "read-only"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-53",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-53",
              "path": "registry/default/components/input/input-53.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-53",
              "path": "registry/default/components/input/input-53.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-53",
              "path": "registry/default/components/input/input-53.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-53",
              "path": "registry/default/components/input/input-53.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-54",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/tooltip.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-54.tsx",
          "type": "registry:component",
          "target": "components/ui/input-54.tsx",
          "content": "'use client'\n\nimport { useId, useRef, useState } from 'react'\nimport { cn } from '@timui/core'\nimport {\n  Input,\n  Label,\n  Tooltip,\n  TooltipContent,\n  TooltipProvider,\n  TooltipTrigger,\n} from '@timui/react'\nimport { CheckIcon, CopyIcon } from 'lucide-react'\n\nexport default function Component() {\n  const id = useId()\n  const [copied, setCopied] = useState<boolean>(false)\n  const inputRef = useRef<HTMLInputElement>(null)\n\n  const handleCopy = () => {\n    if (inputRef.current) {\n      navigator.clipboard.writeText(inputRef.current.value)\n      setCopied(true)\n      setTimeout(() => setCopied(false), 1500)\n    }\n  }\n\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Copy to clipboard</Label>\n      <div className=\"relative\">\n        <Input\n          ref={inputRef}\n          id={id}\n          className=\"pe-9\"\n          type=\"text\"\n          defaultValue=\"pnpm install origin-ui\"\n          readOnly\n        />\n        <TooltipProvider delayDuration={0}>\n          <Tooltip>\n            <TooltipTrigger asChild>\n              <button\n                onClick={handleCopy}\n                className=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed\"\n                aria-label={copied ? 'Copied' : 'Copy to clipboard'}\n                disabled={copied}\n              >\n                <div\n                  className={cn(\n                    'transition-all',\n                    copied ? 'scale-100 opacity-100' : 'scale-0 opacity-0'\n                  )}\n                >\n                  <CheckIcon className=\"stroke-emerald-500\" size={16} aria-hidden=\"true\" />\n                </div>\n                <div\n                  className={cn(\n                    'absolute transition-all',\n                    copied ? 'scale-0 opacity-0' : 'scale-100 opacity-100'\n                  )}\n                >\n                  <CopyIcon size={16} aria-hidden=\"true\" />\n                </div>\n              </button>\n            </TooltipTrigger>\n            <TooltipContent className=\"px-2 py-1 text-xs\">Copy to clipboard</TooltipContent>\n          </Tooltip>\n        </TooltipProvider>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-54.vue",
          "target": "components/ui/input-54.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { cn } from '@timui/core';\nimport { CheckIcon, CopyIcon } from 'lucide-vue-next';\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\nimport { Tooltip } from '@timui/vue';\nimport { TooltipContent } from '@timui/vue';\nimport { TooltipProvider } from '@timui/vue';\nimport { TooltipTrigger } from '@timui/vue';\n\n\n\nconst copied = ref<boolean>(false);\n\n\nconst id = 'input-54';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Copy to clipboard</Label><div class=\"relative\"><Input :ref=\"inputRef\" :id=\"id\" class=\"pe-9\" type=\"text\" default-value=\"pnpm install origin-ui\" readOnly /><TooltipProvider :delayDuration=\"0\"><Tooltip><TooltipTrigger as-child><button @click=\"handleCopy\" class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed\" :aria-label=\"copied ? 'Copied' : 'Copy to clipboard'\" :disabled=\"copied\"><div :class=\"cn(\n                    'transition-all',\n                    copied ? 'scale-100 opacity-100' : 'scale-0 opacity-0'\n                  )\"><CheckIcon class=\"stroke-emerald-500\" :size=\"16\" aria-hidden=\"true\" /></div><div :class=\"cn(\n                    'absolute transition-all',\n                    copied ? 'scale-0 opacity-0' : 'scale-100 opacity-100'\n                  )\"><CopyIcon :size=\"16\" aria-hidden=\"true\" /></div></button></TooltipTrigger><TooltipContent class=\"px-2 py-1 text-xs\">Copy to clipboard</TooltipContent></Tooltip></TooltipProvider></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-54.html",
          "target": "components/ui/input-54.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Copy to clipboard</Label><div class=\"relative\"><Input ref=\"${inputRef}\" id=\"${id}\" class=\"pe-9\" type=\"text\" default-value=\"pnpm install origin-ui\" readonly /><TooltipProvider delayduration=\"${0}\"><Tooltip><TooltipTrigger aschild><button on-click=\"${handleCopy}\" class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed\" aria-label=\"${copied ? 'Copied' : 'Copy to clipboard'}\" disabled=\"${copied}\"><div class=\"${cn(\n                    'transition-all',\n                    copied ? 'scale-100 opacity-100' : 'scale-0 opacity-0'\n                  )}\"><CheckIcon class=\"stroke-emerald-500\" size=\"${16}\" aria-hidden=\"true\" /></div><div class=\"${cn(\n                    'absolute transition-all',\n                    copied ? 'scale-0 opacity-0' : 'scale-100 opacity-100'\n                  )}\"><CopyIcon size=\"${16}\" aria-hidden=\"true\" /></div></button></TooltipTrigger><TooltipContent class=\"px-2 py-1 text-xs\">Copy to clipboard</TooltipContent></Tooltip></TooltipProvider></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-54.wxml",
          "target": "components/ui/input-54/input-54.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Copy to clipboard</label><view class=\"relative\"><input ref=\"{{inputRef}}\" id=\"{{id}}\" class=\"pe-9\" type=\"text\" default-value=\"pnpm install origin-ui\" readonly /><tooltipprovider delayduration=\"{{0}}\"><tooltip><tooltiptrigger aschild><button bindtap=\"handleCopy\" class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed\" aria-label=\"{{copied ? 'Copied' : 'Copy to clipboard'}}\" disabled=\"{{copied}}\"><view class=\"{{cn(\n                    'transition-all',\n                    copied ? 'scale-100 opacity-100' : 'scale-0 opacity-0'\n                  )}}\"><checkicon class=\"stroke-emerald-500\" size=\"{{16}}\" aria-hidden=\"true\" /></view><view class=\"{{cn(\n                    'absolute transition-all',\n                    copied ? 'scale-0 opacity-0' : 'scale-100 opacity-100'\n                  )}}\"><copyicon size=\"{{16}}\" aria-hidden=\"true\" /></view></button></tooltiptrigger><tooltipcontent class=\"px-2 py-1 text-xs\">Copy to clipboard</tooltipcontent></tooltip></tooltipprovider></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "copy"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-54",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-54",
              "path": "registry/default/components/input/input-54.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-54",
              "path": "registry/default/components/input/input-54.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-54",
              "path": "registry/default/components/input/input-54.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-54",
              "path": "registry/default/components/input/input-54.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/core",
        "@timui/react"
      ]
    },
    {
      "name": "input-55",
      "type": "registry:component",
      "dependencies": [
        "@timui/react",
        "use-mask-input"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-55.tsx",
          "type": "registry:component",
          "target": "components/ui/input-55.tsx",
          "content": "'use client'\n\nimport { useId } from 'react'\nimport { Input, Label } from '@timui/react'\nimport { withMask } from 'use-mask-input'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Input with mask</Label>\n      <Input\n        id={id}\n        placeholder=\"AB12 CDE\"\n        type=\"text\"\n        ref={withMask('AA99 AAA', {\n          placeholder: '',\n          showMaskOnHover: false,\n        })}\n      />\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Built with{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://github.com/eduardoborges/use-mask-input\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          use-mask-input\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-55.vue",
          "target": "components/ui/input-55.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { Input, Label } from '@timui/vue'\n\nconst id = 'input-55'\nconst value = ref('')\n\nconst isLetter = (char: string) => /^[A-Z]$/.test(char)\nconst isDigit = (char: string) => /^\\d$/.test(char)\n\nfunction formatMaskedValue(input: string): string {\n  const raw = input.toUpperCase().replace(/[^A-Z0-9]/g, '')\n  let cursor = 0\n\n  const consume = (matcher: (char: string) => boolean) => {\n    while (cursor < raw.length) {\n      const char = raw[cursor]\n      cursor += 1\n      if (char && matcher(char)) return char\n    }\n    return ''\n  }\n\n  const p1 = consume(isLetter)\n  if (!p1) return ''\n  const p2 = consume(isLetter)\n  if (!p2) return p1\n  const d1 = consume(isDigit)\n  if (!d1) return `${p1}${p2}`\n  const d2 = consume(isDigit)\n  if (!d2) return `${p1}${p2}${d1}`\n  const l1 = consume(isLetter)\n  if (!l1) return `${p1}${p2}${d1}${d2}`\n  const l2 = consume(isLetter)\n  if (!l2) return `${p1}${p2}${d1}${d2} ${l1}`\n  const l3 = consume(isLetter)\n  if (!l3) return `${p1}${p2}${d1}${d2} ${l1}${l2}`\n  return `${p1}${p2}${d1}${d2} ${l1}${l2}${l3}`\n}\n\nfunction handleValueChange(nextValue: string | number) {\n  value.value = formatMaskedValue(String(nextValue))\n}\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\">\n    <Label :htmlFor=\"id\">Input with mask</Label>\n    <Input\n      :id=\"id\"\n      v-model=\"value\"\n      placeholder=\"AB12 CDE\"\n      type=\"text\"\n      @update:model-value=\"handleValueChange\"\n    />\n    <p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n      Built with native mask formatting\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-55.html",
          "target": "components/ui/input-55.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Input with mask</Label><Input id=\"${id}\" placeholder=\"AB12 CDE\" type=\"text\" ref=\"${withMask('AA99 AAA', {\n          placeholder: '',\n          showMaskOnHover: false,\n        })}\" /><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with${' '}<a class=\"hover:text-foreground underline\" href=\"https://github.com/eduardoborges/use-mask-input\" target=\"_blank\" rel=\"noopener nofollow\">use-mask-input\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-55.wxml",
          "target": "components/ui/input-55/input-55.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Input with mask</label><input id=\"{{id}}\" placeholder=\"AB12 CDE\" type=\"text\" ref=\"{{withMask('AA99 AAA', {\n          placeholder: '',\n          showMaskOnHover: false,\n        })}}\" /><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://github.com/eduardoborges/use-mask-input\" target=\"_blank\" rel=\"noopener nofollow\">use-mask-input\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "mask"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-55",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-55",
              "path": "registry/default/components/input/input-55.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-55",
              "path": "registry/default/components/input/input-55.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-55",
              "path": "registry/default/components/input/input-55.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-55",
              "path": "registry/default/components/input/input-55.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react",
              "use-mask-input"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ]
    },
    {
      "name": "input-56",
      "type": "registry:component",
      "dependencies": [
        "@timui/react",
        "use-mask-input"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-56.tsx",
          "type": "registry:component",
          "target": "components/ui/input-56.tsx",
          "content": "'use client'\n\nimport { useId } from 'react'\nimport { Input, Label } from '@timui/react'\nimport { withMask } from 'use-mask-input'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Timestamp</Label>\n      <Input\n        id={id}\n        placeholder=\"00:00:00\"\n        type=\"text\"\n        ref={withMask('99:99:99', {\n          placeholder: '-',\n          showMaskOnHover: false,\n        })}\n      />\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Built with{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://github.com/eduardoborges/use-mask-input\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          use-mask-input\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-56.vue",
          "target": "components/ui/input-56.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { Input, Label } from '@timui/vue'\n\nconst id = 'input-56'\nconst value = ref('')\n\nfunction formatTimestamp(input: string): string {\n  const raw = input.replace(/\\D/g, '').slice(0, 6)\n  if (raw.length <= 2) return raw\n  if (raw.length <= 4) return `${raw.slice(0, 2)}:${raw.slice(2)}`\n  return `${raw.slice(0, 2)}:${raw.slice(2, 4)}:${raw.slice(4, 6)}`\n}\n\nfunction handleValueChange(nextValue: string | number) {\n  value.value = formatTimestamp(String(nextValue))\n}\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\">\n    <Label :htmlFor=\"id\">Timestamp</Label>\n    <Input\n      :id=\"id\"\n      v-model=\"value\"\n      placeholder=\"00:00:00\"\n      type=\"text\"\n      @update:model-value=\"handleValueChange\"\n    />\n    <p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n      Built with native mask formatting\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-56.html",
          "target": "components/ui/input-56.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Timestamp</Label><Input id=\"${id}\" placeholder=\"00:00:00\" type=\"text\" ref=\"${withMask('99:99:99', {\n          placeholder: '-',\n          showMaskOnHover: false,\n        })}\" /><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with${' '}<a class=\"hover:text-foreground underline\" href=\"https://github.com/eduardoborges/use-mask-input\" target=\"_blank\" rel=\"noopener nofollow\">use-mask-input\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-56.wxml",
          "target": "components/ui/input-56/input-56.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Timestamp</label><input id=\"{{id}}\" placeholder=\"00:00:00\" type=\"text\" ref=\"{{withMask('99:99:99', {\n          placeholder: '-',\n          showMaskOnHover: false,\n        })}}\" /><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://github.com/eduardoborges/use-mask-input\" target=\"_blank\" rel=\"noopener nofollow\">use-mask-input\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "mask",
          "time"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-56",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-56",
              "path": "registry/default/components/input/input-56.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-56",
              "path": "registry/default/components/input/input-56.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-56",
              "path": "registry/default/components/input/input-56.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-56",
              "path": "registry/default/components/input/input-56.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react",
              "use-mask-input"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ]
    },
    {
      "name": "input-58",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "tags-input"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-58.tsx",
          "type": "registry:component",
          "target": "components/ui/input-58.tsx",
          "content": "import { useId, useState } from 'react'\nimport {\n  Label,\n  TagsInput,\n  TagsInputClearTrigger,\n  TagsInputControl,\n  TagsInputInput,\n  TagsInputItem,\n} from '@timui/react'\n\nconst defaultTags = ['Sport', 'Coding', 'Travel']\n\nexport default function Component() {\n  const id = useId()\n  const [value, setValue] = useState(defaultTags)\n\n  return (\n    <div className=\"flex flex-col gap-2\">\n      <Label htmlFor={id}>Input with tags</Label>\n      <TagsInput value={value} onValueChange={(details) => setValue(details.value)}>\n        <TagsInputControl>\n          {value.map((tag, index) => (\n            <TagsInputItem key={index} index={index} value={tag} />\n          ))}\n          <TagsInputInput placeholder=\"Add a tag\" />\n        </TagsInputControl>\n        <TagsInputClearTrigger />\n      </TagsInput>\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Built with <span className=\"text-foreground\">TimUI TagsInput</span>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-58.vue",
          "target": "components/ui/input-58.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Label } from '@timui/vue';\nimport { TagsInput } from '@timui/vue';\nimport { TagsInputClearTrigger } from '@timui/vue';\nimport { TagsInputControl } from '@timui/vue';\nimport { TagsInputInput } from '@timui/vue';\nimport { TagsInputItem } from '@timui/vue';\n\nconst defaultTags = ['Sport', 'Coding', 'Travel'];\n\nconst value = ref(defaultTags);\n\n\nfunction setValue(next: typeof value.value | ((prev: typeof value.value) => typeof value.value)) {\n  value.value = typeof next === 'function'\n    ? (next as (prev: typeof value.value) => typeof value.value)(value.value)\n    : next;\n}\n\n\nconst id = 'input-58';\n\n</script>\n\n<template>\n  <div class=\"flex flex-col gap-2\"><Label :htmlFor=\"id\">Input with tags</Label><TagsInput :value=\"value\" @update:modelValue=\"setValue\"><TagsInputControl><TagsInputItem v-for=\"(tag, index) in value\" :key=\"index\" :index=\"index\" :value=\"tag\" /><TagsInputInput placeholder=\"Add a tag\" /></TagsInputControl><TagsInputClearTrigger /></TagsInput><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with <span class=\"text-foreground\">TimUI TagsInput</span></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-58.html",
          "target": "components/ui/input-58.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex flex-col gap-2\"><Label htmlfor=\"${id}\">Input with tags</Label><TagsInput value=\"${value}\" on-value-change=\"${(details) => setValue(details.value)}\"><TagsInputControl><!-- Loop value -->\n<TagsInputItem key=\"${index}\" index=\"${index}\" value=\"${tag}\" />\n<!-- End Loop --><TagsInputInput placeholder=\"Add a tag\" /></TagsInputControl><TagsInputClearTrigger /></TagsInput><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with <span class=\"text-foreground\">TimUI TagsInput</span></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-58.wxml",
          "target": "components/ui/input-58/input-58.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex flex-col gap-2\"><label htmlfor=\"{{id}}\">Input with tags</label><tagsinput value=\"{{value}}\" bindchange=\"setValue(details.value)\"><tagsinputcontrol><tagsinputitem wx:for=\"{{value}}\" wx:for-item=\"tag\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{index}}\" index=\"{{index}}\" value=\"{{tag}}\" /><tagsinputinput placeholder=\"Add a tag\" /></tagsinputcontrol><tagsinputcleartrigger /></tagsinput><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with <text class=\"text-foreground\">TimUI TagsInput</text></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "tag",
          "emblor"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-58",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-58",
              "path": "registry/default/components/input/input-58.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-58",
              "path": "registry/default/components/input/input-58.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-58",
              "path": "registry/default/components/input/input-58.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-58",
              "path": "registry/default/components/input/input-58.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-59",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "tags-input"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-59.tsx",
          "type": "registry:component",
          "target": "components/ui/input-59.tsx",
          "content": "import { useId, useState } from 'react'\nimport { Label, TagsInput, TagsInputControl, TagsInputInput, TagsInputItem } from '@timui/react'\n\nconst defaultTags = ['Red']\n\nexport default function Component() {\n  const id = useId()\n  const [value, setValue] = useState(defaultTags)\n\n  return (\n    <div className=\"flex flex-col gap-2\">\n      <Label htmlFor={id}>Input with inner tags</Label>\n      <TagsInput value={value} onValueChange={(details) => setValue(details.value)}>\n        <TagsInputControl>\n          {value.map((tag, index) => (\n            <TagsInputItem key={index} index={index} value={tag} />\n          ))}\n          <TagsInputInput placeholder=\"Add a tag\" />\n        </TagsInputControl>\n      </TagsInput>\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Built with <span className=\"text-foreground\">TimUI TagsInput</span>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-59.vue",
          "target": "components/ui/input-59.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Label } from '@timui/vue';\nimport { TagsInput } from '@timui/vue';\nimport { TagsInputControl } from '@timui/vue';\nimport { TagsInputInput } from '@timui/vue';\nimport { TagsInputItem } from '@timui/vue';\n\nconst defaultTags = ['Red'];\n\nconst value = ref(defaultTags);\n\n\nfunction setValue(next: typeof value.value | ((prev: typeof value.value) => typeof value.value)) {\n  value.value = typeof next === 'function'\n    ? (next as (prev: typeof value.value) => typeof value.value)(value.value)\n    : next;\n}\n\n\nconst id = 'input-59';\n\n</script>\n\n<template>\n  <div class=\"flex flex-col gap-2\"><Label :htmlFor=\"id\">Input with inner tags</Label><TagsInput :value=\"value\" @update:modelValue=\"setValue\"><TagsInputControl><TagsInputItem v-for=\"(tag, index) in value\" :key=\"index\" :index=\"index\" :value=\"tag\" /><TagsInputInput placeholder=\"Add a tag\" /></TagsInputControl></TagsInput><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with <span class=\"text-foreground\">TimUI TagsInput</span></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-59.html",
          "target": "components/ui/input-59.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex flex-col gap-2\"><Label htmlfor=\"${id}\">Input with inner tags</Label><TagsInput value=\"${value}\" on-value-change=\"${(details) => setValue(details.value)}\"><TagsInputControl><!-- Loop value -->\n<TagsInputItem key=\"${index}\" index=\"${index}\" value=\"${tag}\" />\n<!-- End Loop --><TagsInputInput placeholder=\"Add a tag\" /></TagsInputControl></TagsInput><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with <span class=\"text-foreground\">TimUI TagsInput</span></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-59.wxml",
          "target": "components/ui/input-59/input-59.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex flex-col gap-2\"><label htmlfor=\"{{id}}\">Input with inner tags</label><tagsinput value=\"{{value}}\" bindchange=\"setValue(details.value)\"><tagsinputcontrol><tagsinputitem wx:for=\"{{value}}\" wx:for-item=\"tag\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{index}}\" index=\"{{index}}\" value=\"{{tag}}\" /><tagsinputinput placeholder=\"Add a tag\" /></tagsinputcontrol></tagsinput><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with <text class=\"text-foreground\">TimUI TagsInput</text></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "tag",
          "emblor"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-59",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-59",
              "path": "registry/default/components/input/input-59.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-59",
              "path": "registry/default/components/input/input-59.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-59",
              "path": "registry/default/components/input/input-59.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-59",
              "path": "registry/default/components/input/input-59.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "input-46",
      "type": "registry:component",
      "dependencies": [
        "@timui/core",
        "@timui/react",
        "input-otp"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-46.tsx",
          "type": "registry:component",
          "target": "components/ui/input-46.tsx",
          "content": "'use client'\n\nimport { useId } from 'react'\nimport { cn } from '@timui/core'\nimport { Label } from '@timui/react'\nimport { OTPInput, SlotProps } from 'input-otp'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>OTP input (spaced)</Label>\n      <OTPInput\n        id={id}\n        containerClassName=\"flex items-center gap-3 has-disabled:opacity-50\"\n        maxLength={4}\n        render={({ slots }) => (\n          <div className=\"flex gap-2\">\n            {slots.map((slot, idx) => (\n              <Slot key={idx} {...slot} />\n            ))}\n          </div>\n        )}\n      />\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Built with{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://github.com/guilhermerodz/input-otp\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          Input OTP\n        </a>\n      </p>\n    </div>\n  )\n}\n\nfunction Slot(props: SlotProps) {\n  return (\n    <div\n      className={cn(\n        'border-input bg-background text-foreground flex size-9 items-center justify-center rounded-md border font-medium shadow-xs transition-[color,box-shadow]',\n        { 'border-ring ring-ring/50 z-10 ring-[3px]': props.isActive }\n      )}\n    >\n      {props.char !== null && <div>{props.char}</div>}\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-46.vue",
          "target": "components/ui/input-46.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { Label } from '@timui/vue'\n\nconst id = 'input-46'\nconst digits = ref(['', '', '', ''])\nconst inputRefs = ref<Array<HTMLInputElement | null>>([])\n\nfunction setInputRef(index: number, el: HTMLInputElement | null) {\n  inputRefs.value[index] = el\n}\n\nfunction handleInput(index: number, event: Event) {\n  const target = event.target as HTMLInputElement\n  const value = target.value.replace(/\\D/g, '').slice(-1)\n  digits.value[index] = value\n  target.value = value\n  if (value && index < digits.value.length - 1) {\n    inputRefs.value[index + 1]?.focus()\n  }\n}\n\nfunction handleKeydown(index: number, event: KeyboardEvent) {\n  if (event.key === 'Backspace' && !digits.value[index] && index > 0) {\n    inputRefs.value[index - 1]?.focus()\n  }\n}\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\">\n    <Label :htmlFor=\"id\">OTP input (spaced)</Label>\n    <div class=\"flex gap-2\">\n      <input\n        v-for=\"(_, index) in digits\"\n        :key=\"`${id}-${index}`\"\n        :id=\"index === 0 ? id : `${id}-${index}`\"\n        :ref=\"(el) => setInputRef(index, el as HTMLInputElement | null)\"\n        class=\"border-input bg-background text-foreground flex size-9 items-center justify-center rounded-md border text-center font-medium shadow-xs transition-[color,box-shadow] focus:z-10 focus:outline-none focus:ring-2 focus:ring-ring/50\"\n        inputmode=\"numeric\"\n        pattern=\"[0-9]*\"\n        maxlength=\"1\"\n        autocomplete=\"one-time-code\"\n        @input=\"(event) => handleInput(index, event)\"\n        @keydown=\"(event) => handleKeydown(index, event)\"\n      />\n    </div>\n    <p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n      Built with\n      <a\n        class=\"hover:text-foreground underline\"\n        href=\"https://github.com/guilhermerodz/input-otp\"\n        target=\"_blank\"\n        rel=\"noopener nofollow\"\n      >\n        Input OTP\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-46.html",
          "target": "components/ui/input-46.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">OTP input (spaced)</Label><OTPInput id=\"${id}\" containerclassname=\"flex items-center gap-3 has-disabled:opacity-50\" maxlength=\"${4}\" render=\"${({ slots }) => (\n          <div className=\"flex gap-2\">\n            {slots.map((slot, idx) => (\n              <Slot key={idx} {...slot} />\n            ))}\n          </div>\n        )}\" /><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with${' '}<a class=\"hover:text-foreground underline\" href=\"https://github.com/guilhermerodz/input-otp\" target=\"_blank\" rel=\"noopener nofollow\">Input OTP\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-46.wxml",
          "target": "components/ui/input-46/input-46.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">OTP input (spaced)</label><otpinput id=\"{{id}}\" containerclassname=\"flex items-center gap-3 has-disabled:opacity-50\" maxlength=\"{{4}}\" render=\"{{({ slots }) => (\n          <div className=\"flex gap-2\">\n            {slots.map((slot, idx) => (\n              <Slot key={idx} {...slot} />\n            ))}\n          </div>\n        )}}\" /><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://github.com/guilhermerodz/input-otp\" target=\"_blank\" rel=\"noopener nofollow\">Input OTP\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "otp"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-46",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-46",
              "path": "registry/default/components/input/input-46.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-46",
              "path": "registry/default/components/input/input-46.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-46",
              "path": "registry/default/components/input/input-46.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-46",
              "path": "registry/default/components/input/input-46.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@timui/react",
              "input-otp"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ]
    },
    {
      "name": "textarea-01",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/textarea.json"
      ],
      "files": [
        {
          "path": "registry/default/components/textarea/textarea-01.tsx",
          "type": "registry:component",
          "target": "components/ui/textarea-01.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Textarea } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Simple textarea</Label>\n      <Textarea id={id} placeholder=\"Leave a comment\" />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-01.vue",
          "target": "components/ui/textarea-01.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Textarea } from '@timui/vue';\n\n\n\n\n\nconst id = 'textarea-01';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Simple textarea</Label><Textarea :id=\"id\" placeholder=\"Leave a comment\" /></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-01.html",
          "target": "components/ui/textarea-01.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Simple textarea</Label><Textarea id=\"${id}\" placeholder=\"Leave a comment\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/textarea/textarea-01.wxml",
          "target": "components/ui/textarea-01/textarea-01.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Simple textarea</label><textarea id=\"{{id}}\" placeholder=\"Leave a comment\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "textarea"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "textarea-01",
          "group": "textarea",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "textarea-01",
              "path": "registry/default/components/textarea/textarea-01.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "textarea-01",
              "path": "registry/default/components/textarea/textarea-01.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "textarea-01",
              "path": "registry/default/components/textarea/textarea-01.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "textarea-01",
              "path": "registry/default/components/textarea/textarea-01.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "textarea",
        "title": "Textarea · Simple textarea"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "textarea"
      ]
    },
    {
      "name": "textarea-02",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/textarea.json"
      ],
      "files": [
        {
          "path": "registry/default/components/textarea/textarea-02.tsx",
          "type": "registry:component",
          "target": "components/ui/textarea-02.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Textarea } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>\n        Required textarea <span className=\"text-destructive\">*</span>\n      </Label>\n      <Textarea id={id} placeholder=\"Leave a message\" required />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-02.vue",
          "target": "components/ui/textarea-02.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Textarea } from '@timui/vue';\n\n\n\n\n\nconst id = 'textarea-02';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Required textarea <span class=\"text-destructive\">*</span></Label><Textarea :id=\"id\" placeholder=\"Leave a message\" required /></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-02.html",
          "target": "components/ui/textarea-02.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Required textarea <span class=\"text-destructive\">*</span></Label><Textarea id=\"${id}\" placeholder=\"Leave a message\" required /></div>\n</template>"
        },
        {
          "path": "registry/default/components/textarea/textarea-02.wxml",
          "target": "components/ui/textarea-02/textarea-02.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Required textarea <text class=\"text-destructive\">*</text></label><textarea id=\"{{id}}\" placeholder=\"Leave a message\" required /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "textarea",
          "required"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "textarea-02",
          "group": "textarea",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "textarea-02",
              "path": "registry/default/components/textarea/textarea-02.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "textarea-02",
              "path": "registry/default/components/textarea/textarea-02.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "textarea-02",
              "path": "registry/default/components/textarea/textarea-02.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "textarea-02",
              "path": "registry/default/components/textarea/textarea-02.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "textarea",
        "title": "Textarea · Destructive Variant"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "textarea"
      ]
    },
    {
      "name": "textarea-03",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/textarea.json"
      ],
      "files": [
        {
          "path": "registry/default/components/textarea/textarea-03.tsx",
          "type": "registry:component",
          "target": "components/ui/textarea-03.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Textarea } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Textarea with helper text</Label>\n      <Textarea id={id} placeholder=\"Leave a comment\" />\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Please add as many details as you can\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-03.vue",
          "target": "components/ui/textarea-03.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Textarea } from '@timui/vue';\n\n\n\n\n\nconst id = 'textarea-03';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Textarea with helper text</Label><Textarea :id=\"id\" placeholder=\"Leave a comment\" /><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Please add as many details as you can\n      </p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-03.html",
          "target": "components/ui/textarea-03.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Textarea with helper text</Label><Textarea id=\"${id}\" placeholder=\"Leave a comment\" /><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Please add as many details as you can\n      </p></div>\n</template>"
        },
        {
          "path": "registry/default/components/textarea/textarea-03.wxml",
          "target": "components/ui/textarea-03/textarea-03.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Textarea with helper text</label><textarea id=\"{{id}}\" placeholder=\"Leave a comment\" /><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Please add as many details as you can\n      </text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "textarea",
          "helper"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "textarea-03",
          "group": "textarea",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "textarea-03",
              "path": "registry/default/components/textarea/textarea-03.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "textarea-03",
              "path": "registry/default/components/textarea/textarea-03.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "textarea-03",
              "path": "registry/default/components/textarea/textarea-03.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "textarea-03",
              "path": "registry/default/components/textarea/textarea-03.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "textarea",
        "title": "Textarea · Textarea with helper text"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "textarea"
      ]
    },
    {
      "name": "textarea-04",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/textarea.json"
      ],
      "files": [
        {
          "path": "registry/default/components/textarea/textarea-04.tsx",
          "type": "registry:component",
          "target": "components/ui/textarea-04.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Textarea } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <div className=\"flex items-center justify-between gap-1\">\n        <Label htmlFor={id} className=\"leading-6\">\n          Textarea with hint\n        </Label>\n        <span className=\"text-muted-foreground text-sm\">Optional</span>\n      </div>\n      <Textarea id={id} placeholder=\"Leave a comment\" />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-04.vue",
          "target": "components/ui/textarea-04.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Textarea } from '@timui/vue';\n\n\n\n\n\nconst id = 'textarea-04';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><div class=\"flex items-center justify-between gap-1\"><Label :htmlFor=\"id\" class=\"leading-6\">Textarea with hint\n        </Label><span class=\"text-muted-foreground text-sm\">Optional</span></div><Textarea :id=\"id\" placeholder=\"Leave a comment\" /></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-04.html",
          "target": "components/ui/textarea-04.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><div class=\"flex items-center justify-between gap-1\"><Label htmlfor=\"${id}\" class=\"leading-6\">Textarea with hint\n        </Label><span class=\"text-muted-foreground text-sm\">Optional</span></div><Textarea id=\"${id}\" placeholder=\"Leave a comment\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/textarea/textarea-04.wxml",
          "target": "components/ui/textarea-04/textarea-04.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><view class=\"flex items-center justify-between gap-1\"><label htmlfor=\"{{id}}\" class=\"leading-6\">Textarea with hint\n        </label><text class=\"text-muted-foreground text-sm\">Optional</text></view><textarea id=\"{{id}}\" placeholder=\"Leave a comment\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "textarea",
          "hint"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "textarea-04",
          "group": "textarea",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "textarea-04",
              "path": "registry/default/components/textarea/textarea-04.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "textarea-04",
              "path": "registry/default/components/textarea/textarea-04.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "textarea-04",
              "path": "registry/default/components/textarea/textarea-04.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "textarea-04",
              "path": "registry/default/components/textarea/textarea-04.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "textarea",
        "title": "Textarea · Textarea with hint"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "textarea"
      ]
    },
    {
      "name": "textarea-05",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/textarea.json"
      ],
      "files": [
        {
          "path": "registry/default/components/textarea/textarea-05.tsx",
          "type": "registry:component",
          "target": "components/ui/textarea-05.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Textarea } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"[--ring:var(--color-indigo-300)] *:not-first:mt-2 in-[.dark]:[--ring:var(--color-indigo-900)]\">\n      <Label htmlFor={id}>Textarea with colored border and ring</Label>\n      <Textarea id={id} placeholder=\"Leave a comment\" />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-05.vue",
          "target": "components/ui/textarea-05.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Textarea } from '@timui/vue';\n\n\n\n\n\nconst id = 'textarea-05';\n\n</script>\n\n<template>\n  <div class=\"[--ring:var(--color-indigo-300)] *:not-first:mt-2 in-[.dark]:[--ring:var(--color-indigo-900)]\"><Label :htmlFor=\"id\">Textarea with colored border and ring</Label><Textarea :id=\"id\" placeholder=\"Leave a comment\" /></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-05.html",
          "target": "components/ui/textarea-05.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"[--ring:var(--color-indigo-300)] *:not-first:mt-2 in-[.dark]:[--ring:var(--color-indigo-900)]\"><Label htmlfor=\"${id}\">Textarea with colored border and ring</Label><Textarea id=\"${id}\" placeholder=\"Leave a comment\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/textarea/textarea-05.wxml",
          "target": "components/ui/textarea-05/textarea-05.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"[--ring:var(--color-indigo-300)] *:not-first:mt-2 in-[.dark]:[--ring:var(--color-indigo-900)]\"><label htmlfor=\"{{id}}\">Textarea with colored border and ring</label><textarea id=\"{{id}}\" placeholder=\"Leave a comment\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "textarea"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "textarea-05",
          "group": "textarea",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "textarea-05",
              "path": "registry/default/components/textarea/textarea-05.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "textarea-05",
              "path": "registry/default/components/textarea/textarea-05.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "textarea-05",
              "path": "registry/default/components/textarea/textarea-05.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "textarea-05",
              "path": "registry/default/components/textarea/textarea-05.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "textarea",
        "title": "Textarea · Textarea with colored border and ring"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "textarea"
      ]
    },
    {
      "name": "textarea-06",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/textarea.json"
      ],
      "files": [
        {
          "path": "registry/default/components/textarea/textarea-06.tsx",
          "type": "registry:component",
          "target": "components/ui/textarea-06.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Textarea } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Textarea with error</Label>\n      <Textarea id={id} placeholder=\"Leave a comment\" defaultValue=\"Hello!\" aria-invalid />\n      <p className=\"text-destructive mt-2 text-xs\" role=\"alert\" aria-live=\"polite\">\n        Message should be at least 10 characters\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-06.vue",
          "target": "components/ui/textarea-06.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Textarea } from '@timui/vue';\n\n\n\n\n\nconst id = 'textarea-06';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Textarea with error</Label><Textarea :id=\"id\" placeholder=\"Leave a comment\" default-value=\"Hello!\" aria-invalid /><p class=\"text-destructive mt-2 text-xs\" role=\"alert\" aria-live=\"polite\">Message should be at least 10 characters\n      </p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-06.html",
          "target": "components/ui/textarea-06.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Textarea with error</Label><Textarea id=\"${id}\" placeholder=\"Leave a comment\" default-value=\"Hello!\" aria-invalid /><p class=\"text-destructive mt-2 text-xs\" role=\"alert\" aria-live=\"polite\">Message should be at least 10 characters\n      </p></div>\n</template>"
        },
        {
          "path": "registry/default/components/textarea/textarea-06.wxml",
          "target": "components/ui/textarea-06/textarea-06.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Textarea with error</label><textarea id=\"{{id}}\" placeholder=\"Leave a comment\" default-value=\"Hello!\" aria-invalid /><text class=\"text-destructive mt-2 text-xs\" role=\"alert\" aria-live=\"polite\">Message should be at least 10 characters\n      </text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "textarea",
          "error"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "textarea-06",
          "group": "textarea",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "textarea-06",
              "path": "registry/default/components/textarea/textarea-06.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "textarea-06",
              "path": "registry/default/components/textarea/textarea-06.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "textarea-06",
              "path": "registry/default/components/textarea/textarea-06.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "textarea-06",
              "path": "registry/default/components/textarea/textarea-06.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "textarea",
        "title": "Textarea · Textarea with error"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "textarea"
      ]
    },
    {
      "name": "textarea-07",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/textarea.json"
      ],
      "files": [
        {
          "path": "registry/default/components/textarea/textarea-07.tsx",
          "type": "registry:component",
          "target": "components/ui/textarea-07.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Textarea } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Textarea with gray background</Label>\n      <Textarea\n        id={id}\n        className=\"bg-muted border-transparent shadow-none\"\n        placeholder=\"Leave a comment\"\n      />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-07.vue",
          "target": "components/ui/textarea-07.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Textarea } from '@timui/vue';\n\n\n\n\n\nconst id = 'textarea-07';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Textarea with gray background</Label><Textarea :id=\"id\" class=\"bg-muted border-transparent shadow-none\" placeholder=\"Leave a comment\" /></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-07.html",
          "target": "components/ui/textarea-07.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Textarea with gray background</Label><Textarea id=\"${id}\" class=\"bg-muted border-transparent shadow-none\" placeholder=\"Leave a comment\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/textarea/textarea-07.wxml",
          "target": "components/ui/textarea-07/textarea-07.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Textarea with gray background</label><textarea id=\"{{id}}\" class=\"bg-muted border-transparent shadow-none\" placeholder=\"Leave a comment\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "textarea"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "textarea-07",
          "group": "textarea",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "textarea-07",
              "path": "registry/default/components/textarea/textarea-07.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "textarea-07",
              "path": "registry/default/components/textarea/textarea-07.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "textarea-07",
              "path": "registry/default/components/textarea/textarea-07.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "textarea-07",
              "path": "registry/default/components/textarea/textarea-07.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "textarea",
        "title": "Textarea · Textarea with gray background"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "textarea"
      ]
    },
    {
      "name": "textarea-08",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/textarea.json"
      ],
      "files": [
        {
          "path": "registry/default/components/textarea/textarea-08.tsx",
          "type": "registry:component",
          "target": "components/ui/textarea-08.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Textarea } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Shorter textarea</Label>\n      <Textarea id={id} className=\"min-h-0\" placeholder=\"Leave a comment\" rows={2} />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-08.vue",
          "target": "components/ui/textarea-08.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Textarea } from '@timui/vue';\n\n\n\n\n\nconst id = 'textarea-08';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Shorter textarea</Label><Textarea :id=\"id\" class=\"min-h-0\" placeholder=\"Leave a comment\" :rows=\"2\" /></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-08.html",
          "target": "components/ui/textarea-08.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Shorter textarea</Label><Textarea id=\"${id}\" class=\"min-h-0\" placeholder=\"Leave a comment\" rows=\"${2}\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/textarea/textarea-08.wxml",
          "target": "components/ui/textarea-08/textarea-08.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Shorter textarea</label><textarea id=\"{{id}}\" class=\"min-h-0\" placeholder=\"Leave a comment\" rows=\"{{2}}\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "textarea"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "textarea-08",
          "group": "textarea",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "textarea-08",
              "path": "registry/default/components/textarea/textarea-08.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "textarea-08",
              "path": "registry/default/components/textarea/textarea-08.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "textarea-08",
              "path": "registry/default/components/textarea/textarea-08.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "textarea-08",
              "path": "registry/default/components/textarea/textarea-08.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "textarea",
        "title": "Textarea · Shorter textarea"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "textarea"
      ]
    },
    {
      "name": "textarea-09",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/textarea.json"
      ],
      "files": [
        {
          "path": "registry/default/components/textarea/textarea-09.tsx",
          "type": "registry:component",
          "target": "components/ui/textarea-09.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Textarea } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Disabled textarea</Label>\n      <Textarea id={id} disabled placeholder=\"Leave a comment\" />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-09.vue",
          "target": "components/ui/textarea-09.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Textarea } from '@timui/vue';\n\n\n\n\n\nconst id = 'textarea-09';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Disabled textarea</Label><Textarea :id=\"id\" disabled placeholder=\"Leave a comment\" /></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-09.html",
          "target": "components/ui/textarea-09.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Disabled textarea</Label><Textarea id=\"${id}\" disabled placeholder=\"Leave a comment\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/textarea/textarea-09.wxml",
          "target": "components/ui/textarea-09/textarea-09.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Disabled textarea</label><textarea id=\"{{id}}\" disabled placeholder=\"Leave a comment\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "textarea",
          "disabled"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "textarea-09",
          "group": "textarea",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "textarea-09",
              "path": "registry/default/components/textarea/textarea-09.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "textarea-09",
              "path": "registry/default/components/textarea/textarea-09.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "textarea-09",
              "path": "registry/default/components/textarea/textarea-09.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "textarea-09",
              "path": "registry/default/components/textarea/textarea-09.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "textarea",
        "title": "Textarea · Disabled textarea"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "textarea"
      ]
    },
    {
      "name": "textarea-10",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/textarea.json"
      ],
      "files": [
        {
          "path": "registry/default/components/textarea/textarea-10.tsx",
          "type": "registry:component",
          "target": "components/ui/textarea-10.tsx",
          "content": "import { useId } from 'react'\nimport { Button, Label, Textarea } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Textarea with left button</Label>\n      <Textarea id={id} placeholder=\"Leave a comment\" />\n      <Button variant=\"outline\">Send</Button>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-10.vue",
          "target": "components/ui/textarea-10.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\nimport { Label } from '@timui/vue';\nimport { Textarea } from '@timui/vue';\n\n\n\n\n\nconst id = 'textarea-10';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Textarea with left button</Label><Textarea :id=\"id\" placeholder=\"Leave a comment\" /><Button variant=\"outline\">Send</Button></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-10.html",
          "target": "components/ui/textarea-10.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Textarea with left button</Label><Textarea id=\"${id}\" placeholder=\"Leave a comment\" /><Button variant=\"outline\">Send</Button></div>\n</template>"
        },
        {
          "path": "registry/default/components/textarea/textarea-10.wxml",
          "target": "components/ui/textarea-10/textarea-10.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Textarea with left button</label><textarea id=\"{{id}}\" placeholder=\"Leave a comment\" /><button variant=\"outline\">Send</button></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "textarea",
          "button"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "textarea-10",
          "group": "textarea",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "textarea-10",
              "path": "registry/default/components/textarea/textarea-10.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "textarea-10",
              "path": "registry/default/components/textarea/textarea-10.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "textarea-10",
              "path": "registry/default/components/textarea/textarea-10.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "textarea-10",
              "path": "registry/default/components/textarea/textarea-10.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "textarea",
        "title": "Textarea · Textarea with left button"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "textarea"
      ]
    },
    {
      "name": "textarea-11",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/textarea.json"
      ],
      "files": [
        {
          "path": "registry/default/components/textarea/textarea-11.tsx",
          "type": "registry:component",
          "target": "components/ui/textarea-11.tsx",
          "content": "import { useId } from 'react'\nimport { Button, Label, Textarea } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Textarea with right button</Label>\n      <Textarea id={id} placeholder=\"Leave a comment\" />\n      <div className=\"flex justify-end\">\n        <Button variant=\"outline\">Send</Button>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-11.vue",
          "target": "components/ui/textarea-11.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\nimport { Label } from '@timui/vue';\nimport { Textarea } from '@timui/vue';\n\n\n\n\n\nconst id = 'textarea-11';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Textarea with right button</Label><Textarea :id=\"id\" placeholder=\"Leave a comment\" /><div class=\"flex justify-end\"><Button variant=\"outline\">Send</Button></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-11.html",
          "target": "components/ui/textarea-11.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Textarea with right button</Label><Textarea id=\"${id}\" placeholder=\"Leave a comment\" /><div class=\"flex justify-end\"><Button variant=\"outline\">Send</Button></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/textarea/textarea-11.wxml",
          "target": "components/ui/textarea-11/textarea-11.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Textarea with right button</label><textarea id=\"{{id}}\" placeholder=\"Leave a comment\" /><view class=\"flex justify-end\"><button variant=\"outline\">Send</button></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "textarea",
          "button"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "textarea-11",
          "group": "textarea",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "textarea-11",
              "path": "registry/default/components/textarea/textarea-11.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "textarea-11",
              "path": "registry/default/components/textarea/textarea-11.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "textarea-11",
              "path": "registry/default/components/textarea/textarea-11.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "textarea-11",
              "path": "registry/default/components/textarea/textarea-11.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "textarea",
        "title": "Textarea · Textarea with right button"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "textarea"
      ]
    },
    {
      "name": "textarea-12",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/textarea.json"
      ],
      "files": [
        {
          "path": "registry/default/components/textarea/textarea-12.tsx",
          "type": "registry:component",
          "target": "components/ui/textarea-12.tsx",
          "content": "import { useId } from 'react'\nimport { Button, Label, Textarea } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Textarea with button</Label>\n      <Textarea id={id} placeholder=\"Leave a comment\" />\n      <Button variant=\"outline\" className=\"w-full\">\n        Send\n      </Button>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-12.vue",
          "target": "components/ui/textarea-12.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\nimport { Label } from '@timui/vue';\nimport { Textarea } from '@timui/vue';\n\n\n\n\n\nconst id = 'textarea-12';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Textarea with button</Label><Textarea :id=\"id\" placeholder=\"Leave a comment\" /><Button variant=\"outline\" class=\"w-full\">Send\n      </Button></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-12.html",
          "target": "components/ui/textarea-12.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Textarea with button</Label><Textarea id=\"${id}\" placeholder=\"Leave a comment\" /><Button variant=\"outline\" class=\"w-full\">Send\n      </Button></div>\n</template>"
        },
        {
          "path": "registry/default/components/textarea/textarea-12.wxml",
          "target": "components/ui/textarea-12/textarea-12.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Textarea with button</label><textarea id=\"{{id}}\" placeholder=\"Leave a comment\" /><button variant=\"outline\" class=\"w-full\">Send\n      </button></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "textarea",
          "button"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "textarea-12",
          "group": "textarea",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "textarea-12",
              "path": "registry/default/components/textarea/textarea-12.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "textarea-12",
              "path": "registry/default/components/textarea/textarea-12.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "textarea-12",
              "path": "registry/default/components/textarea/textarea-12.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "textarea-12",
              "path": "registry/default/components/textarea/textarea-12.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "textarea",
        "title": "Textarea · Textarea with button"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "textarea"
      ]
    },
    {
      "name": "textarea-13",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/textarea.json"
      ],
      "files": [
        {
          "path": "registry/default/components/textarea/textarea-13.tsx",
          "type": "registry:component",
          "target": "components/ui/textarea-13.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Textarea } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"group relative\">\n      <Label\n        htmlFor={id}\n        className=\"bg-background text-foreground absolute start-1 top-0 z-10 block -translate-y-1/2 px-2 text-xs font-medium group-has-disabled:opacity-50\"\n      >\n        Textarea with overlapping label\n      </Label>\n      <Textarea id={id} />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-13.vue",
          "target": "components/ui/textarea-13.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Textarea } from '@timui/vue';\n\n\n\n\n\nconst id = 'textarea-13';\n\n</script>\n\n<template>\n  <div class=\"group relative\"><Label :htmlFor=\"id\" class=\"bg-background text-foreground absolute start-1 top-0 z-10 block -translate-y-1/2 px-2 text-xs font-medium group-has-disabled:opacity-50\">Textarea with overlapping label\n      </Label><Textarea :id=\"id\" /></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-13.html",
          "target": "components/ui/textarea-13.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"group relative\"><Label htmlfor=\"${id}\" class=\"bg-background text-foreground absolute start-1 top-0 z-10 block -translate-y-1/2 px-2 text-xs font-medium group-has-disabled:opacity-50\">Textarea with overlapping label\n      </Label><Textarea id=\"${id}\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/textarea/textarea-13.wxml",
          "target": "components/ui/textarea-13/textarea-13.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"group relative\"><label htmlfor=\"{{id}}\" class=\"bg-background text-foreground absolute start-1 top-0 z-10 block -translate-y-1/2 px-2 text-xs font-medium group-has-disabled:opacity-50\">Textarea with overlapping label\n      </label><textarea id=\"{{id}}\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "textarea"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "textarea-13",
          "group": "textarea",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "textarea-13",
              "path": "registry/default/components/textarea/textarea-13.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "textarea-13",
              "path": "registry/default/components/textarea/textarea-13.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "textarea-13",
              "path": "registry/default/components/textarea/textarea-13.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "textarea-13",
              "path": "registry/default/components/textarea/textarea-13.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "textarea",
        "title": "Textarea · Textarea with overlapping label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "textarea"
      ]
    },
    {
      "name": "textarea-14",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/textarea.json"
      ],
      "files": [
        {
          "path": "registry/default/components/textarea/textarea-14.tsx",
          "type": "registry:component",
          "target": "components/ui/textarea-14.tsx",
          "content": "import { useId } from 'react'\nimport { Textarea } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"group relative\">\n      <label\n        htmlFor={id}\n        className=\"origin-start text-muted-foreground/70 group-focus-within:text-foreground has-[+textarea:not(:placeholder-shown)]:text-foreground has-aria-invalid:border-destructive/60 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40 has-aria-invalid:border-destructive absolute top-0 block translate-y-2 cursor-text px-1 text-sm transition-all group-focus-within:pointer-events-none group-focus-within:-translate-y-1/2 group-focus-within:cursor-default group-focus-within:text-xs group-focus-within:font-medium has-[+textarea:not(:placeholder-shown)]:pointer-events-none has-[+textarea:not(:placeholder-shown)]:-translate-y-1/2 has-[+textarea:not(:placeholder-shown)]:cursor-default has-[+textarea:not(:placeholder-shown)]:text-xs has-[+textarea:not(:placeholder-shown)]:font-medium\"\n      >\n        <span className=\"bg-background inline-flex px-2\">Textarea with label animation</span>\n      </label>\n      <Textarea id={id} placeholder=\" \" />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-14.vue",
          "target": "components/ui/textarea-14.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Textarea } from '@timui/vue';\n\n\n\n\n\nconst id = 'textarea-14';\n\n</script>\n\n<template>\n  <div class=\"group relative\"><label :for=\"id\" class=\"origin-start text-muted-foreground/70 group-focus-within:text-foreground has-[+textarea:not(:placeholder-shown)]:text-foreground has-aria-invalid:border-destructive/60 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40 has-aria-invalid:border-destructive absolute top-0 block translate-y-2 cursor-text px-1 text-sm transition-all group-focus-within:pointer-events-none group-focus-within:-translate-y-1/2 group-focus-within:cursor-default group-focus-within:text-xs group-focus-within:font-medium has-[+textarea:not(:placeholder-shown)]:pointer-events-none has-[+textarea:not(:placeholder-shown)]:-translate-y-1/2 has-[+textarea:not(:placeholder-shown)]:cursor-default has-[+textarea:not(:placeholder-shown)]:text-xs has-[+textarea:not(:placeholder-shown)]:font-medium\"><span class=\"bg-background inline-flex px-2\">Textarea with label animation</span></label><Textarea :id=\"id\" placeholder=\" \" /></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-14.html",
          "target": "components/ui/textarea-14.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"group relative\"><label htmlfor=\"${id}\" class=\"origin-start text-muted-foreground/70 group-focus-within:text-foreground has-[+textarea:not(:placeholder-shown)]:text-foreground has-aria-invalid:border-destructive/60 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40 has-aria-invalid:border-destructive absolute top-0 block translate-y-2 cursor-text px-1 text-sm transition-all group-focus-within:pointer-events-none group-focus-within:-translate-y-1/2 group-focus-within:cursor-default group-focus-within:text-xs group-focus-within:font-medium has-[+textarea:not(:placeholder-shown)]:pointer-events-none has-[+textarea:not(:placeholder-shown)]:-translate-y-1/2 has-[+textarea:not(:placeholder-shown)]:cursor-default has-[+textarea:not(:placeholder-shown)]:text-xs has-[+textarea:not(:placeholder-shown)]:font-medium\"><span class=\"bg-background inline-flex px-2\">Textarea with label animation</span></label><Textarea id=\"${id}\" placeholder=\" \" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/textarea/textarea-14.wxml",
          "target": "components/ui/textarea-14/textarea-14.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"group relative\"><label htmlfor=\"{{id}}\" class=\"origin-start text-muted-foreground/70 group-focus-within:text-foreground has-[+textarea:not(:placeholder-shown)]:text-foreground has-aria-invalid:border-destructive/60 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40 has-aria-invalid:border-destructive absolute top-0 block translate-y-2 cursor-text px-1 text-sm transition-all group-focus-within:pointer-events-none group-focus-within:-translate-y-1/2 group-focus-within:cursor-default group-focus-within:text-xs group-focus-within:font-medium has-[+textarea:not(:placeholder-shown)]:pointer-events-none has-[+textarea:not(:placeholder-shown)]:-translate-y-1/2 has-[+textarea:not(:placeholder-shown)]:cursor-default has-[+textarea:not(:placeholder-shown)]:text-xs has-[+textarea:not(:placeholder-shown)]:font-medium\"><text class=\"bg-background inline-flex px-2\">Textarea with label animation</text></label><textarea id=\"{{id}}\" placeholder=\" \" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "textarea"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "textarea-14",
          "group": "textarea",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "textarea-14",
              "path": "registry/default/components/textarea/textarea-14.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "textarea-14",
              "path": "registry/default/components/textarea/textarea-14.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "textarea-14",
              "path": "registry/default/components/textarea/textarea-14.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "textarea-14",
              "path": "registry/default/components/textarea/textarea-14.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "textarea",
        "title": "Textarea · Destructive Variant"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "textarea"
      ]
    },
    {
      "name": "textarea-15",
      "type": "registry:component",
      "files": [
        {
          "path": "registry/default/components/textarea/textarea-15.tsx",
          "type": "registry:component",
          "target": "components/ui/textarea-15.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Textarea } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n\n  return (\n    <div className=\"border-input bg-background focus-within:border-ring focus-within:ring-ring/50 relative rounded-md border shadow-xs transition-[color,box-shadow] outline-none focus-within:ring-[3px] has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50\">\n      <Label htmlFor={id} className=\"text-foreground block px-3 pt-2 text-xs font-medium\">\n        Textarea with inset label\n      </Label>\n      <Textarea id={id} className=\"min-h-[70px] rounded-none border-0 px-3 pb-2 shadow-none\" />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-15.vue",
          "target": "components/ui/textarea-15.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue'\nimport { Textarea } from '@timui/vue'\n\nconst id = 'textarea-15'\n</script>\n\n<template>\n  <div class=\"border-input bg-background focus-within:border-ring focus-within:ring-ring/50 relative rounded-md border shadow-xs transition-[color,box-shadow] outline-none focus-within:ring-[3px] has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50\">\n    <Label :htmlFor=\"id\" class=\"text-foreground block px-3 pt-2 text-xs font-medium\">\n      Textarea with inset label\n    </Label>\n    <Textarea :id=\"id\" class=\"min-h-[70px] rounded-none border-0 px-3 pb-2 shadow-none\" />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-15.html",
          "target": "components/ui/textarea-15.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"border-input bg-background focus-within:border-ring focus-within:ring-ring/50 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40 has-aria-invalid:border-destructive relative rounded-md border shadow-xs transition-[color,box-shadow] outline-none focus-within:ring-[3px] has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50 has-[input:is(:disabled)]:*:pointer-events-none\"><label htmlfor=\"${id}\" class=\"text-foreground block px-3 pt-2 text-xs font-medium\">Textarea with inset label\n      </label><textarea id=\"${id}\" class=\"text-foreground placeholder:text-muted-foreground/70 flex min-h-[70px] w-full bg-transparent px-3 pb-2 text-sm focus-visible:outline-none\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/textarea/textarea-15.wxml",
          "target": "components/ui/textarea-15/textarea-15.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"border-input bg-background focus-within:border-ring focus-within:ring-ring/50 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40 has-aria-invalid:border-destructive relative rounded-md border shadow-xs transition-[color,box-shadow] outline-none focus-within:ring-[3px] has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50 has-[input:is(:disabled)]:*:pointer-events-none\"><label htmlfor=\"{{id}}\" class=\"text-foreground block px-3 pt-2 text-xs font-medium\">Textarea with inset label\n      </label><textarea id=\"{{id}}\" class=\"text-foreground placeholder:text-muted-foreground/70 flex min-h-[70px] w-full bg-transparent px-3 pb-2 text-sm focus-visible:outline-none\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "textarea"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "textarea-15",
          "group": "textarea",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "textarea-15",
              "path": "registry/default/components/textarea/textarea-15.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "textarea-15",
              "path": "registry/default/components/textarea/textarea-15.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "textarea-15",
              "path": "registry/default/components/textarea/textarea-15.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "textarea-15",
              "path": "registry/default/components/textarea/textarea-15.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "textarea",
        "title": "Textarea · Textarea with inset label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "textarea"
      ]
    },
    {
      "name": "textarea-16",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/textarea.json"
      ],
      "files": [
        {
          "path": "registry/default/components/textarea/textarea-16.tsx",
          "type": "registry:component",
          "target": "components/ui/textarea-16.tsx",
          "content": "'use client'\n\nimport { useId } from 'react'\nimport { Label, Textarea } from '@timui/react'\n\nimport { useCharacterLimit } from '@/registry/default/hooks/use-character-limit'\n\nexport default function Component() {\n  const id = useId()\n  const maxLength = 180\n  const { value, characterCount, handleChange, maxLength: limit } = useCharacterLimit({ maxLength })\n\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Textarea with characters left</Label>\n      <Textarea\n        id={id}\n        value={value}\n        maxLength={maxLength}\n        onChange={handleChange}\n        aria-describedby={`${id}-description`}\n      />\n      <p\n        id={`${id}-description`}\n        className=\"text-muted-foreground mt-2 text-right text-xs\"\n        role=\"status\"\n        aria-live=\"polite\"\n      >\n        <span className=\"tabular-nums\">{limit - characterCount}</span> characters left\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/hooks/use-character-limit.ts",
          "type": "registry:hook",
          "target": "components/ui/textarea-16/use-character-limit.ts",
          "content": "'use client'\n\nimport { ChangeEvent, useState } from 'react'\n\ntype UseCharacterLimitProps = {\n  maxLength: number\n  initialValue?: string\n}\n\nexport function useCharacterLimit({ maxLength, initialValue = '' }: UseCharacterLimitProps) {\n  const [value, setValue] = useState(initialValue)\n  const [characterCount, setCharacterCount] = useState(initialValue.length)\n\n  const handleChange = (e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {\n    const newValue = e.target.value\n    if (newValue.length <= maxLength) {\n      setValue(newValue)\n      setCharacterCount(newValue.length)\n    }\n  }\n\n  return {\n    value,\n    characterCount,\n    handleChange,\n    maxLength,\n  }\n}\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-16.vue",
          "target": "components/ui/textarea-16.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Textarea } from '@timui/vue';\nimport { useCharacterLimit } from '@/registry/default/hooks/use-character-limit-vue';\n\nconst id = 'textarea-16';\nconst maxLength = 180;\n\nconst { value, characterCount, maxLength: limit } = useCharacterLimit({ maxLength });\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\">\n    <Label :htmlFor=\"id\">Textarea with characters left</Label>\n    <Textarea\n      :id=\"id\"\n      v-model=\"value\"\n      :maxLength=\"maxLength\"\n      :aria-describedby=\"`${id}-description`\"\n    />\n    <p :id=\"`${id}-description`\" class=\"text-muted-foreground mt-2 text-right text-xs\" role=\"status\" aria-live=\"polite\">\n      <span class=\"tabular-nums\">{{ limit - characterCount }}</span> characters left\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-16.html",
          "target": "components/ui/textarea-16.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Textarea with characters left</Label><Textarea id=\"${id}\" value=\"${value}\" maxlength=\"${maxLength}\" onchange=\"${handleChange}\" aria-describedby=\"${`${id}-description`}\" /><p id=\"${`${id}-description`}\" class=\"text-muted-foreground mt-2 text-right text-xs\" role=\"status\" aria-live=\"polite\"><span class=\"tabular-nums\">${limit - characterCount}</span>characters left\n      </p></div>\n</template>"
        },
        {
          "path": "registry/default/components/textarea/textarea-16.wxml",
          "target": "components/ui/textarea-16/textarea-16.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Textarea with characters left</label><textarea id=\"{{id}}\" value=\"{{value}}\" maxlength=\"{{maxLength}}\" onchange=\"{{handleChange}}\" aria-describedby=\"{{`${id}-description`}}\" /><text id=\"{{`${id}-description`}}\" class=\"text-muted-foreground mt-2 text-right text-xs\" role=\"status\" aria-live=\"polite\"><text class=\"tabular-nums\">{{ limit - characterCount }}</text>characters left\n      </text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "textarea"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "textarea-16",
          "group": "textarea",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "textarea-16",
              "path": "registry/default/components/textarea/textarea-16.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "textarea-16",
              "path": "registry/default/components/textarea/textarea-16.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "textarea-16",
              "path": "registry/default/components/textarea/textarea-16.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "textarea-16",
              "path": "registry/default/components/textarea/textarea-16.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "textarea",
        "title": "Textarea · Textarea with characters left"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "textarea"
      ]
    },
    {
      "name": "textarea-17",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/textarea.json"
      ],
      "files": [
        {
          "path": "registry/default/components/textarea/textarea-17.tsx",
          "type": "registry:component",
          "target": "components/ui/textarea-17.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Textarea } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Textarea with no resize</Label>\n      <Textarea id={id} className=\"[resize:none]\" placeholder=\"Leave a comment\" />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-17.vue",
          "target": "components/ui/textarea-17.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Textarea } from '@timui/vue';\n\n\n\n\n\nconst id = 'textarea-17';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Textarea with no resize</Label><Textarea :id=\"id\" class=\"[resize:none]\" placeholder=\"Leave a comment\" /></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-17.html",
          "target": "components/ui/textarea-17.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Textarea with no resize</Label><Textarea id=\"${id}\" class=\"[resize:none]\" placeholder=\"Leave a comment\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/textarea/textarea-17.wxml",
          "target": "components/ui/textarea-17/textarea-17.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Textarea with no resize</label><textarea id=\"{{id}}\" class=\"[resize:none]\" placeholder=\"Leave a comment\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "textarea"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "textarea-17",
          "group": "textarea",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "textarea-17",
              "path": "registry/default/components/textarea/textarea-17.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "textarea-17",
              "path": "registry/default/components/textarea/textarea-17.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "textarea-17",
              "path": "registry/default/components/textarea/textarea-17.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "textarea-17",
              "path": "registry/default/components/textarea/textarea-17.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "textarea",
        "title": "Textarea · Textarea with no resize"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "textarea"
      ]
    },
    {
      "name": "textarea-18",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/textarea.json"
      ],
      "files": [
        {
          "path": "registry/default/components/textarea/textarea-18.tsx",
          "type": "registry:component",
          "target": "components/ui/textarea-18.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Textarea } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Read-only textarea</Label>\n      <Textarea\n        id={id}\n        className=\"read-only:bg-muted\"\n        defaultValue=\"This is a read-only textarea\"\n        readOnly\n        placeholder=\"Leave a comment\"\n      />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-18.vue",
          "target": "components/ui/textarea-18.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Textarea } from '@timui/vue';\n\n\n\n\n\nconst id = 'textarea-18';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Read-only textarea</Label><Textarea :id=\"id\" class=\"read-only:bg-muted\" default-value=\"This is a read-only textarea\" readOnly placeholder=\"Leave a comment\" /></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-18.html",
          "target": "components/ui/textarea-18.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Read-only textarea</Label><Textarea id=\"${id}\" class=\"read-only:bg-muted\" default-value=\"This is a read-only textarea\" readonly placeholder=\"Leave a comment\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/textarea/textarea-18.wxml",
          "target": "components/ui/textarea-18/textarea-18.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Read-only textarea</label><textarea id=\"{{id}}\" class=\"read-only:bg-muted\" default-value=\"This is a read-only textarea\" readonly placeholder=\"Leave a comment\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "textarea",
          "read-only"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "textarea-18",
          "group": "textarea",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "textarea-18",
              "path": "registry/default/components/textarea/textarea-18.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "textarea-18",
              "path": "registry/default/components/textarea/textarea-18.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "textarea-18",
              "path": "registry/default/components/textarea/textarea-18.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "textarea-18",
              "path": "registry/default/components/textarea/textarea-18.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "textarea",
        "title": "Textarea · Read-only textarea"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "textarea"
      ]
    },
    {
      "name": "textarea-19",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/textarea.json"
      ],
      "files": [
        {
          "path": "registry/default/components/textarea/textarea-19.tsx",
          "type": "registry:component",
          "target": "components/ui/textarea-19.tsx",
          "content": "'use client'\n\nimport { useId } from 'react'\nimport { Label, Textarea } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Autogrowing textarea</Label>\n      <Textarea\n        id={id}\n        placeholder=\"Leave a comment\"\n        className=\"field-sizing-content max-h-29.5 min-h-0 resize-none py-1.75\"\n      />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-19.vue",
          "target": "components/ui/textarea-19.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Textarea } from '@timui/vue';\n\n\n\n\n\nconst id = 'textarea-19';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Autogrowing textarea</Label><Textarea :id=\"id\" placeholder=\"Leave a comment\" class=\"field-sizing-content max-h-29.5 min-h-0 resize-none py-1.75\" /></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/textarea/textarea-19.html",
          "target": "components/ui/textarea-19.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Autogrowing textarea</Label><Textarea id=\"${id}\" placeholder=\"Leave a comment\" class=\"field-sizing-content max-h-29.5 min-h-0 resize-none py-1.75\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/textarea/textarea-19.wxml",
          "target": "components/ui/textarea-19/textarea-19.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Autogrowing textarea</label><textarea id=\"{{id}}\" placeholder=\"Leave a comment\" class=\"field-sizing-content max-h-29.5 min-h-0 resize-none py-1.75\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "textarea"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "textarea-19",
          "group": "textarea",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "textarea-19",
              "path": "registry/default/components/textarea/textarea-19.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "textarea-19",
              "path": "registry/default/components/textarea/textarea-19.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "textarea-19",
              "path": "registry/default/components/textarea/textarea-19.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "textarea-19",
              "path": "registry/default/components/textarea/textarea-19.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "textarea",
        "title": "Textarea · Autogrowing textarea"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "textarea"
      ]
    },
    {
      "name": "button-01",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-01.tsx",
          "type": "registry:component",
          "target": "components/ui/button-01.tsx",
          "content": "import { Button } from '@timui/react'\n\nexport default function Component() {\n  return <Button>Button</Button>\n}\n"
        },
        {
          "path": "registry/default/components/button/button-01.vue",
          "target": "components/ui/button-01.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Button>Button</Button>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-01.html",
          "target": "components/ui/button-01.html",
          "type": "registry:component",
          "content": "<template>\n  <Button>Button</Button>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-01.wxml",
          "target": "components/ui/button-01/button-01.wxml",
          "type": "registry:component",
          "content": "<view>\n  <button>Button</button>\n</view>"
        },
        {
          "path": "registry/default/components/button/button-01.wxss",
          "target": "components/ui/button-01/button-01.wxss",
          "type": "registry:component",
          "content": "/* Ensure button styling is applied */\n.btn {\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  border-radius: 6px;\n  font-size: 14px;\n  font-weight: 500;\n  background-color: #18181b; /* primary */\n  color: #fafafa;\n  padding: 8px 16px;\n}\n"
        },
        {
          "path": "registry/default/components/button/button-01.json",
          "target": "components/ui/button-01/button-01.json",
          "type": "registry:component",
          "content": "{\n    \"usingComponents\": {}\n}"
        }
      ],
      "meta": {
        "tags": [
          "button"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-01",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-01",
              "path": "registry/default/components/button/button-01.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-01",
              "path": "registry/default/components/button/button-01.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-01",
              "path": "registry/default/components/button/button-01.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-01",
              "path": "registry/default/components/button/button-01.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · Basic button"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-02",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-02.tsx",
          "type": "registry:component",
          "target": "components/ui/button-02.tsx",
          "content": "import { Button } from '@timui/react'\n\nexport default function Component() {\n  return <Button disabled>Button</Button>\n}\n"
        },
        {
          "path": "registry/default/components/button/button-02.vue",
          "target": "components/ui/button-02.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Button disabled>Button</Button>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-02.html",
          "target": "components/ui/button-02.html",
          "type": "registry:component",
          "content": "<template>\n  <Button disabled>Button</Button>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-02.wxml",
          "target": "components/ui/button-02/button-02.wxml",
          "type": "registry:component",
          "content": "<view>\n  <button disabled>Button</button>\n</view>"
        },
        {
          "path": "registry/default/components/button/button-02.wxss",
          "target": "components/ui/button-02/button-02.wxss",
          "type": "registry:component",
          "content": ".btn {\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  border-radius: 6px;\n  font-size: 14px;\n  font-weight: 500;\n  background-color: #18181b;\n  color: #fafafa;\n  padding: 8px 16px;\n}\n\n.btn[disabled] {\n  opacity: 0.5;\n  pointer-events: none;\n}\n"
        },
        {
          "path": "registry/default/components/button/button-02.json",
          "target": "components/ui/button-02/button-02.json",
          "type": "registry:component",
          "content": "{\n    \"component\": true,\n    \"usingComponents\": {}\n}"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "disabled"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-02",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-02",
              "path": "registry/default/components/button/button-02.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-02",
              "path": "registry/default/components/button/button-02.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-02",
              "path": "registry/default/components/button/button-02.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-02",
              "path": "registry/default/components/button/button-02.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · Disabled State"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-03",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-03.tsx",
          "type": "registry:component",
          "target": "components/ui/button-03.tsx",
          "content": "import { Button } from '@timui/react'\n\nexport default function Component() {\n  return <Button className=\"rounded-full\">Button</Button>\n}\n"
        },
        {
          "path": "registry/default/components/button/button-03.vue",
          "target": "components/ui/button-03.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Button class=\"rounded-full\">Button</Button>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-03.html",
          "target": "components/ui/button-03.html",
          "type": "registry:component",
          "content": "<template>\n  <Button class=\"rounded-full\">Button</Button>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-03.wxml",
          "target": "components/ui/button-03/button-03.wxml",
          "type": "registry:component",
          "content": "<view>\n  <button class=\"rounded-full\">Button</button>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-03",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-03",
              "path": "registry/default/components/button/button-03.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-03",
              "path": "registry/default/components/button/button-03.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-03",
              "path": "registry/default/components/button/button-03.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-03",
              "path": "registry/default/components/button/button-03.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · Rounded button"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-04",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-04.tsx",
          "type": "registry:component",
          "target": "components/ui/button-04.tsx",
          "content": "import { Button } from '@timui/react'\nimport { ArchiveIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <Button>\n      <ArchiveIcon className=\"-ms-1 opacity-60\" size={16} aria-hidden=\"true\" />\n      Button\n    </Button>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-04.vue",
          "target": "components/ui/button-04.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ArchiveIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Button><ArchiveIcon class=\"-ms-1 opacity-60\" :size=\"16\" aria-hidden=\"true\" />Button\n    </Button>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-04.html",
          "target": "components/ui/button-04.html",
          "type": "registry:component",
          "content": "<template>\n  <Button><ArchiveIcon class=\"-ms-1 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Button\n    </Button>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-04.wxml",
          "target": "components/ui/button-04/button-04.wxml",
          "type": "registry:component",
          "content": "<view>\n  <button><archiveicon class=\"-ms-1 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Button\n    </button>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-04",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-04",
              "path": "registry/default/components/button/button-04.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-04",
              "path": "registry/default/components/button/button-04.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-04",
              "path": "registry/default/components/button/button-04.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-04",
              "path": "registry/default/components/button/button-04.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-05",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-05.tsx",
          "type": "registry:component",
          "target": "components/ui/button-05.tsx",
          "content": "import { Button } from '@timui/react'\nimport { TrashIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <Button variant=\"destructive\">\n      <TrashIcon className=\"-ms-1 opacity-60\" size={16} aria-hidden=\"true\" />\n      Button\n    </Button>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-05.vue",
          "target": "components/ui/button-05.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { TrashIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Button variant=\"destructive\"><TrashIcon class=\"-ms-1 opacity-60\" :size=\"16\" aria-hidden=\"true\" />Button\n    </Button>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-05.html",
          "target": "components/ui/button-05.html",
          "type": "registry:component",
          "content": "<template>\n  <Button variant=\"destructive\"><TrashIcon class=\"-ms-1 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Button\n    </Button>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-05.wxml",
          "target": "components/ui/button-05/button-05.wxml",
          "type": "registry:component",
          "content": "<view>\n  <button variant=\"destructive\"><trashicon class=\"-ms-1 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Button\n    </button>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "delete"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-05",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-05",
              "path": "registry/default/components/button/button-05.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-05",
              "path": "registry/default/components/button/button-05.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-05",
              "path": "registry/default/components/button/button-05.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-05",
              "path": "registry/default/components/button/button-05.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-06",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-06.tsx",
          "type": "registry:component",
          "target": "components/ui/button-06.tsx",
          "content": "import { Button } from '@timui/react'\nimport { XIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <Button variant=\"secondary\">\n      <XIcon className=\"-ms-1 opacity-60\" size={16} aria-hidden=\"true\" />\n      Button\n    </Button>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-06.vue",
          "target": "components/ui/button-06.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { XIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Button variant=\"secondary\"><XIcon class=\"-ms-1 opacity-60\" :size=\"16\" aria-hidden=\"true\" />Button\n    </Button>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-06.html",
          "target": "components/ui/button-06.html",
          "type": "registry:component",
          "content": "<template>\n  <Button variant=\"secondary\"><XIcon class=\"-ms-1 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Button\n    </Button>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-06.wxml",
          "target": "components/ui/button-06/button-06.wxml",
          "type": "registry:component",
          "content": "<view>\n  <button variant=\"secondary\"><xicon class=\"-ms-1 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Button\n    </button>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-06",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-06",
              "path": "registry/default/components/button/button-06.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-06",
              "path": "registry/default/components/button/button-06.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-06",
              "path": "registry/default/components/button/button-06.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-06",
              "path": "registry/default/components/button/button-06.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-07",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-07.tsx",
          "type": "registry:component",
          "target": "components/ui/button-07.tsx",
          "content": "import { Button } from '@timui/react'\nimport { SparklesIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <Button variant=\"outline\">\n      Button\n      <SparklesIcon className=\"-me-1 opacity-60\" size={16} aria-hidden=\"true\" />\n    </Button>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-07.vue",
          "target": "components/ui/button-07.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { SparklesIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Button variant=\"outline\">Button\n      <SparklesIcon class=\"-me-1 opacity-60\" :size=\"16\" aria-hidden=\"true\" /></Button>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-07.html",
          "target": "components/ui/button-07.html",
          "type": "registry:component",
          "content": "<template>\n  <Button variant=\"outline\">Button\n      <SparklesIcon class=\"-me-1 opacity-60\" size=\"${16}\" aria-hidden=\"true\" /></Button>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-07.wxml",
          "target": "components/ui/button-07/button-07.wxml",
          "type": "registry:component",
          "content": "<view>\n  <button variant=\"outline\">Button\n      <sparklesicon class=\"-me-1 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" /></button>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-07",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-07",
              "path": "registry/default/components/button/button-07.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-07",
              "path": "registry/default/components/button/button-07.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-07",
              "path": "registry/default/components/button/button-07.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-07",
              "path": "registry/default/components/button/button-07.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-08",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-08.tsx",
          "type": "registry:component",
          "target": "components/ui/button-08.tsx",
          "content": "import { Button } from '@timui/react'\nimport { ArrowLeftIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <Button className=\"group\" variant=\"ghost\">\n      <ArrowLeftIcon\n        className=\"-ms-1 opacity-60 transition-transform group-hover:-translate-x-0.5\"\n        size={16}\n        aria-hidden=\"true\"\n      />\n      Button\n    </Button>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-08.vue",
          "target": "components/ui/button-08.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ArrowLeftIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Button class=\"group\" variant=\"ghost\"><ArrowLeftIcon class=\"-ms-1 opacity-60 transition-transform group-hover:-translate-x-0.5\" :size=\"16\" aria-hidden=\"true\" />Button\n    </Button>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-08.html",
          "target": "components/ui/button-08.html",
          "type": "registry:component",
          "content": "<template>\n  <Button class=\"group\" variant=\"ghost\"><ArrowLeftIcon class=\"-ms-1 opacity-60 transition-transform group-hover:-translate-x-0.5\" size=\"${16}\" aria-hidden=\"true\" />Button\n    </Button>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-08.wxml",
          "target": "components/ui/button-08/button-08.wxml",
          "type": "registry:component",
          "content": "<view>\n  <button class=\"group\" variant=\"ghost\"><arrowlefticon class=\"-ms-1 opacity-60 transition-transform group-hover:-translate-x-0.5\" size=\"{{16}}\" aria-hidden=\"true\" />Button\n    </button>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "back"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-08",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-08",
              "path": "registry/default/components/button/button-08.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-08",
              "path": "registry/default/components/button/button-08.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-08",
              "path": "registry/default/components/button/button-08.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-08",
              "path": "registry/default/components/button/button-08.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-09",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-09.tsx",
          "type": "registry:component",
          "target": "components/ui/button-09.tsx",
          "content": "import { Button } from '@timui/react'\nimport { ArrowRightIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <Button className=\"group\">\n      Button\n      <ArrowRightIcon\n        className=\"-me-1 opacity-60 transition-transform group-hover:translate-x-0.5\"\n        size={16}\n        aria-hidden=\"true\"\n      />\n    </Button>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-09.vue",
          "target": "components/ui/button-09.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ArrowRightIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Button class=\"group\">Button\n      <ArrowRightIcon class=\"-me-1 opacity-60 transition-transform group-hover:translate-x-0.5\" :size=\"16\" aria-hidden=\"true\" /></Button>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-09.html",
          "target": "components/ui/button-09.html",
          "type": "registry:component",
          "content": "<template>\n  <Button class=\"group\">Button\n      <ArrowRightIcon class=\"-me-1 opacity-60 transition-transform group-hover:translate-x-0.5\" size=\"${16}\" aria-hidden=\"true\" /></Button>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-09.wxml",
          "target": "components/ui/button-09/button-09.wxml",
          "type": "registry:component",
          "content": "<view>\n  <button class=\"group\">Button\n      <arrowrighticon class=\"-me-1 opacity-60 transition-transform group-hover:translate-x-0.5\" size=\"{{16}}\" aria-hidden=\"true\" /></button>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "next"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-09",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-09",
              "path": "registry/default/components/button/button-09.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-09",
              "path": "registry/default/components/button/button-09.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-09",
              "path": "registry/default/components/button/button-09.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-09",
              "path": "registry/default/components/button/button-09.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-10",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-10.tsx",
          "type": "registry:component",
          "target": "components/ui/button-10.tsx",
          "content": "import { Button } from '@timui/react'\nimport { ArrowRightIcon, MailIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <Button className=\"group\" variant=\"secondary\">\n      <MailIcon className=\"-ms-1 opacity-60\" size={16} aria-hidden=\"true\" />\n      Email\n      <ArrowRightIcon\n        className=\"-me-1 opacity-60 transition-transform group-hover:translate-x-0.5\"\n        size={16}\n        aria-hidden=\"true\"\n      />\n    </Button>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-10.vue",
          "target": "components/ui/button-10.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ArrowRightIcon, MailIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Button class=\"group\" variant=\"secondary\"><MailIcon class=\"-ms-1 opacity-60\" :size=\"16\" aria-hidden=\"true\" />Email\n      <ArrowRightIcon class=\"-me-1 opacity-60 transition-transform group-hover:translate-x-0.5\" :size=\"16\" aria-hidden=\"true\" /></Button>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-10.html",
          "target": "components/ui/button-10.html",
          "type": "registry:component",
          "content": "<template>\n  <Button class=\"group\" variant=\"secondary\"><MailIcon class=\"-ms-1 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Email\n      <ArrowRightIcon class=\"-me-1 opacity-60 transition-transform group-hover:translate-x-0.5\" size=\"${16}\" aria-hidden=\"true\" /></Button>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-10.wxml",
          "target": "components/ui/button-10/button-10.wxml",
          "type": "registry:component",
          "content": "<view>\n  <button class=\"group\" variant=\"secondary\"><mailicon class=\"-ms-1 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Email\n      <arrowrighticon class=\"-me-1 opacity-60 transition-transform group-hover:translate-x-0.5\" size=\"{{16}}\" aria-hidden=\"true\" /></button>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-10",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-10",
              "path": "registry/default/components/button/button-10.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-10",
              "path": "registry/default/components/button/button-10.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-10",
              "path": "registry/default/components/button/button-10.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-10",
              "path": "registry/default/components/button/button-10.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-11",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-11.tsx",
          "type": "registry:component",
          "target": "components/ui/button-11.tsx",
          "content": "import { Button } from '@timui/react'\nimport { ChevronDownIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <Button>\n      Button\n      <ChevronDownIcon className=\"-me-1 opacity-60\" size={16} aria-hidden=\"true\" />\n    </Button>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-11.vue",
          "target": "components/ui/button-11.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ChevronDownIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Button>Button\n      <ChevronDownIcon class=\"-me-1 opacity-60\" :size=\"16\" aria-hidden=\"true\" /></Button>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-11.html",
          "target": "components/ui/button-11.html",
          "type": "registry:component",
          "content": "<template>\n  <Button>Button\n      <ChevronDownIcon class=\"-me-1 opacity-60\" size=\"${16}\" aria-hidden=\"true\" /></Button>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-11.wxml",
          "target": "components/ui/button-11/button-11.wxml",
          "type": "registry:component",
          "content": "<view>\n  <button>Button\n      <chevrondownicon class=\"-me-1 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" /></button>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "dropdown"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-11",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-11",
              "path": "registry/default/components/button/button-11.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-11",
              "path": "registry/default/components/button/button-11.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-11",
              "path": "registry/default/components/button/button-11.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-11",
              "path": "registry/default/components/button/button-11.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-12",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-12.tsx",
          "type": "registry:component",
          "target": "components/ui/button-12.tsx",
          "content": "import { Button } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"inline-flex items-center gap-2\">\n      <Button variant=\"ghost\">Cancel</Button>\n      <Button>Save</Button>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-12.vue",
          "target": "components/ui/button-12.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"inline-flex items-center gap-2\"><Button variant=\"ghost\">Cancel</Button><Button>Save</Button></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-12.html",
          "target": "components/ui/button-12.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"inline-flex items-center gap-2\"><Button variant=\"ghost\">Cancel</Button><Button>Save</Button></div>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-12.wxml",
          "target": "components/ui/button-12/button-12.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"inline-flex items-center gap-2\"><button variant=\"ghost\">Cancel</button><button>Save</button></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-12",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-12",
              "path": "registry/default/components/button/button-12.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-12",
              "path": "registry/default/components/button/button-12.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-12",
              "path": "registry/default/components/button/button-12.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-12",
              "path": "registry/default/components/button/button-12.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · Low emphasis variant"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-13",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-13.tsx",
          "type": "registry:component",
          "target": "components/ui/button-13.tsx",
          "content": "import { Button } from '@timui/react'\nimport { LoaderCircleIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <Button disabled>\n      <LoaderCircleIcon className=\"-ms-1 animate-spin\" size={16} aria-hidden=\"true\" />\n      Button\n    </Button>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-13.vue",
          "target": "components/ui/button-13.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { LoaderCircleIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Button disabled><LoaderCircleIcon class=\"-ms-1 animate-spin\" :size=\"16\" aria-hidden=\"true\" />Button\n    </Button>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-13.html",
          "target": "components/ui/button-13.html",
          "type": "registry:component",
          "content": "<template>\n  <Button disabled><LoaderCircleIcon class=\"-ms-1 animate-spin\" size=\"${16}\" aria-hidden=\"true\" />Button\n    </Button>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-13.wxml",
          "target": "components/ui/button-13/button-13.wxml",
          "type": "registry:component",
          "content": "<view>\n  <button disabled><loadercircleicon class=\"-ms-1 animate-spin\" size=\"{{16}}\" aria-hidden=\"true\" />Button\n    </button>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "loading"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-13",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-13",
              "path": "registry/default/components/button/button-13.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-13",
              "path": "registry/default/components/button/button-13.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-13",
              "path": "registry/default/components/button/button-13.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-13",
              "path": "registry/default/components/button/button-13.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-14",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-14.tsx",
          "type": "registry:component",
          "target": "components/ui/button-14.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Button } from '@timui/react'\nimport { LoaderCircleIcon } from 'lucide-react'\n\nexport default function Component() {\n  const [isLoading, setIsLoading] = useState<boolean>(false)\n\n  const handleClick = () => {\n    setIsLoading(true)\n    // Simulate an async operation\n    setTimeout(() => {\n      setIsLoading(false)\n    }, 1000) // Reset after 1 second\n  }\n\n  return (\n    <Button\n      onClick={handleClick}\n      disabled={isLoading}\n      data-loading={isLoading || undefined}\n      className=\"group relative disabled:opacity-100\"\n    >\n      <span className=\"group-data-loading:text-transparent\">Click me</span>\n      {isLoading && (\n        <div className=\"absolute inset-0 flex items-center justify-center\">\n          <LoaderCircleIcon className=\"animate-spin\" size={16} aria-hidden=\"true\" />\n        </div>\n      )}\n    </Button>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-14.vue",
          "target": "components/ui/button-14.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { LoaderCircleIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\nconst isLoading = ref<boolean>(false);\n\n</script>\n\n<template>\n  <Button @click=\"handleClick\" :disabled=\"isLoading\" :data-loading=\"isLoading || undefined\" class=\"group relative disabled:opacity-100\"><span class=\"group-data-loading:text-transparent\">Click me</span><div v-if=\"isLoading\" class=\"absolute inset-0 flex items-center justify-center\"><LoaderCircleIcon class=\"animate-spin\" :size=\"16\" aria-hidden=\"true\" /></div></Button>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-14.html",
          "target": "components/ui/button-14.html",
          "type": "registry:component",
          "content": "<template>\n  <Button on-click=\"${handleClick}\" disabled=\"${isLoading}\" data-loading=\"${isLoading || undefined}\" class=\"group relative disabled:opacity-100\"><span class=\"group-data-loading:text-transparent\">Click me</span><!-- if isLoading -->\n<div class=\"absolute inset-0 flex items-center justify-center\"><LoaderCircleIcon class=\"animate-spin\" size=\"${16}\" aria-hidden=\"true\" /></div>\n<!-- endif --></Button>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-14.wxml",
          "target": "components/ui/button-14/button-14.wxml",
          "type": "registry:component",
          "content": "<view>\n  <button bindtap=\"handleClick\" disabled=\"{{isLoading}}\" data-loading=\"{{isLoading || undefined}}\" class=\"group relative disabled:opacity-100\"><text class=\"group-data-loading:text-transparent\">Click me</text><view wx:if=\"{{isLoading}}\" class=\"absolute inset-0 flex items-center justify-center\"><loadercircleicon class=\"animate-spin\" size=\"{{16}}\" aria-hidden=\"true\" /></view></button>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "loading"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-14",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-14",
              "path": "registry/default/components/button/button-14.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-14",
              "path": "registry/default/components/button/button-14.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-14",
              "path": "registry/default/components/button/button-14.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-14",
              "path": "registry/default/components/button/button-14.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · Loading state"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-15",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-15.tsx",
          "type": "registry:component",
          "target": "components/ui/button-15.tsx",
          "content": "import { Button } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Button variant=\"outline\" className=\"gap-3\">\n      Messages\n      <span className=\"text-muted-foreground -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">\n        18\n      </span>\n    </Button>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-15.vue",
          "target": "components/ui/button-15.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Button variant=\"outline\" class=\"gap-3\">Messages\n      <span class=\"text-muted-foreground -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">18\n      </span></Button>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-15.html",
          "target": "components/ui/button-15.html",
          "type": "registry:component",
          "content": "<template>\n  <Button variant=\"outline\" class=\"gap-3\">Messages\n      <span class=\"text-muted-foreground -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">18\n      </span></Button>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-15.wxml",
          "target": "components/ui/button-15/button-15.wxml",
          "type": "registry:component",
          "content": "<view>\n  <button variant=\"outline\" class=\"gap-3\">Messages\n      <text class=\"text-muted-foreground -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">18\n      </text></button>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "counter"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-15",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-15",
              "path": "registry/default/components/button/button-15.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-15",
              "path": "registry/default/components/button/button-15.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-15",
              "path": "registry/default/components/button/button-15.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-15",
              "path": "registry/default/components/button/button-15.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · Outlined variant"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-16",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-16.tsx",
          "type": "registry:component",
          "target": "components/ui/button-16.tsx",
          "content": "import { Button } from '@timui/react'\nimport { PrinterIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <Button variant=\"outline\">\n      <PrinterIcon className=\"-ms-1 opacity-60\" size={16} aria-hidden=\"true\" />\n      Print\n      <kbd className=\"bg-background text-muted-foreground/70 ms-1 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">\n        ⌘P\n      </kbd>\n    </Button>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-16.vue",
          "target": "components/ui/button-16.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { PrinterIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Button variant=\"outline\"><PrinterIcon class=\"-ms-1 opacity-60\" :size=\"16\" aria-hidden=\"true\" />Print\n      <kbd class=\"bg-background text-muted-foreground/70 ms-1 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">⌘P\n      </kbd></Button>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-16.html",
          "target": "components/ui/button-16.html",
          "type": "registry:component",
          "content": "<template>\n  <Button variant=\"outline\"><PrinterIcon class=\"-ms-1 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Print\n      <kbd class=\"bg-background text-muted-foreground/70 ms-1 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">⌘P\n      </kbd></Button>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-16.wxml",
          "target": "components/ui/button-16/button-16.wxml",
          "type": "registry:component",
          "content": "<view>\n  <button variant=\"outline\"><printericon class=\"-ms-1 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Print\n      <kbd class=\"bg-background text-muted-foreground/70 ms-1 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">⌘P\n      </kbd></button>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "kbd"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-16",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-16",
              "path": "registry/default/components/button/button-16.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-16",
              "path": "registry/default/components/button/button-16.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-16",
              "path": "registry/default/components/button/button-16.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-16",
              "path": "registry/default/components/button/button-16.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-17",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-17.tsx",
          "type": "registry:component",
          "target": "components/ui/button-17.tsx",
          "content": "import { Button } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Button className=\"gap-0 rounded-full py-0 ps-0\">\n      <div className=\"me-0.5 flex aspect-square h-full p-1.5\">\n        <img\n          className=\"h-auto w-full rounded-full\"\n          src=\"avatar.jpg\"\n          alt=\"Profile image\"\n          width={24}\n          height={24}\n          aria-hidden=\"true\"\n        />\n      </div>\n      @georgelucas\n    </Button>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-17.vue",
          "target": "components/ui/button-17.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Button class=\"gap-0 rounded-full py-0 ps-0\"><div class=\"me-0.5 flex aspect-square h-full p-1.5\"><img class=\"h-auto w-full rounded-full\" src=\"avatar.jpg\" alt=\"Profile image\" :width=\"24\" :height=\"24\" aria-hidden=\"true\" /></div>@georgelucas\n    </Button>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-17.html",
          "target": "components/ui/button-17.html",
          "type": "registry:component",
          "content": "<template>\n  <Button class=\"gap-0 rounded-full py-0 ps-0\"><div class=\"me-0.5 flex aspect-square h-full p-1.5\"><img class=\"h-auto w-full rounded-full\" src=\"avatar.jpg\" alt=\"Profile image\" width=\"${24}\" height=\"${24}\" aria-hidden=\"true\" /></div>@georgelucas\n    </Button>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-17.wxml",
          "target": "components/ui/button-17/button-17.wxml",
          "type": "registry:component",
          "content": "<view>\n  <button class=\"gap-0 rounded-full py-0 ps-0\"><view class=\"me-0.5 flex aspect-square h-full p-1.5\"><image class=\"h-auto w-full rounded-full\" src=\"avatar.jpg\" alt=\"Profile image\" width=\"{{24}}\" height=\"{{24}}\" aria-hidden=\"true\" /></view>@georgelucas\n    </button>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "user",
          "avatar",
          "profile"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-17",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-17",
              "path": "registry/default/components/button/button-17.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-17",
              "path": "registry/default/components/button/button-17.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-17",
              "path": "registry/default/components/button/button-17.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-17",
              "path": "registry/default/components/button/button-17.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · Rounded button"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-18",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-18.tsx",
          "type": "registry:component",
          "target": "components/ui/button-18.tsx",
          "content": "import { Avatar, AvatarFallback, AvatarImage, Button } from '@timui/react'\nimport { ChevronDownIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <Button variant=\"ghost\" className=\"h-auto p-0 hover:bg-transparent\">\n      <Avatar>\n        <AvatarImage src=\"./avatar.jpg\" alt=\"Profile image\" />\n        <AvatarFallback>KK</AvatarFallback>\n      </Avatar>\n      <ChevronDownIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n    </Button>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-18.vue",
          "target": "components/ui/button-18.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ChevronDownIcon } from 'lucide-vue-next';\nimport { Avatar, AvatarFallback, AvatarImage } from '@timui/vue';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Button variant=\"ghost\" class=\"h-auto p-0 hover:bg-transparent\"><Avatar><AvatarImage src=\"./avatar.jpg\" alt=\"Profile image\" /><AvatarFallback>KK</AvatarFallback></Avatar><ChevronDownIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" /></Button>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-18.html",
          "target": "components/ui/button-18.html",
          "type": "registry:component",
          "content": "<template>\n  <Button variant=\"ghost\" class=\"h-auto p-0 hover:bg-transparent\"><Avatar><AvatarImage src=\"./avatar.jpg\" alt=\"Profile image\" /><AvatarFallback>KK</AvatarFallback></Avatar><ChevronDownIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" /></Button>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-18.wxml",
          "target": "components/ui/button-18/button-18.wxml",
          "type": "registry:component",
          "content": "<view>\n  <button variant=\"ghost\" class=\"h-auto p-0 hover:bg-transparent\"><avatar><avatarimage src=\"./avatar.jpg\" alt=\"Profile image\" /><avatarfallback>KK</avatarfallback></avatar><chevrondownicon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" /></button>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "user",
          "avatar",
          "profile",
          "dropdown"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-18",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-18",
              "path": "registry/default/components/button/button-18.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-18",
              "path": "registry/default/components/button/button-18.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-18",
              "path": "registry/default/components/button/button-18.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-18",
              "path": "registry/default/components/button/button-18.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-19",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-19.tsx",
          "type": "registry:component",
          "target": "components/ui/button-19.tsx",
          "content": "import { Button } from '@timui/react'\nimport { PlusIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <Button variant=\"outline\" className=\"aspect-square max-sm:p-0\">\n      <PlusIcon className=\"opacity-60 sm:-ms-1\" size={16} aria-hidden=\"true\" />\n      <span className=\"max-sm:sr-only\">Add new</span>\n    </Button>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-19.vue",
          "target": "components/ui/button-19.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { PlusIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Button variant=\"outline\" class=\"aspect-square max-sm:p-0\"><PlusIcon class=\"opacity-60 sm:-ms-1\" :size=\"16\" aria-hidden=\"true\" /><span class=\"max-sm:sr-only\">Add new</span></Button>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-19.html",
          "target": "components/ui/button-19.html",
          "type": "registry:component",
          "content": "<template>\n  <Button variant=\"outline\" class=\"aspect-square max-sm:p-0\"><PlusIcon class=\"opacity-60 sm:-ms-1\" size=\"${16}\" aria-hidden=\"true\" /><span class=\"max-sm:sr-only\">Add new</span></Button>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-19.wxml",
          "target": "components/ui/button-19/button-19.wxml",
          "type": "registry:component",
          "content": "<view>\n  <button variant=\"outline\" class=\"aspect-square max-sm:p-0\"><plusicon class=\"opacity-60 sm:-ms-1\" size=\"{{16}}\" aria-hidden=\"true\" /><text class=\"max-sm:sr-only\">Add new</text></button>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-19",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-19",
              "path": "registry/default/components/button/button-19.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-19",
              "path": "registry/default/components/button/button-19.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-19",
              "path": "registry/default/components/button/button-19.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-19",
              "path": "registry/default/components/button/button-19.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-20",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-20.tsx",
          "type": "registry:component",
          "target": "components/ui/button-20.tsx",
          "content": "import { Button } from '@timui/react'\nimport { PlusIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <Button className=\"rounded-full\" variant=\"outline\" size=\"icon\" aria-label=\"Add new item\">\n      <PlusIcon size={16} aria-hidden=\"true\" />\n    </Button>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-20.vue",
          "target": "components/ui/button-20.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { PlusIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Button class=\"rounded-full\" variant=\"outline\" size=\"icon\" aria-label=\"Add new item\"><PlusIcon :size=\"16\" aria-hidden=\"true\" /></Button>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-20.html",
          "target": "components/ui/button-20.html",
          "type": "registry:component",
          "content": "<template>\n  <Button class=\"rounded-full\" variant=\"outline\" size=\"icon\" aria-label=\"Add new item\"><PlusIcon size=\"${16}\" aria-hidden=\"true\" /></Button>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-20.wxml",
          "target": "components/ui/button-20/button-20.wxml",
          "type": "registry:component",
          "content": "<view>\n  <button class=\"rounded-full\" variant=\"outline\" size=\"icon\" aria-label=\"Add new item\"><plusicon size=\"{{16}}\" aria-hidden=\"true\" /></button>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-20",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-20",
              "path": "registry/default/components/button/button-20.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-20",
              "path": "registry/default/components/button/button-20.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-20",
              "path": "registry/default/components/button/button-20.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-20",
              "path": "registry/default/components/button/button-20.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · Rounded button"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-21",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-21.tsx",
          "type": "registry:component",
          "target": "components/ui/button-21.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Button } from '@timui/react'\nimport { PlusIcon } from 'lucide-react'\n\nexport default function Component() {\n  const [open, setOpen] = useState<boolean>(false)\n\n  return (\n    <Button\n      className=\"group rounded-full\"\n      variant=\"outline\"\n      size=\"icon\"\n      onClick={() => setOpen((prevState) => !prevState)}\n      aria-expanded={open}\n      aria-label={open ? 'Close menu' : 'Open menu'}\n    >\n      <PlusIcon\n        className=\"transition-transform duration-500 ease-[cubic-bezier(0.68,-0.6,0.32,1.6)] group-aria-expanded:rotate-[135deg]\"\n        size={16}\n        aria-hidden=\"true\"\n      />\n    </Button>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-21.vue",
          "target": "components/ui/button-21.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { PlusIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\nconst open = ref<boolean>(false);\n\n\nfunction setOpen(next: typeof open.value | ((prev: typeof open.value) => typeof open.value)) {\n  open.value = typeof next === 'function'\n    ? (next as (prev: typeof open.value) => typeof open.value)(open.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <Button class=\"group rounded-full\" variant=\"outline\" size=\"icon\" @click=\"setOpen((prevState) => !prevState)\" :aria-expanded=\"open\" :aria-label=\"open ? 'Close menu' : 'Open menu'\"><PlusIcon class=\"transition-transform duration-500 ease-[cubic-bezier(0.68,-0.6,0.32,1.6)] group-aria-expanded:rotate-[135deg]\" :size=\"16\" aria-hidden=\"true\" /></Button>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-21.html",
          "target": "components/ui/button-21.html",
          "type": "registry:component",
          "content": "<template>\n  <Button class=\"group rounded-full\" variant=\"outline\" size=\"icon\" on-click=\"${() => setOpen((prevState) => !prevState)}\" aria-expanded=\"${open}\" aria-label=\"${open ? 'Close menu' : 'Open menu'}\"><PlusIcon class=\"transition-transform duration-500 ease-[cubic-bezier(0.68,-0.6,0.32,1.6)] group-aria-expanded:rotate-[135deg]\" size=\"${16}\" aria-hidden=\"true\" /></Button>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-21.wxml",
          "target": "components/ui/button-21/button-21.wxml",
          "type": "registry:component",
          "content": "<view>\n  <button class=\"group rounded-full\" variant=\"outline\" size=\"icon\" bindtap=\"setOpen((prevState) => !prevState)\" aria-expanded=\"{{open}}\" aria-label=\"{{open ? 'Close menu' : 'Open menu'}}\"><plusicon class=\"transition-transform duration-500 ease-[cubic-bezier(0.68,-0.6,0.32,1.6)] group-aria-expanded:rotate-[135deg]\" size=\"{{16}}\" aria-hidden=\"true\" /></button>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "menu"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-21",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-21",
              "path": "registry/default/components/button/button-21.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-21",
              "path": "registry/default/components/button/button-21.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-21",
              "path": "registry/default/components/button/button-21.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-21",
              "path": "registry/default/components/button/button-21.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · Rounded button"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-22",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/tooltip.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-22.tsx",
          "type": "registry:component",
          "target": "components/ui/button-22.tsx",
          "content": "'use client'\n\nimport { Button, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@timui/react'\nimport { PlusIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <TooltipProvider delayDuration={0}>\n      <Tooltip>\n        <TooltipTrigger asChild>\n          <Button variant=\"outline\" size=\"icon\" aria-label=\"Add new item\">\n            <PlusIcon size={16} aria-hidden=\"true\" />\n          </Button>\n        </TooltipTrigger>\n        <TooltipContent className=\"px-2 py-1 text-xs\">Tooltip</TooltipContent>\n      </Tooltip>\n    </TooltipProvider>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-22.vue",
          "target": "components/ui/button-22.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { PlusIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { Tooltip } from '@timui/vue';\nimport { TooltipContent } from '@timui/vue';\nimport { TooltipProvider } from '@timui/vue';\nimport { TooltipTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <TooltipProvider :delayDuration=\"0\"><Tooltip><TooltipTrigger as-child><Button variant=\"outline\" size=\"icon\" aria-label=\"Add new item\"><PlusIcon :size=\"16\" aria-hidden=\"true\" /></Button></TooltipTrigger><TooltipContent class=\"px-2 py-1 text-xs\">Tooltip</TooltipContent></Tooltip></TooltipProvider>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-22.html",
          "target": "components/ui/button-22.html",
          "type": "registry:component",
          "content": "<template>\n  <TooltipProvider delayduration=\"${0}\"><Tooltip><TooltipTrigger aschild><Button variant=\"outline\" size=\"icon\" aria-label=\"Add new item\"><PlusIcon size=\"${16}\" aria-hidden=\"true\" /></Button></TooltipTrigger><TooltipContent class=\"px-2 py-1 text-xs\">Tooltip</TooltipContent></Tooltip></TooltipProvider>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-22.wxml",
          "target": "components/ui/button-22/button-22.wxml",
          "type": "registry:component",
          "content": "<view>\n  <tooltipprovider delayduration=\"{{0}}\"><tooltip><tooltiptrigger aschild><button variant=\"outline\" size=\"icon\" aria-label=\"Add new item\"><plusicon size=\"{{16}}\" aria-hidden=\"true\" /></button></tooltiptrigger><tooltipcontent class=\"px-2 py-1 text-xs\">Tooltip</tooltipcontent></tooltip></tooltipprovider>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "tooltip"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-22",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-22",
              "path": "registry/default/components/button/button-22.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-22",
              "path": "registry/default/components/button/button-22.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-22",
              "path": "registry/default/components/button/button-22.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-22",
              "path": "registry/default/components/button/button-22.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-23",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-23.tsx",
          "type": "registry:component",
          "target": "components/ui/button-23.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Button } from '@timui/react'\n\nexport default function Component() {\n  const [open, setOpen] = useState<boolean>(false)\n\n  return (\n    <Button\n      className=\"group\"\n      variant=\"outline\"\n      size=\"icon\"\n      onClick={() => setOpen((prevState) => !prevState)}\n      aria-expanded={open}\n      aria-label={open ? 'Close menu' : 'Open menu'}\n    >\n      <svg\n        className=\"pointer-events-none\"\n        width={16}\n        height={16}\n        viewBox=\"0 0 24 24\"\n        fill=\"none\"\n        stroke=\"currentColor\"\n        strokeWidth=\"2\"\n        strokeLinecap=\"round\"\n        strokeLinejoin=\"round\"\n        xmlns=\"http://www.w3.org/2000/svg\"\n      >\n        <path\n          d=\"M4 12L20 12\"\n          className=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\"\n        />\n        <path\n          d=\"M4 12H20\"\n          className=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\"\n        />\n        <path\n          d=\"M4 12H20\"\n          className=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\"\n        />\n      </svg>\n    </Button>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-23.vue",
          "target": "components/ui/button-23.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Button } from '@timui/vue';\n\n\n\nconst open = ref<boolean>(false);\n\n\nfunction setOpen(next: typeof open.value | ((prev: typeof open.value) => typeof open.value)) {\n  open.value = typeof next === 'function'\n    ? (next as (prev: typeof open.value) => typeof open.value)(open.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <Button class=\"group\" variant=\"outline\" size=\"icon\" @click=\"setOpen((prevState) => !prevState)\" :aria-expanded=\"open\" :aria-label=\"open ? 'Close menu' : 'Open menu'\"><svg class=\"pointer-events-none\" :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></Button>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-23.html",
          "target": "components/ui/button-23.html",
          "type": "registry:component",
          "content": "<template>\n  <Button class=\"group\" variant=\"outline\" size=\"icon\" on-click=\"${() => setOpen((prevState) => !prevState)}\" aria-expanded=\"${open}\" aria-label=\"${open ? 'Close menu' : 'Open menu'}\"><svg class=\"pointer-events-none\" width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></Button>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-23.wxml",
          "target": "components/ui/button-23/button-23.wxml",
          "type": "registry:component",
          "content": "<view>\n  <button class=\"group\" variant=\"outline\" size=\"icon\" bindtap=\"setOpen((prevState) => !prevState)\" aria-expanded=\"{{open}}\" aria-label=\"{{open ? 'Close menu' : 'Open menu'}}\"><svg class=\"pointer-events-none\" width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></button>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "menu",
          "hamburger"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-23",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-23",
              "path": "registry/default/components/button/button-23.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-23",
              "path": "registry/default/components/button/button-23.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-23",
              "path": "registry/default/components/button/button-23.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-23",
              "path": "registry/default/components/button/button-23.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-24",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/toggle.json",
        "https://ui.timkit.cn/r/tooltip.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-24.tsx",
          "type": "registry:component",
          "target": "components/ui/button-24.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Toggle, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@timui/react'\nimport { BookmarkIcon } from 'lucide-react'\n\nexport default function Component() {\n  const [bookmarked, setBookmarked] = useState<boolean>(false)\n  return (\n    <TooltipProvider>\n      <Tooltip>\n        <TooltipTrigger asChild>\n          <div>\n            <Toggle\n              className=\"group size-9 p-0 hover:bg-indigo-50 hover:text-indigo-500 data-[state=on]:bg-indigo-50 data-[state=on]:text-indigo-500\"\n              aria-label=\"BookmarkIcon this\"\n              pressed={bookmarked}\n              onPressedChange={setBookmarked}\n            >\n              <BookmarkIcon size={16} aria-hidden=\"true\" />\n            </Toggle>\n          </div>\n        </TooltipTrigger>\n        <TooltipContent className=\"px-2 py-1 text-xs\">\n          <p>{bookmarked ? 'Remove bookmark' : 'BookmarkIcon this'}</p>\n        </TooltipContent>\n      </Tooltip>\n    </TooltipProvider>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-24.vue",
          "target": "components/ui/button-24.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { BookmarkIcon } from 'lucide-vue-next';\nimport { Toggle } from '@timui/vue';\nimport { Tooltip } from '@timui/vue';\nimport { TooltipContent } from '@timui/vue';\nimport { TooltipProvider } from '@timui/vue';\nimport { TooltipTrigger } from '@timui/vue';\n\n\n\nconst bookmarked = ref<boolean>(false);\n\n\nfunction setBookmarked(next: typeof bookmarked.value | ((prev: typeof bookmarked.value) => typeof bookmarked.value)) {\n  bookmarked.value = typeof next === 'function'\n    ? (next as (prev: typeof bookmarked.value) => typeof bookmarked.value)(bookmarked.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <TooltipProvider><Tooltip><TooltipTrigger as-child><div><Toggle class=\"group size-9 p-0 hover:bg-indigo-50 hover:text-indigo-500 data-[state=on]:bg-indigo-50 data-[state=on]:text-indigo-500\" aria-label=\"BookmarkIcon this\" :pressed=\"bookmarked\" :onPressedChange=\"setBookmarked\"><BookmarkIcon :size=\"16\" aria-hidden=\"true\" /></Toggle></div></TooltipTrigger><TooltipContent class=\"px-2 py-1 text-xs\"><p><template v-if=\"bookmarked\">\n{{ 'Remove bookmark' }}\n</template>\n<template v-else>\n{{ 'BookmarkIcon this' }}\n</template></p></TooltipContent></Tooltip></TooltipProvider>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-24.html",
          "target": "components/ui/button-24.html",
          "type": "registry:component",
          "content": "<template>\n  <TooltipProvider><Tooltip><TooltipTrigger aschild><div><Toggle class=\"group size-9 p-0 hover:bg-indigo-50 hover:text-indigo-500 data-[state=on]:bg-indigo-50 data-[state=on]:text-indigo-500\" aria-label=\"BookmarkIcon this\" pressed=\"${bookmarked}\" onpressedchange=\"${setBookmarked}\"><BookmarkIcon size=\"${16}\" aria-hidden=\"true\" /></Toggle></div></TooltipTrigger><TooltipContent class=\"px-2 py-1 text-xs\"><p><!-- if bookmarked -->\n${'Remove bookmark'}\n<!-- else -->\n${'BookmarkIcon this'}\n<!-- endif --></p></TooltipContent></Tooltip></TooltipProvider>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-24.wxml",
          "target": "components/ui/button-24/button-24.wxml",
          "type": "registry:component",
          "content": "<view>\n  <tooltipprovider><tooltip><tooltiptrigger aschild><view><toggle class=\"group size-9 p-0 hover:bg-indigo-50 hover:text-indigo-500 data-[state=on]:bg-indigo-50 data-[state=on]:text-indigo-500\" aria-label=\"BookmarkIcon this\" pressed=\"{{bookmarked}}\" onpressedchange=\"{{setBookmarked}}\"><bookmarkicon size=\"{{16}}\" aria-hidden=\"true\" /></toggle></view></tooltiptrigger><tooltipcontent class=\"px-2 py-1 text-xs\"><text><block wx:if=\"{{bookmarked}}\">\n{{ 'Remove bookmark' }}\n</block>\n<block wx:else>\n{{ 'BookmarkIcon this' }}\n</block></text></tooltipcontent></tooltip></tooltipprovider>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "toggle"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-24",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-24",
              "path": "registry/default/components/button/button-24.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-24",
              "path": "registry/default/components/button/button-24.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-24",
              "path": "registry/default/components/button/button-24.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-24",
              "path": "registry/default/components/button/button-24.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-27",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-27.tsx",
          "type": "registry:component",
          "target": "components/ui/button-27.tsx",
          "content": "import { Button } from '@timui/react'\nimport { ChevronDownIcon, ChevronUpIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <div className=\"inline-flex -space-x-px rounded-md shadow-xs rtl:space-x-reverse\">\n      <Button\n        className=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\"\n        variant=\"outline\"\n        size=\"icon\"\n        aria-label=\"Upvote\"\n      >\n        <ChevronUpIcon size={16} aria-hidden=\"true\" />\n      </Button>\n      <span className=\"border-input flex items-center border px-3 text-sm font-medium\">235</span>\n      <Button\n        className=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\"\n        variant=\"outline\"\n        size=\"icon\"\n        aria-label=\"Downvote\"\n      >\n        <ChevronDownIcon size={16} aria-hidden=\"true\" />\n      </Button>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-27.vue",
          "target": "components/ui/button-27.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ChevronDownIcon, ChevronUpIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"inline-flex -space-x-px rounded-md shadow-xs rtl:space-x-reverse\"><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" variant=\"outline\" size=\"icon\" aria-label=\"Upvote\"><ChevronUpIcon :size=\"16\" aria-hidden=\"true\" /></Button><span class=\"border-input flex items-center border px-3 text-sm font-medium\">235</span><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" variant=\"outline\" size=\"icon\" aria-label=\"Downvote\"><ChevronDownIcon :size=\"16\" aria-hidden=\"true\" /></Button></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-27.html",
          "target": "components/ui/button-27.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"inline-flex -space-x-px rounded-md shadow-xs rtl:space-x-reverse\"><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" variant=\"outline\" size=\"icon\" aria-label=\"Upvote\"><ChevronUpIcon size=\"${16}\" aria-hidden=\"true\" /></Button><span class=\"border-input flex items-center border px-3 text-sm font-medium\">235</span><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" variant=\"outline\" size=\"icon\" aria-label=\"Downvote\"><ChevronDownIcon size=\"${16}\" aria-hidden=\"true\" /></Button></div>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-27.wxml",
          "target": "components/ui/button-27/button-27.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"inline-flex -space-x-px rounded-md shadow-xs rtl:space-x-reverse\"><button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" variant=\"outline\" size=\"icon\" aria-label=\"Upvote\"><chevronupicon size=\"{{16}}\" aria-hidden=\"true\" /></button><text class=\"border-input flex items-center border px-3 text-sm font-medium\">235</text><button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" variant=\"outline\" size=\"icon\" aria-label=\"Downvote\"><chevrondownicon size=\"{{16}}\" aria-hidden=\"true\" /></button></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "vote",
          "counter"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-27",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-27",
              "path": "registry/default/components/button/button-27.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-27",
              "path": "registry/default/components/button/button-27.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-27",
              "path": "registry/default/components/button/button-27.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-27",
              "path": "registry/default/components/button/button-27.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-28",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-28.tsx",
          "type": "registry:component",
          "target": "components/ui/button-28.tsx",
          "content": "import { Button } from '@timui/react'\nimport { ChevronDownIcon, ChevronUpIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <div className=\"inline-flex -space-x-px rounded-full shadow-xs rtl:space-x-reverse\">\n      <Button\n        className=\"rounded-none shadow-none first:rounded-s-full last:rounded-e-full focus-visible:z-10\"\n        size=\"icon\"\n        aria-label=\"Upvote\"\n      >\n        <ChevronUpIcon size={16} aria-hidden=\"true\" />\n      </Button>\n      <span className=\"bg-primary text-primary-foreground flex items-center px-1 text-sm font-medium\">\n        235\n      </span>\n      <Button\n        className=\"rounded-none shadow-none first:rounded-s-full last:rounded-e-full focus-visible:z-10\"\n        size=\"icon\"\n        aria-label=\"Downvote\"\n      >\n        <ChevronDownIcon size={16} aria-hidden=\"true\" />\n      </Button>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-28.vue",
          "target": "components/ui/button-28.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ChevronDownIcon, ChevronUpIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"inline-flex -space-x-px rounded-full shadow-xs rtl:space-x-reverse\"><Button class=\"rounded-none shadow-none first:rounded-s-full last:rounded-e-full focus-visible:z-10\" size=\"icon\" aria-label=\"Upvote\"><ChevronUpIcon :size=\"16\" aria-hidden=\"true\" /></Button><span class=\"bg-primary text-primary-foreground flex items-center px-1 text-sm font-medium\">235\n      </span><Button class=\"rounded-none shadow-none first:rounded-s-full last:rounded-e-full focus-visible:z-10\" size=\"icon\" aria-label=\"Downvote\"><ChevronDownIcon :size=\"16\" aria-hidden=\"true\" /></Button></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-28.html",
          "target": "components/ui/button-28.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"inline-flex -space-x-px rounded-full shadow-xs rtl:space-x-reverse\"><Button class=\"rounded-none shadow-none first:rounded-s-full last:rounded-e-full focus-visible:z-10\" size=\"icon\" aria-label=\"Upvote\"><ChevronUpIcon size=\"${16}\" aria-hidden=\"true\" /></Button><span class=\"bg-primary text-primary-foreground flex items-center px-1 text-sm font-medium\">235\n      </span><Button class=\"rounded-none shadow-none first:rounded-s-full last:rounded-e-full focus-visible:z-10\" size=\"icon\" aria-label=\"Downvote\"><ChevronDownIcon size=\"${16}\" aria-hidden=\"true\" /></Button></div>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-28.wxml",
          "target": "components/ui/button-28/button-28.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"inline-flex -space-x-px rounded-full shadow-xs rtl:space-x-reverse\"><button class=\"rounded-none shadow-none first:rounded-s-full last:rounded-e-full focus-visible:z-10\" size=\"icon\" aria-label=\"Upvote\"><chevronupicon size=\"{{16}}\" aria-hidden=\"true\" /></button><text class=\"bg-primary text-primary-foreground flex items-center px-1 text-sm font-medium\">235\n      </text><button class=\"rounded-none shadow-none first:rounded-s-full last:rounded-e-full focus-visible:z-10\" size=\"icon\" aria-label=\"Downvote\"><chevrondownicon size=\"{{16}}\" aria-hidden=\"true\" /></button></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "vote",
          "counter"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-28",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-28",
              "path": "registry/default/components/button/button-28.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-28",
              "path": "registry/default/components/button/button-28.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-28",
              "path": "registry/default/components/button/button-28.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-28",
              "path": "registry/default/components/button/button-28.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · Rounded button"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-29",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-29.tsx",
          "type": "registry:component",
          "target": "components/ui/button-29.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Button } from '@timui/react'\nimport {\n  MinusIcon,\n  PlusIcon,\n  Volume1Icon,\n  Volume2Icon,\n  VolumeIcon,\n  VolumeXIcon,\n} from 'lucide-react'\n\nexport default function Component() {\n  const [volume, setVolume] = useState(3) // Initialize volume state (0-9)\n\n  const decreaseVolume = () => setVolume((prev) => Math.max(0, prev - 1))\n  const increaseVolume = () => setVolume((prev) => Math.min(6, prev + 1))\n\n  // Optimized volume icon selection\n  const Icon =\n    volume === 0 ? VolumeXIcon : volume < 3 ? VolumeIcon : volume < 5 ? Volume1Icon : Volume2Icon\n\n  return (\n    <div className=\"inline-flex items-center\" role=\"group\" aria-labelledby=\"volume-control\">\n      <span id=\"volume-control\" className=\"sr-only\">\n        Volume Control\n      </span>\n      <Button\n        className=\"rounded-full\"\n        variant=\"outline\"\n        size=\"icon\"\n        aria-label=\"Decrease volume\"\n        onClick={decreaseVolume}\n        disabled={volume === 0}\n      >\n        <MinusIcon size={16} aria-hidden=\"true\" />\n      </Button>\n      <div className=\"flex items-center px-3 text-sm font-medium tabular-nums\" aria-live=\"polite\">\n        <Icon className=\"opacity-60\" size={16} aria-hidden=\"true\" />\n        <span className=\"ms-2\" aria-label={`Current volume is ${volume}`}>\n          {volume}\n        </span>\n      </div>\n      <Button\n        className=\"rounded-full\"\n        variant=\"outline\"\n        size=\"icon\"\n        aria-label=\"Increase volume\"\n        onClick={increaseVolume}\n        disabled={volume === 6}\n      >\n        <PlusIcon size={16} aria-hidden=\"true\" />\n      </Button>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-29.vue",
          "target": "components/ui/button-29.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport {\n  MinusIcon,\n  PlusIcon,\n  Volume1Icon,\n  Volume2Icon,\n  VolumeIcon,\n  VolumeXIcon,\n} from 'lucide-vue-next'\nimport { Button } from '@timui/vue'\n\nconst volume = ref(3)\n\nconst decreaseVolume = () => {\n  volume.value = Math.max(0, volume.value - 1)\n}\n\nconst increaseVolume = () => {\n  volume.value = Math.min(6, volume.value + 1)\n}\n\nconst volumeIcon = computed(() => {\n  if (volume.value === 0) return VolumeXIcon\n  if (volume.value < 3) return VolumeIcon\n  if (volume.value < 5) return Volume1Icon\n  return Volume2Icon\n})\n</script>\n\n<template>\n  <div class=\"inline-flex items-center\" role=\"group\" aria-labelledby=\"volume-control\">\n    <span id=\"volume-control\" class=\"sr-only\">Volume Control</span>\n    <Button\n      class=\"rounded-full\"\n      variant=\"outline\"\n      size=\"icon\"\n      aria-label=\"Decrease volume\"\n      :disabled=\"volume === 0\"\n      @click=\"decreaseVolume\"\n    >\n      <MinusIcon :size=\"16\" aria-hidden=\"true\" />\n    </Button>\n    <div class=\"flex items-center px-3 text-sm font-medium tabular-nums\" aria-live=\"polite\">\n      <component :is=\"volumeIcon\" class=\"opacity-60\" :size=\"16\" aria-hidden=\"true\" />\n      <span class=\"ms-2\" :aria-label=\"`Current volume is ${volume}`\">{{ volume }}</span>\n    </div>\n    <Button\n      class=\"rounded-full\"\n      variant=\"outline\"\n      size=\"icon\"\n      aria-label=\"Increase volume\"\n      :disabled=\"volume === 6\"\n      @click=\"increaseVolume\"\n    >\n      <PlusIcon :size=\"16\" aria-hidden=\"true\" />\n    </Button>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-29.html",
          "target": "components/ui/button-29.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"inline-flex items-center\" role=\"group\" aria-labelledby=\"volume-control\"><span id=\"volume-control\" class=\"sr-only\">Volume Control\n      </span><Button class=\"rounded-full\" variant=\"outline\" size=\"icon\" aria-label=\"Decrease volume\" on-click=\"${decreaseVolume}\" disabled=\"${volume === 0}\"><MinusIcon size=\"${16}\" aria-hidden=\"true\" /></Button><div class=\"flex items-center px-3 text-sm font-medium tabular-nums\" aria-live=\"polite\"><Icon class=\"opacity-60\" size=\"${16}\" aria-hidden=\"true\" /><span class=\"ms-2\" aria-label=\"${`Current volume is ${volume}`}\">${volume}</span></div><Button class=\"rounded-full\" variant=\"outline\" size=\"icon\" aria-label=\"Increase volume\" on-click=\"${increaseVolume}\" disabled=\"${volume === 6}\"><PlusIcon size=\"${16}\" aria-hidden=\"true\" /></Button></div>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-29.wxml",
          "target": "components/ui/button-29/button-29.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"inline-flex items-center\" role=\"group\" aria-labelledby=\"volume-control\"><text id=\"volume-control\" class=\"sr-only\">Volume Control\n      </text><button class=\"rounded-full\" variant=\"outline\" size=\"icon\" aria-label=\"Decrease volume\" bindtap=\"decreaseVolume\" disabled=\"{{volume === 0}}\"><minusicon size=\"{{16}}\" aria-hidden=\"true\" /></button><view class=\"flex items-center px-3 text-sm font-medium tabular-nums\" aria-live=\"polite\"><icon class=\"opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" /><text class=\"ms-2\" aria-label=\"{{`Current volume is ${volume}`}}\">{{ volume }}</text></view><button class=\"rounded-full\" variant=\"outline\" size=\"icon\" aria-label=\"Increase volume\" bindtap=\"increaseVolume\" disabled=\"{{volume === 6}}\"><plusicon size=\"{{16}}\" aria-hidden=\"true\" /></button></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "volume",
          "controls"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-29",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-29",
              "path": "registry/default/components/button/button-29.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-29",
              "path": "registry/default/components/button/button-29.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-29",
              "path": "registry/default/components/button/button-29.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-29",
              "path": "registry/default/components/button/button-29.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · Rounded button"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-30",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/tooltip.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-30.tsx",
          "type": "registry:component",
          "target": "components/ui/button-30.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { cn } from '@timui/core'\nimport { Button, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@timui/react'\nimport { CheckIcon, CopyIcon } from 'lucide-react'\n\nexport default function Component() {\n  const [copied, setCopied] = useState<boolean>(false)\n\n  const handleCopy = async () => {\n    try {\n      // await navigator.clipboard.writeText(\"string to copy\");\n      setCopied(true)\n      setTimeout(() => setCopied(false), 1500)\n    } catch (err) {\n      console.error('Failed to copy text: ', err)\n    }\n  }\n\n  return (\n    <TooltipProvider delayDuration={0}>\n      <Tooltip>\n        <TooltipTrigger asChild>\n          <Button\n            variant=\"outline\"\n            size=\"icon\"\n            className=\"disabled:opacity-100\"\n            onClick={handleCopy}\n            aria-label={copied ? 'Copied' : 'Copy to clipboard'}\n            disabled={copied}\n          >\n            <div\n              className={cn(\n                'transition-all',\n                copied ? 'scale-100 opacity-100' : 'scale-0 opacity-0'\n              )}\n            >\n              <CheckIcon className=\"stroke-emerald-500\" size={16} aria-hidden=\"true\" />\n            </div>\n            <div\n              className={cn(\n                'absolute transition-all',\n                copied ? 'scale-0 opacity-0' : 'scale-100 opacity-100'\n              )}\n            >\n              <CopyIcon size={16} aria-hidden=\"true\" />\n            </div>\n          </Button>\n        </TooltipTrigger>\n        <TooltipContent className=\"px-2 py-1 text-xs\">Click to copy</TooltipContent>\n      </Tooltip>\n    </TooltipProvider>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-30.vue",
          "target": "components/ui/button-30.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { cn } from '@timui/core';\nimport { CheckIcon, CopyIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { Tooltip } from '@timui/vue';\nimport { TooltipContent } from '@timui/vue';\nimport { TooltipProvider } from '@timui/vue';\nimport { TooltipTrigger } from '@timui/vue';\n\n\n\nconst copied = ref<boolean>(false);\n\n</script>\n\n<template>\n  <TooltipProvider :delayDuration=\"0\"><Tooltip><TooltipTrigger as-child><Button variant=\"outline\" size=\"icon\" class=\"disabled:opacity-100\" @click=\"handleCopy\" :aria-label=\"copied ? 'Copied' : 'Copy to clipboard'\" :disabled=\"copied\"><div :class=\"cn(\n                'transition-all',\n                copied ? 'scale-100 opacity-100' : 'scale-0 opacity-0'\n              )\"><CheckIcon class=\"stroke-emerald-500\" :size=\"16\" aria-hidden=\"true\" /></div><div :class=\"cn(\n                'absolute transition-all',\n                copied ? 'scale-0 opacity-0' : 'scale-100 opacity-100'\n              )\"><CopyIcon :size=\"16\" aria-hidden=\"true\" /></div></Button></TooltipTrigger><TooltipContent class=\"px-2 py-1 text-xs\">Click to copy</TooltipContent></Tooltip></TooltipProvider>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-30.html",
          "target": "components/ui/button-30.html",
          "type": "registry:component",
          "content": "<template>\n  <TooltipProvider delayduration=\"${0}\"><Tooltip><TooltipTrigger aschild><Button variant=\"outline\" size=\"icon\" class=\"disabled:opacity-100\" on-click=\"${handleCopy}\" aria-label=\"${copied ? 'Copied' : 'Copy to clipboard'}\" disabled=\"${copied}\"><div class=\"${cn(\n                'transition-all',\n                copied ? 'scale-100 opacity-100' : 'scale-0 opacity-0'\n              )}\"><CheckIcon class=\"stroke-emerald-500\" size=\"${16}\" aria-hidden=\"true\" /></div><div class=\"${cn(\n                'absolute transition-all',\n                copied ? 'scale-0 opacity-0' : 'scale-100 opacity-100'\n              )}\"><CopyIcon size=\"${16}\" aria-hidden=\"true\" /></div></Button></TooltipTrigger><TooltipContent class=\"px-2 py-1 text-xs\">Click to copy</TooltipContent></Tooltip></TooltipProvider>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-30.wxml",
          "target": "components/ui/button-30/button-30.wxml",
          "type": "registry:component",
          "content": "<view>\n  <tooltipprovider delayduration=\"{{0}}\"><tooltip><tooltiptrigger aschild><button variant=\"outline\" size=\"icon\" class=\"disabled:opacity-100\" bindtap=\"handleCopy\" aria-label=\"{{copied ? 'Copied' : 'Copy to clipboard'}}\" disabled=\"{{copied}}\"><view class=\"{{cn(\n                'transition-all',\n                copied ? 'scale-100 opacity-100' : 'scale-0 opacity-0'\n              )}}\"><checkicon class=\"stroke-emerald-500\" size=\"{{16}}\" aria-hidden=\"true\" /></view><view class=\"{{cn(\n                'absolute transition-all',\n                copied ? 'scale-0 opacity-0' : 'scale-100 opacity-100'\n              )}}\"><copyicon size=\"{{16}}\" aria-hidden=\"true\" /></view></button></tooltiptrigger><tooltipcontent class=\"px-2 py-1 text-xs\">Click to copy</tooltipcontent></tooltip></tooltipprovider>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "copy"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-30",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-30",
              "path": "registry/default/components/button/button-30.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-30",
              "path": "registry/default/components/button/button-30.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-30",
              "path": "registry/default/components/button/button-30.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-30",
              "path": "registry/default/components/button/button-30.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/core",
        "@timui/react"
      ]
    },
    {
      "name": "button-31",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-31.tsx",
          "type": "registry:component",
          "target": "components/ui/button-31.tsx",
          "content": "import { Button } from '@timui/react'\nimport { FlipHorizontalIcon, FlipVerticalIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <div className=\"inline-flex -space-x-px rounded-md shadow-xs rtl:space-x-reverse\">\n      <Button\n        className=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\"\n        variant=\"outline\"\n        size=\"icon\"\n        aria-label=\"Flip Horizontal\"\n      >\n        <FlipHorizontalIcon size={16} aria-hidden=\"true\" />\n      </Button>\n      <Button\n        className=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\"\n        variant=\"outline\"\n        size=\"icon\"\n        aria-label=\"Flip Vertical\"\n      >\n        <FlipVerticalIcon size={16} aria-hidden=\"true\" />\n      </Button>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-31.vue",
          "target": "components/ui/button-31.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { FlipHorizontalIcon, FlipVerticalIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"inline-flex -space-x-px rounded-md shadow-xs rtl:space-x-reverse\"><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" variant=\"outline\" size=\"icon\" aria-label=\"Flip Horizontal\"><FlipHorizontalIcon :size=\"16\" aria-hidden=\"true\" /></Button><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" variant=\"outline\" size=\"icon\" aria-label=\"Flip Vertical\"><FlipVerticalIcon :size=\"16\" aria-hidden=\"true\" /></Button></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-31.html",
          "target": "components/ui/button-31.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"inline-flex -space-x-px rounded-md shadow-xs rtl:space-x-reverse\"><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" variant=\"outline\" size=\"icon\" aria-label=\"Flip Horizontal\"><FlipHorizontalIcon size=\"${16}\" aria-hidden=\"true\" /></Button><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" variant=\"outline\" size=\"icon\" aria-label=\"Flip Vertical\"><FlipVerticalIcon size=\"${16}\" aria-hidden=\"true\" /></Button></div>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-31.wxml",
          "target": "components/ui/button-31/button-31.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"inline-flex -space-x-px rounded-md shadow-xs rtl:space-x-reverse\"><button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" variant=\"outline\" size=\"icon\" aria-label=\"Flip Horizontal\"><fliphorizontalicon size=\"{{16}}\" aria-hidden=\"true\" /></button><button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" variant=\"outline\" size=\"icon\" aria-label=\"Flip Vertical\"><flipverticalicon size=\"{{16}}\" aria-hidden=\"true\" /></button></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "toggle group"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-31",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-31",
              "path": "registry/default/components/button/button-31.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-31",
              "path": "registry/default/components/button/button-31.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-31",
              "path": "registry/default/components/button/button-31.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-31",
              "path": "registry/default/components/button/button-31.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-32",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/toggle-group.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-32.tsx",
          "type": "registry:component",
          "target": "components/ui/button-32.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { ToggleGroup, ToggleGroupItem } from '@timui/react'\nimport { AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon } from 'lucide-react'\n\nexport default function Component() {\n  const [value, setValue] = useState<string>('center')\n\n  return (\n    <ToggleGroup\n      className=\"divide-background inline-flex divide-x\"\n      type=\"single\"\n      value={value}\n      onValueChange={(value) => {\n        if (value) setValue(value)\n      }}\n    >\n      <ToggleGroupItem\n        className=\"bg-primary/80 text-primary-foreground hover:bg-primary hover:text-primary-foreground data-[state=on]:bg-primary data-[state=on]:text-primary-foreground\"\n        aria-label=\"Align Left\"\n        value=\"left\"\n      >\n        <AlignLeftIcon size={16} aria-hidden=\"true\" />\n      </ToggleGroupItem>\n      <ToggleGroupItem\n        className=\"bg-primary/80 text-primary-foreground hover:bg-primary hover:text-primary-foreground data-[state=on]:bg-primary data-[state=on]:text-primary-foreground\"\n        aria-label=\"Align Center\"\n        value=\"center\"\n      >\n        <AlignCenterIcon size={16} aria-hidden=\"true\" />\n      </ToggleGroupItem>\n      <ToggleGroupItem\n        className=\"bg-primary/80 text-primary-foreground hover:bg-primary hover:text-primary-foreground data-[state=on]:bg-primary data-[state=on]:text-primary-foreground\"\n        aria-label=\"Align Right\"\n        value=\"right\"\n      >\n        <AlignRightIcon size={16} aria-hidden=\"true\" />\n      </ToggleGroupItem>\n      <ToggleGroupItem\n        className=\"bg-primary/80 text-primary-foreground hover:bg-primary hover:text-primary-foreground data-[state=on]:bg-primary data-[state=on]:text-primary-foreground\"\n        aria-label=\"Align Justify\"\n        value=\"justify\"\n      >\n        <AlignJustifyIcon size={16} aria-hidden=\"true\" />\n      </ToggleGroupItem>\n    </ToggleGroup>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-32.vue",
          "target": "components/ui/button-32.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport {\n  AlignCenterIcon,\n  AlignJustifyIcon,\n  AlignLeftIcon,\n  AlignRightIcon,\n} from 'lucide-vue-next'\nimport { ToggleGroup } from '@timui/vue'\nimport { ToggleGroupItem } from '@timui/vue'\n\nconst value = ref<string>('center')\n\nconst handleValueChange = (next?: string) => {\n  if (next) value.value = next\n}\n</script>\n\n<template>\n  <ToggleGroup\n    class=\"divide-background inline-flex divide-x\"\n    type=\"single\"\n    :value=\"value\"\n    @update:modelValue=\"handleValueChange\"\n  >\n    <ToggleGroupItem\n      class=\"bg-primary/80 text-primary-foreground hover:bg-primary hover:text-primary-foreground data-[state=on]:bg-primary data-[state=on]:text-primary-foreground\"\n      aria-label=\"Align Left\"\n      value=\"left\"\n    >\n      <AlignLeftIcon :size=\"16\" aria-hidden=\"true\" />\n    </ToggleGroupItem>\n    <ToggleGroupItem\n      class=\"bg-primary/80 text-primary-foreground hover:bg-primary hover:text-primary-foreground data-[state=on]:bg-primary data-[state=on]:text-primary-foreground\"\n      aria-label=\"Align Center\"\n      value=\"center\"\n    >\n      <AlignCenterIcon :size=\"16\" aria-hidden=\"true\" />\n    </ToggleGroupItem>\n    <ToggleGroupItem\n      class=\"bg-primary/80 text-primary-foreground hover:bg-primary hover:text-primary-foreground data-[state=on]:bg-primary data-[state=on]:text-primary-foreground\"\n      aria-label=\"Align Right\"\n      value=\"right\"\n    >\n      <AlignRightIcon :size=\"16\" aria-hidden=\"true\" />\n    </ToggleGroupItem>\n    <ToggleGroupItem\n      class=\"bg-primary/80 text-primary-foreground hover:bg-primary hover:text-primary-foreground data-[state=on]:bg-primary data-[state=on]:text-primary-foreground\"\n      aria-label=\"Align Justify\"\n      value=\"justify\"\n    >\n      <AlignJustifyIcon :size=\"16\" aria-hidden=\"true\" />\n    </ToggleGroupItem>\n  </ToggleGroup>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-32.html",
          "target": "components/ui/button-32.html",
          "type": "registry:component",
          "content": "<template>\n  <ToggleGroup class=\"divide-background inline-flex divide-x\" type=\"single\" value=\"${value}\" on-value-change=\"${(value) => {\n        if (value) setValue(value)\n      }}\"><ToggleGroupItem class=\"bg-primary/80 text-primary-foreground hover:bg-primary hover:text-primary-foreground data-[state=on]:bg-primary data-[state=on]:text-primary-foreground\" aria-label=\"Align Left\" value=\"left\"><AlignLeftIcon size=\"${16}\" aria-hidden=\"true\" /></ToggleGroupItem><ToggleGroupItem class=\"bg-primary/80 text-primary-foreground hover:bg-primary hover:text-primary-foreground data-[state=on]:bg-primary data-[state=on]:text-primary-foreground\" aria-label=\"Align Center\" value=\"center\"><AlignCenterIcon size=\"${16}\" aria-hidden=\"true\" /></ToggleGroupItem><ToggleGroupItem class=\"bg-primary/80 text-primary-foreground hover:bg-primary hover:text-primary-foreground data-[state=on]:bg-primary data-[state=on]:text-primary-foreground\" aria-label=\"Align Right\" value=\"right\"><AlignRightIcon size=\"${16}\" aria-hidden=\"true\" /></ToggleGroupItem><ToggleGroupItem class=\"bg-primary/80 text-primary-foreground hover:bg-primary hover:text-primary-foreground data-[state=on]:bg-primary data-[state=on]:text-primary-foreground\" aria-label=\"Align Justify\" value=\"justify\"><AlignJustifyIcon size=\"${16}\" aria-hidden=\"true\" /></ToggleGroupItem></ToggleGroup>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-32.wxml",
          "target": "components/ui/button-32/button-32.wxml",
          "type": "registry:component",
          "content": "<view>\n  <togglegroup class=\"divide-background inline-flex divide-x\" type=\"single\" value=\"{{value}}\" bindchange=\"{\n        if (value) setValue(value)\n      }\"><togglegroupitem class=\"bg-primary/80 text-primary-foreground hover:bg-primary hover:text-primary-foreground data-[state=on]:bg-primary data-[state=on]:text-primary-foreground\" aria-label=\"Align Left\" value=\"left\"><alignlefticon size=\"{{16}}\" aria-hidden=\"true\" /></togglegroupitem><togglegroupitem class=\"bg-primary/80 text-primary-foreground hover:bg-primary hover:text-primary-foreground data-[state=on]:bg-primary data-[state=on]:text-primary-foreground\" aria-label=\"Align Center\" value=\"center\"><aligncentericon size=\"{{16}}\" aria-hidden=\"true\" /></togglegroupitem><togglegroupitem class=\"bg-primary/80 text-primary-foreground hover:bg-primary hover:text-primary-foreground data-[state=on]:bg-primary data-[state=on]:text-primary-foreground\" aria-label=\"Align Right\" value=\"right\"><alignrighticon size=\"{{16}}\" aria-hidden=\"true\" /></togglegroupitem><togglegroupitem class=\"bg-primary/80 text-primary-foreground hover:bg-primary hover:text-primary-foreground data-[state=on]:bg-primary data-[state=on]:text-primary-foreground\" aria-label=\"Align Justify\" value=\"justify\"><alignjustifyicon size=\"{{16}}\" aria-hidden=\"true\" /></togglegroupitem></togglegroup>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "toggle group"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-32",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-32",
              "path": "registry/default/components/button/button-32.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-32",
              "path": "registry/default/components/button/button-32.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-32",
              "path": "registry/default/components/button/button-32.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-32",
              "path": "registry/default/components/button/button-32.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-33",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-33.tsx",
          "type": "registry:component",
          "target": "components/ui/button-33.tsx",
          "content": "import { Button } from '@timui/react'\nimport { EllipsisIcon, FilesIcon, FilmIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <div className=\"inline-flex -space-x-px rounded-md shadow-xs rtl:space-x-reverse\">\n      <Button\n        className=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\"\n        variant=\"outline\"\n      >\n        <FilesIcon className=\"-ms-1 opacity-60\" size={16} aria-hidden=\"true\" />\n        Files\n      </Button>\n      <Button\n        className=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\"\n        variant=\"outline\"\n      >\n        <FilmIcon className=\"-ms-1 opacity-60\" size={16} aria-hidden=\"true\" />\n        Media\n      </Button>\n      <Button\n        className=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\"\n        variant=\"outline\"\n        size=\"icon\"\n        aria-label=\"Menu\"\n      >\n        <EllipsisIcon size={16} aria-hidden=\"true\" />\n      </Button>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-33.vue",
          "target": "components/ui/button-33.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { EllipsisIcon, FilesIcon, FilmIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"inline-flex -space-x-px rounded-md shadow-xs rtl:space-x-reverse\"><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" variant=\"outline\"><FilesIcon class=\"-ms-1 opacity-60\" :size=\"16\" aria-hidden=\"true\" />Files\n      </Button><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" variant=\"outline\"><FilmIcon class=\"-ms-1 opacity-60\" :size=\"16\" aria-hidden=\"true\" />Media\n      </Button><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" variant=\"outline\" size=\"icon\" aria-label=\"Menu\"><EllipsisIcon :size=\"16\" aria-hidden=\"true\" /></Button></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-33.html",
          "target": "components/ui/button-33.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"inline-flex -space-x-px rounded-md shadow-xs rtl:space-x-reverse\"><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" variant=\"outline\"><FilesIcon class=\"-ms-1 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Files\n      </Button><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" variant=\"outline\"><FilmIcon class=\"-ms-1 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Media\n      </Button><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" variant=\"outline\" size=\"icon\" aria-label=\"Menu\"><EllipsisIcon size=\"${16}\" aria-hidden=\"true\" /></Button></div>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-33.wxml",
          "target": "components/ui/button-33/button-33.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"inline-flex -space-x-px rounded-md shadow-xs rtl:space-x-reverse\"><button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" variant=\"outline\"><filesicon class=\"-ms-1 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Files\n      </button><button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" variant=\"outline\"><filmicon class=\"-ms-1 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Media\n      </button><button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" variant=\"outline\" size=\"icon\" aria-label=\"Menu\"><ellipsisicon size=\"{{16}}\" aria-hidden=\"true\" /></button></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "toggle group",
          "dropdown"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-33",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-33",
              "path": "registry/default/components/button/button-33.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-33",
              "path": "registry/default/components/button/button-33.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-33",
              "path": "registry/default/components/button/button-33.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-33",
              "path": "registry/default/components/button/button-33.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-34",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/toggle-group.json"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-34.tsx",
          "type": "registry:component",
          "target": "components/ui/button-34.tsx",
          "content": "import { ToggleGroup, ToggleGroupItem } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <ToggleGroup variant=\"outline\" className=\"inline-flex\" type=\"single\">\n      <ToggleGroupItem value=\"left\">Left</ToggleGroupItem>\n      <ToggleGroupItem value=\"center\">Center</ToggleGroupItem>\n      <ToggleGroupItem value=\"right\">Right</ToggleGroupItem>\n    </ToggleGroup>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-34.vue",
          "target": "components/ui/button-34.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ToggleGroup } from '@timui/vue';\nimport { ToggleGroupItem } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <ToggleGroup variant=\"outline\" class=\"inline-flex\" type=\"single\"><ToggleGroupItem value=\"left\">Left</ToggleGroupItem><ToggleGroupItem value=\"center\">Center</ToggleGroupItem><ToggleGroupItem value=\"right\">Right</ToggleGroupItem></ToggleGroup>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-34.html",
          "target": "components/ui/button-34.html",
          "type": "registry:component",
          "content": "<template>\n  <ToggleGroup variant=\"outline\" class=\"inline-flex\" type=\"single\"><ToggleGroupItem value=\"left\">Left</ToggleGroupItem><ToggleGroupItem value=\"center\">Center</ToggleGroupItem><ToggleGroupItem value=\"right\">Right</ToggleGroupItem></ToggleGroup>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-34.wxml",
          "target": "components/ui/button-34/button-34.wxml",
          "type": "registry:component",
          "content": "<view>\n  <togglegroup variant=\"outline\" class=\"inline-flex\" type=\"single\"><togglegroupitem value=\"left\">Left</togglegroupitem><togglegroupitem value=\"center\">Center</togglegroupitem><togglegroupitem value=\"right\">Right</togglegroupitem></togglegroup>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "toggle group"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-34",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-34",
              "path": "registry/default/components/button/button-34.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-34",
              "path": "registry/default/components/button/button-34.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-34",
              "path": "registry/default/components/button/button-34.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-34",
              "path": "registry/default/components/button/button-34.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · Outlined variant"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-35",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/toggle-group.json"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-35.tsx",
          "type": "registry:component",
          "target": "components/ui/button-35.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { ToggleGroup, ToggleGroupItem } from '@timui/react'\n\nexport default function Component() {\n  const [value, setValue] = useState<string>('left')\n\n  return (\n    <ToggleGroup\n      type=\"single\"\n      variant=\"outline\"\n      value={value}\n      onValueChange={(value) => {\n        if (value) setValue(value)\n      }}\n    >\n      <ToggleGroupItem className=\"flex-1\" value=\"left\">\n        Left\n      </ToggleGroupItem>\n      <ToggleGroupItem className=\"flex-1\" value=\"center\">\n        Center\n      </ToggleGroupItem>\n      <ToggleGroupItem className=\"flex-1\" value=\"right\">\n        Right\n      </ToggleGroupItem>\n    </ToggleGroup>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-35.vue",
          "target": "components/ui/button-35.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { ToggleGroup } from '@timui/vue'\nimport { ToggleGroupItem } from '@timui/vue'\n\nconst value = ref<string>('left')\n\nconst handleValueChange = (next?: string) => {\n  if (next) value.value = next\n}\n</script>\n\n<template>\n  <ToggleGroup\n    type=\"single\"\n    variant=\"outline\"\n    :value=\"value\"\n    @update:modelValue=\"handleValueChange\"\n  >\n    <ToggleGroupItem class=\"flex-1\" value=\"left\">Left</ToggleGroupItem>\n    <ToggleGroupItem class=\"flex-1\" value=\"center\">Center</ToggleGroupItem>\n    <ToggleGroupItem class=\"flex-1\" value=\"right\">Right</ToggleGroupItem>\n  </ToggleGroup>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-35.html",
          "target": "components/ui/button-35.html",
          "type": "registry:component",
          "content": "<template>\n  <ToggleGroup type=\"single\" variant=\"outline\" value=\"${value}\" on-value-change=\"${(value) => {\n        if (value) setValue(value)\n      }}\"><ToggleGroupItem class=\"flex-1\" value=\"left\">Left\n      </ToggleGroupItem><ToggleGroupItem class=\"flex-1\" value=\"center\">Center\n      </ToggleGroupItem><ToggleGroupItem class=\"flex-1\" value=\"right\">Right\n      </ToggleGroupItem></ToggleGroup>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-35.wxml",
          "target": "components/ui/button-35/button-35.wxml",
          "type": "registry:component",
          "content": "<view>\n  <togglegroup type=\"single\" variant=\"outline\" value=\"{{value}}\" bindchange=\"{\n        if (value) setValue(value)\n      }\"><togglegroupitem class=\"flex-1\" value=\"left\">Left\n      </togglegroupitem><togglegroupitem class=\"flex-1\" value=\"center\">Center\n      </togglegroupitem><togglegroupitem class=\"flex-1\" value=\"right\">Right\n      </togglegroupitem></togglegroup>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "toggle group"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-35",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-35",
              "path": "registry/default/components/button/button-35.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-35",
              "path": "registry/default/components/button/button-35.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-35",
              "path": "registry/default/components/button/button-35.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-35",
              "path": "registry/default/components/button/button-35.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · Outlined variant"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-36",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-36.tsx",
          "type": "registry:component",
          "target": "components/ui/button-36.tsx",
          "content": "import { Button } from '@timui/react'\nimport { QrCodeIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <div className=\"divide-primary-foreground/30 inline-flex divide-x rounded-md shadow-xs rtl:space-x-reverse\">\n      <Button\n        className=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\"\n        size=\"icon\"\n        aria-label=\"QR code\"\n      >\n        <QrCodeIcon size={16} aria-hidden=\"true\" />\n      </Button>\n      <Button className=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\">\n        Sign in\n      </Button>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-36.vue",
          "target": "components/ui/button-36.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { QrCodeIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"divide-primary-foreground/30 inline-flex divide-x rounded-md shadow-xs rtl:space-x-reverse\"><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" size=\"icon\" aria-label=\"QR code\"><QrCodeIcon :size=\"16\" aria-hidden=\"true\" /></Button><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\">Sign in\n      </Button></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-36.html",
          "target": "components/ui/button-36.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"divide-primary-foreground/30 inline-flex divide-x rounded-md shadow-xs rtl:space-x-reverse\"><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" size=\"icon\" aria-label=\"QR code\"><QrCodeIcon size=\"${16}\" aria-hidden=\"true\" /></Button><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\">Sign in\n      </Button></div>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-36.wxml",
          "target": "components/ui/button-36/button-36.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"divide-primary-foreground/30 inline-flex divide-x rounded-md shadow-xs rtl:space-x-reverse\"><button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" size=\"icon\" aria-label=\"QR code\"><qrcodeicon size=\"{{16}}\" aria-hidden=\"true\" /></button><button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\">Sign in\n      </button></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-36",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-36",
              "path": "registry/default/components/button/button-36.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-36",
              "path": "registry/default/components/button/button-36.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-36",
              "path": "registry/default/components/button/button-36.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-36",
              "path": "registry/default/components/button/button-36.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-37",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-37.tsx",
          "type": "registry:component",
          "target": "components/ui/button-37.tsx",
          "content": "import { Button } from '@timui/react'\nimport { SquareArrowOutUpRightIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <div className=\"inline-flex -space-x-px rounded-md shadow-xs rtl:space-x-reverse\">\n      <Button\n        className=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\"\n        variant=\"outline\"\n      >\n        Preview\n      </Button>\n      <Button\n        className=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\"\n        variant=\"outline\"\n        size=\"icon\"\n        aria-label=\"Open link\"\n      >\n        <SquareArrowOutUpRightIcon size={16} aria-hidden=\"true\" />\n      </Button>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-37.vue",
          "target": "components/ui/button-37.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { SquareArrowOutUpRightIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"inline-flex -space-x-px rounded-md shadow-xs rtl:space-x-reverse\"><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" variant=\"outline\">Preview\n      </Button><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" variant=\"outline\" size=\"icon\" aria-label=\"Open link\"><SquareArrowOutUpRightIcon :size=\"16\" aria-hidden=\"true\" /></Button></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-37.html",
          "target": "components/ui/button-37.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"inline-flex -space-x-px rounded-md shadow-xs rtl:space-x-reverse\"><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" variant=\"outline\">Preview\n      </Button><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" variant=\"outline\" size=\"icon\" aria-label=\"Open link\"><SquareArrowOutUpRightIcon size=\"${16}\" aria-hidden=\"true\" /></Button></div>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-37.wxml",
          "target": "components/ui/button-37/button-37.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"inline-flex -space-x-px rounded-md shadow-xs rtl:space-x-reverse\"><button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" variant=\"outline\">Preview\n      </button><button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" variant=\"outline\" size=\"icon\" aria-label=\"Open link\"><squarearrowoutuprighticon size=\"{{16}}\" aria-hidden=\"true\" /></button></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-37",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-37",
              "path": "registry/default/components/button/button-37.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-37",
              "path": "registry/default/components/button/button-37.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-37",
              "path": "registry/default/components/button/button-37.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-37",
              "path": "registry/default/components/button/button-37.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-38",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-38.tsx",
          "type": "registry:component",
          "target": "components/ui/button-38.tsx",
          "content": "import { Button } from '@timui/react'\nimport { ChevronDownIcon, PinIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <div className=\"divide-primary-foreground/30 inline-flex divide-x rounded-md shadow-xs rtl:space-x-reverse\">\n      <Button\n        className=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\"\n        size=\"icon\"\n        aria-label=\"Options\"\n      >\n        <ChevronDownIcon size={16} aria-hidden=\"true\" />\n      </Button>\n      <Button className=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\">\n        <PinIcon className=\"-ms-1 opacity-60\" size={16} aria-hidden=\"true\" />\n        Pinned\n      </Button>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-38.vue",
          "target": "components/ui/button-38.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ChevronDownIcon, PinIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"divide-primary-foreground/30 inline-flex divide-x rounded-md shadow-xs rtl:space-x-reverse\"><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" size=\"icon\" aria-label=\"Options\"><ChevronDownIcon :size=\"16\" aria-hidden=\"true\" /></Button><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\"><PinIcon class=\"-ms-1 opacity-60\" :size=\"16\" aria-hidden=\"true\" />Pinned\n      </Button></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-38.html",
          "target": "components/ui/button-38.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"divide-primary-foreground/30 inline-flex divide-x rounded-md shadow-xs rtl:space-x-reverse\"><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" size=\"icon\" aria-label=\"Options\"><ChevronDownIcon size=\"${16}\" aria-hidden=\"true\" /></Button><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\"><PinIcon class=\"-ms-1 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Pinned\n      </Button></div>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-38.wxml",
          "target": "components/ui/button-38/button-38.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"divide-primary-foreground/30 inline-flex divide-x rounded-md shadow-xs rtl:space-x-reverse\"><button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" size=\"icon\" aria-label=\"Options\"><chevrondownicon size=\"{{16}}\" aria-hidden=\"true\" /></button><button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\"><pinicon class=\"-ms-1 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Pinned\n      </button></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "dropdown"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-38",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-38",
              "path": "registry/default/components/button/button-38.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-38",
              "path": "registry/default/components/button/button-38.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-38",
              "path": "registry/default/components/button/button-38.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-38",
              "path": "registry/default/components/button/button-38.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-39",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-39.tsx",
          "type": "registry:component",
          "target": "components/ui/button-39.tsx",
          "content": "import { Button } from '@timui/react'\nimport { ChevronDownIcon, GitForkIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <div className=\"divide-primary-foreground/30 inline-flex divide-x rounded-md shadow-xs rtl:space-x-reverse\">\n      <Button className=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\">\n        <GitForkIcon className=\"opacity-60\" size={16} aria-hidden=\"true\" />\n        Fork\n        <span className=\"border-primary-foreground/30 text-primary-foreground/60 ms-1 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">\n          18\n        </span>\n      </Button>\n      <Button\n        className=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\"\n        size=\"icon\"\n        aria-label=\"Options\"\n      >\n        <ChevronDownIcon size={16} aria-hidden=\"true\" />\n      </Button>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-39.vue",
          "target": "components/ui/button-39.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ChevronDownIcon, GitForkIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"divide-primary-foreground/30 inline-flex divide-x rounded-md shadow-xs rtl:space-x-reverse\"><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\"><GitForkIcon class=\"opacity-60\" :size=\"16\" aria-hidden=\"true\" />Fork\n        <span class=\"border-primary-foreground/30 text-primary-foreground/60 ms-1 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">18\n        </span></Button><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" size=\"icon\" aria-label=\"Options\"><ChevronDownIcon :size=\"16\" aria-hidden=\"true\" /></Button></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-39.html",
          "target": "components/ui/button-39.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"divide-primary-foreground/30 inline-flex divide-x rounded-md shadow-xs rtl:space-x-reverse\"><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\"><GitForkIcon class=\"opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Fork\n        <span class=\"border-primary-foreground/30 text-primary-foreground/60 ms-1 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">18\n        </span></Button><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" size=\"icon\" aria-label=\"Options\"><ChevronDownIcon size=\"${16}\" aria-hidden=\"true\" /></Button></div>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-39.wxml",
          "target": "components/ui/button-39/button-39.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"divide-primary-foreground/30 inline-flex divide-x rounded-md shadow-xs rtl:space-x-reverse\"><button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\"><gitforkicon class=\"opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Fork\n        <text class=\"border-primary-foreground/30 text-primary-foreground/60 ms-1 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">18\n        </text></button><button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" size=\"icon\" aria-label=\"Options\"><chevrondownicon size=\"{{16}}\" aria-hidden=\"true\" /></button></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "dropdown",
          "counter"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-39",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-39",
              "path": "registry/default/components/button/button-39.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-39",
              "path": "registry/default/components/button/button-39.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-39",
              "path": "registry/default/components/button/button-39.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-39",
              "path": "registry/default/components/button/button-39.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-41",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-41.tsx",
          "type": "registry:component",
          "target": "components/ui/button-41.tsx",
          "content": "import { Button } from '@timui/react'\nimport { ChevronLeftIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <Button className=\"relative ps-12\">\n      Previous\n      <span className=\"bg-primary-foreground/15 pointer-events-none absolute inset-y-0 start-0 flex w-9 items-center justify-center\">\n        <ChevronLeftIcon className=\"opacity-60\" size={16} aria-hidden=\"true\" />\n      </span>\n    </Button>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-41.vue",
          "target": "components/ui/button-41.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ChevronLeftIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Button class=\"relative ps-12\">Previous\n      <span class=\"bg-primary-foreground/15 pointer-events-none absolute inset-y-0 start-0 flex w-9 items-center justify-center\"><ChevronLeftIcon class=\"opacity-60\" :size=\"16\" aria-hidden=\"true\" /></span></Button>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-41.html",
          "target": "components/ui/button-41.html",
          "type": "registry:component",
          "content": "<template>\n  <Button class=\"relative ps-12\">Previous\n      <span class=\"bg-primary-foreground/15 pointer-events-none absolute inset-y-0 start-0 flex w-9 items-center justify-center\"><ChevronLeftIcon class=\"opacity-60\" size=\"${16}\" aria-hidden=\"true\" /></span></Button>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-41.wxml",
          "target": "components/ui/button-41/button-41.wxml",
          "type": "registry:component",
          "content": "<view>\n  <button class=\"relative ps-12\">Previous\n      <text class=\"bg-primary-foreground/15 pointer-events-none absolute inset-y-0 start-0 flex w-9 items-center justify-center\"><chevronlefticon class=\"opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" /></text></button>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "previous"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-41",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-41",
              "path": "registry/default/components/button/button-41.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-41",
              "path": "registry/default/components/button/button-41.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-41",
              "path": "registry/default/components/button/button-41.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-41",
              "path": "registry/default/components/button/button-41.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-42",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-42.tsx",
          "type": "registry:component",
          "target": "components/ui/button-42.tsx",
          "content": "import { Button } from '@timui/react'\nimport { ChevronRightIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <Button className=\"relative pe-12\">\n      Next\n      <span className=\"bg-primary-foreground/15 pointer-events-none absolute inset-y-0 end-0 flex w-9 items-center justify-center\">\n        <ChevronRightIcon className=\"opacity-60\" size={16} aria-hidden=\"true\" />\n      </span>\n    </Button>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-42.vue",
          "target": "components/ui/button-42.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ChevronRightIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Button class=\"relative pe-12\">Next\n      <span class=\"bg-primary-foreground/15 pointer-events-none absolute inset-y-0 end-0 flex w-9 items-center justify-center\"><ChevronRightIcon class=\"opacity-60\" :size=\"16\" aria-hidden=\"true\" /></span></Button>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-42.html",
          "target": "components/ui/button-42.html",
          "type": "registry:component",
          "content": "<template>\n  <Button class=\"relative pe-12\">Next\n      <span class=\"bg-primary-foreground/15 pointer-events-none absolute inset-y-0 end-0 flex w-9 items-center justify-center\"><ChevronRightIcon class=\"opacity-60\" size=\"${16}\" aria-hidden=\"true\" /></span></Button>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-42.wxml",
          "target": "components/ui/button-42/button-42.wxml",
          "type": "registry:component",
          "content": "<view>\n  <button class=\"relative pe-12\">Next\n      <text class=\"bg-primary-foreground/15 pointer-events-none absolute inset-y-0 end-0 flex w-9 items-center justify-center\"><chevronrighticon class=\"opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" /></text></button>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "next"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-42",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-42",
              "path": "registry/default/components/button/button-42.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-42",
              "path": "registry/default/components/button/button-42.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-42",
              "path": "registry/default/components/button/button-42.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-42",
              "path": "registry/default/components/button/button-42.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-43",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-43.tsx",
          "type": "registry:component",
          "target": "components/ui/button-43.tsx",
          "content": "import { Button } from '@timui/react'\nimport { ThumbsUpIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <Button className=\"py-0 pe-0\" variant=\"outline\">\n      <ThumbsUpIcon className=\"opacity-60\" size={16} aria-hidden=\"true\" />\n      Like\n      <span className=\"text-muted-foreground before:bg-input relative ms-1 inline-flex h-full items-center justify-center rounded-full px-3 text-xs font-medium before:absolute before:inset-0 before:left-0 before:w-px\">\n        86\n      </span>\n    </Button>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-43.vue",
          "target": "components/ui/button-43.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ThumbsUpIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Button class=\"py-0 pe-0\" variant=\"outline\"><ThumbsUpIcon class=\"opacity-60\" :size=\"16\" aria-hidden=\"true\" />Like\n      <span class=\"text-muted-foreground before:bg-input relative ms-1 inline-flex h-full items-center justify-center rounded-full px-3 text-xs font-medium before:absolute before:inset-0 before:left-0 before:w-px\">86\n      </span></Button>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-43.html",
          "target": "components/ui/button-43.html",
          "type": "registry:component",
          "content": "<template>\n  <Button class=\"py-0 pe-0\" variant=\"outline\"><ThumbsUpIcon class=\"opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Like\n      <span class=\"text-muted-foreground before:bg-input relative ms-1 inline-flex h-full items-center justify-center rounded-full px-3 text-xs font-medium before:absolute before:inset-0 before:left-0 before:w-px\">86\n      </span></Button>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-43.wxml",
          "target": "components/ui/button-43/button-43.wxml",
          "type": "registry:component",
          "content": "<view>\n  <button class=\"py-0 pe-0\" variant=\"outline\"><thumbsupicon class=\"opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Like\n      <text class=\"text-muted-foreground before:bg-input relative ms-1 inline-flex h-full items-center justify-center rounded-full px-3 text-xs font-medium before:absolute before:inset-0 before:left-0 before:w-px\">86\n      </text></button>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "like",
          "counter"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-43",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-43",
              "path": "registry/default/components/button/button-43.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-43",
              "path": "registry/default/components/button/button-43.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-43",
              "path": "registry/default/components/button/button-43.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-43",
              "path": "registry/default/components/button/button-43.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · Rounded button"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-44",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-44.tsx",
          "type": "registry:component",
          "target": "components/ui/button-44.tsx",
          "content": "import { Button } from '@timui/react'\nimport { StarIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <Button>\n      <StarIcon className=\"-ms-1 opacity-60\" size={16} aria-hidden=\"true\" />\n      <span className=\"flex items-baseline gap-2\">\n        Star\n        <span className=\"text-primary-foreground/60 text-xs\">729</span>\n      </span>\n    </Button>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-44.vue",
          "target": "components/ui/button-44.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { StarIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Button><StarIcon class=\"-ms-1 opacity-60\" :size=\"16\" aria-hidden=\"true\" /><span class=\"flex items-baseline gap-2\">Star\n        <span class=\"text-primary-foreground/60 text-xs\">729</span></span></Button>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-44.html",
          "target": "components/ui/button-44.html",
          "type": "registry:component",
          "content": "<template>\n  <Button><StarIcon class=\"-ms-1 opacity-60\" size=\"${16}\" aria-hidden=\"true\" /><span class=\"flex items-baseline gap-2\">Star\n        <span class=\"text-primary-foreground/60 text-xs\">729</span></span></Button>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-44.wxml",
          "target": "components/ui/button-44/button-44.wxml",
          "type": "registry:component",
          "content": "<view>\n  <button><staricon class=\"-ms-1 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" /><text class=\"flex items-baseline gap-2\">Star\n        <text class=\"text-primary-foreground/60 text-xs\">729</text></text></button>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "like",
          "counter"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-44",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-44",
              "path": "registry/default/components/button/button-44.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-44",
              "path": "registry/default/components/button/button-44.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-44",
              "path": "registry/default/components/button/button-44.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-44",
              "path": "registry/default/components/button/button-44.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-45",
      "type": "registry:component",
      "dependencies": [
        "@remixicon/react",
        "@timui/react"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-45.tsx",
          "type": "registry:component",
          "target": "components/ui/button-45.tsx",
          "content": "import { RiFacebookFill, RiGithubFill, RiGoogleFill, RiTwitterXFill } from '@remixicon/react'\nimport { Button } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"inline-flex flex-wrap gap-2\">\n      <Button variant=\"outline\" aria-label=\"Login with Google\" size=\"icon\">\n        <RiGoogleFill size={16} aria-hidden=\"true\" />\n      </Button>\n      <Button variant=\"outline\" aria-label=\"Login with Facebook\" size=\"icon\">\n        <RiFacebookFill size={16} aria-hidden=\"true\" />\n      </Button>\n      <Button variant=\"outline\" aria-label=\"Login with X\" size=\"icon\">\n        <RiTwitterXFill size={16} aria-hidden=\"true\" />\n      </Button>\n      <Button variant=\"outline\" aria-label=\"Login with GitHub\" size=\"icon\">\n        <RiGithubFill size={16} aria-hidden=\"true\" />\n      </Button>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-45.vue",
          "target": "components/ui/button-45.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ChromeIcon, FacebookIcon, GithubIcon, TwitterIcon } from 'lucide-vue-next'\nimport { Button } from '@timui/vue'\n</script>\n\n<template>\n  <div class=\"inline-flex flex-wrap gap-2\">\n    <Button variant=\"outline\" aria-label=\"Login with Google\" size=\"icon\"><ChromeIcon :size=\"16\" aria-hidden=\"true\" /></Button>\n    <Button variant=\"outline\" aria-label=\"Login with Facebook\" size=\"icon\"><FacebookIcon :size=\"16\" aria-hidden=\"true\" /></Button>\n    <Button variant=\"outline\" aria-label=\"Login with X\" size=\"icon\"><TwitterIcon :size=\"16\" aria-hidden=\"true\" /></Button>\n    <Button variant=\"outline\" aria-label=\"Login with GitHub\" size=\"icon\"><GithubIcon :size=\"16\" aria-hidden=\"true\" /></Button>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-45.html",
          "target": "components/ui/button-45.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"inline-flex flex-wrap gap-2\"><Button variant=\"outline\" aria-label=\"Login with Google\" size=\"icon\"><RiGoogleFill size=\"${16}\" aria-hidden=\"true\" /></Button><Button variant=\"outline\" aria-label=\"Login with Facebook\" size=\"icon\"><RiFacebookFill size=\"${16}\" aria-hidden=\"true\" /></Button><Button variant=\"outline\" aria-label=\"Login with X\" size=\"icon\"><RiTwitterXFill size=\"${16}\" aria-hidden=\"true\" /></Button><Button variant=\"outline\" aria-label=\"Login with GitHub\" size=\"icon\"><RiGithubFill size=\"${16}\" aria-hidden=\"true\" /></Button></div>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-45.wxml",
          "target": "components/ui/button-45/button-45.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"inline-flex flex-wrap gap-2\"><button variant=\"outline\" aria-label=\"Login with Google\" size=\"icon\"><rigooglefill size=\"{{16}}\" aria-hidden=\"true\" /></button><button variant=\"outline\" aria-label=\"Login with Facebook\" size=\"icon\"><rifacebookfill size=\"{{16}}\" aria-hidden=\"true\" /></button><button variant=\"outline\" aria-label=\"Login with X\" size=\"icon\"><ritwitterxfill size=\"{{16}}\" aria-hidden=\"true\" /></button><button variant=\"outline\" aria-label=\"Login with GitHub\" size=\"icon\"><rigithubfill size=\"{{16}}\" aria-hidden=\"true\" /></button></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "social",
          "login",
          "authentication"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-45",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-45",
              "path": "registry/default/components/button/button-45.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-45",
              "path": "registry/default/components/button/button-45.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-45",
              "path": "registry/default/components/button/button-45.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-45",
              "path": "registry/default/components/button/button-45.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@remixicon/react",
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ]
    },
    {
      "name": "button-46",
      "type": "registry:component",
      "dependencies": [
        "@remixicon/react",
        "@timui/react"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-46.tsx",
          "type": "registry:component",
          "target": "components/ui/button-46.tsx",
          "content": "import { RiFacebookFill, RiGithubFill, RiGoogleFill, RiTwitterXFill } from '@remixicon/react'\nimport { Button } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"flex flex-wrap gap-2\">\n      <Button className=\"flex-1\" variant=\"outline\" aria-label=\"Login with Google\" size=\"icon\">\n        <RiGoogleFill className=\"dark:text-primary text-[#DB4437]\" size={16} aria-hidden=\"true\" />\n      </Button>\n      <Button className=\"flex-1\" variant=\"outline\" aria-label=\"Login with Facebook\" size=\"icon\">\n        <RiFacebookFill className=\"dark:text-primary text-[#1877f2]\" size={16} aria-hidden=\"true\" />\n      </Button>\n      <Button className=\"flex-1\" variant=\"outline\" aria-label=\"Login with X\" size=\"icon\">\n        <RiTwitterXFill className=\"dark:text-primary text-[#14171a]\" size={16} aria-hidden=\"true\" />\n      </Button>\n      <Button className=\"flex-1\" variant=\"outline\" aria-label=\"Login with GitHub\" size=\"icon\">\n        <RiGithubFill className=\"dark:text-primary text-black\" size={16} aria-hidden=\"true\" />\n      </Button>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-46.vue",
          "target": "components/ui/button-46.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ChromeIcon, FacebookIcon, GithubIcon, TwitterIcon } from 'lucide-vue-next'\nimport { Button } from '@timui/vue'\n</script>\n\n<template>\n  <div class=\"flex flex-wrap gap-2\">\n    <Button class=\"flex-1\" variant=\"outline\" aria-label=\"Login with Google\" size=\"icon\"><ChromeIcon class=\"dark:text-primary text-[#DB4437]\" :size=\"16\" aria-hidden=\"true\" /></Button>\n    <Button class=\"flex-1\" variant=\"outline\" aria-label=\"Login with Facebook\" size=\"icon\"><FacebookIcon class=\"dark:text-primary text-[#1877f2]\" :size=\"16\" aria-hidden=\"true\" /></Button>\n    <Button class=\"flex-1\" variant=\"outline\" aria-label=\"Login with X\" size=\"icon\"><TwitterIcon class=\"dark:text-primary text-[#14171a]\" :size=\"16\" aria-hidden=\"true\" /></Button>\n    <Button class=\"flex-1\" variant=\"outline\" aria-label=\"Login with GitHub\" size=\"icon\"><GithubIcon class=\"dark:text-primary text-black\" :size=\"16\" aria-hidden=\"true\" /></Button>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-46.html",
          "target": "components/ui/button-46.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex flex-wrap gap-2\"><Button class=\"flex-1\" variant=\"outline\" aria-label=\"Login with Google\" size=\"icon\"><RiGoogleFill class=\"dark:text-primary text-[#DB4437]\" size=\"${16}\" aria-hidden=\"true\" /></Button><Button class=\"flex-1\" variant=\"outline\" aria-label=\"Login with Facebook\" size=\"icon\"><RiFacebookFill class=\"dark:text-primary text-[#1877f2]\" size=\"${16}\" aria-hidden=\"true\" /></Button><Button class=\"flex-1\" variant=\"outline\" aria-label=\"Login with X\" size=\"icon\"><RiTwitterXFill class=\"dark:text-primary text-[#14171a]\" size=\"${16}\" aria-hidden=\"true\" /></Button><Button class=\"flex-1\" variant=\"outline\" aria-label=\"Login with GitHub\" size=\"icon\"><RiGithubFill class=\"dark:text-primary text-black\" size=\"${16}\" aria-hidden=\"true\" /></Button></div>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-46.wxml",
          "target": "components/ui/button-46/button-46.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex flex-wrap gap-2\"><button class=\"flex-1\" variant=\"outline\" aria-label=\"Login with Google\" size=\"icon\"><rigooglefill class=\"dark:text-primary text-[#DB4437]\" size=\"{{16}}\" aria-hidden=\"true\" /></button><button class=\"flex-1\" variant=\"outline\" aria-label=\"Login with Facebook\" size=\"icon\"><rifacebookfill class=\"dark:text-primary text-[#1877f2]\" size=\"{{16}}\" aria-hidden=\"true\" /></button><button class=\"flex-1\" variant=\"outline\" aria-label=\"Login with X\" size=\"icon\"><ritwitterxfill class=\"dark:text-primary text-[#14171a]\" size=\"{{16}}\" aria-hidden=\"true\" /></button><button class=\"flex-1\" variant=\"outline\" aria-label=\"Login with GitHub\" size=\"icon\"><rigithubfill class=\"dark:text-primary text-black\" size=\"{{16}}\" aria-hidden=\"true\" /></button></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "social",
          "login",
          "authentication"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-46",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-46",
              "path": "registry/default/components/button/button-46.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-46",
              "path": "registry/default/components/button/button-46.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-46",
              "path": "registry/default/components/button/button-46.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-46",
              "path": "registry/default/components/button/button-46.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@remixicon/react",
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ]
    },
    {
      "name": "button-47",
      "type": "registry:component",
      "dependencies": [
        "@remixicon/react",
        "@timui/react"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-47.tsx",
          "type": "registry:component",
          "target": "components/ui/button-47.tsx",
          "content": "import { RiFacebookFill, RiGithubFill, RiGoogleFill, RiTwitterXFill } from '@remixicon/react'\nimport { Button } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"flex flex-col gap-2\">\n      <Button variant=\"outline\">\n        <RiGoogleFill\n          className=\"me-1 text-[#DB4437] dark:text-white/60\"\n          size={16}\n          aria-hidden=\"true\"\n        />\n        Login with Google\n      </Button>\n      <Button variant=\"outline\">\n        <RiTwitterXFill\n          className=\"me-1 text-[#14171a] dark:text-white/60\"\n          size={16}\n          aria-hidden=\"true\"\n        />\n        Login with X\n      </Button>\n      <Button variant=\"outline\">\n        <RiFacebookFill\n          className=\"me-1 text-[#1877f2] dark:text-white/60\"\n          size={16}\n          aria-hidden=\"true\"\n        />\n        Login with Facebook\n      </Button>\n      <Button variant=\"outline\">\n        <RiGithubFill\n          className=\"me-1 text-[#333333] dark:text-white/60\"\n          size={16}\n          aria-hidden=\"true\"\n        />\n        Login with GitHub\n      </Button>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-47.vue",
          "target": "components/ui/button-47.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ChromeIcon, FacebookIcon, GithubIcon, TwitterIcon } from 'lucide-vue-next'\nimport { Button } from '@timui/vue'\n</script>\n\n<template>\n  <div class=\"flex flex-col gap-2\">\n    <Button variant=\"outline\"><ChromeIcon class=\"me-1 text-[#DB4437] dark:text-white/60\" :size=\"16\" aria-hidden=\"true\" />Login with Google</Button>\n    <Button variant=\"outline\"><TwitterIcon class=\"me-1 text-[#14171a] dark:text-white/60\" :size=\"16\" aria-hidden=\"true\" />Login with X</Button>\n    <Button variant=\"outline\"><FacebookIcon class=\"me-1 text-[#1877f2] dark:text-white/60\" :size=\"16\" aria-hidden=\"true\" />Login with Facebook</Button>\n    <Button variant=\"outline\"><GithubIcon class=\"me-1 text-[#333333] dark:text-white/60\" :size=\"16\" aria-hidden=\"true\" />Login with GitHub</Button>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-47.html",
          "target": "components/ui/button-47.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex flex-col gap-2\"><Button variant=\"outline\"><RiGoogleFill class=\"me-1 text-[#DB4437] dark:text-white/60\" size=\"${16}\" aria-hidden=\"true\" />Login with Google\n      </Button><Button variant=\"outline\"><RiTwitterXFill class=\"me-1 text-[#14171a] dark:text-white/60\" size=\"${16}\" aria-hidden=\"true\" />Login with X\n      </Button><Button variant=\"outline\"><RiFacebookFill class=\"me-1 text-[#1877f2] dark:text-white/60\" size=\"${16}\" aria-hidden=\"true\" />Login with Facebook\n      </Button><Button variant=\"outline\"><RiGithubFill class=\"me-1 text-[#333333] dark:text-white/60\" size=\"${16}\" aria-hidden=\"true\" />Login with GitHub\n      </Button></div>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-47.wxml",
          "target": "components/ui/button-47/button-47.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex flex-col gap-2\"><button variant=\"outline\"><rigooglefill class=\"me-1 text-[#DB4437] dark:text-white/60\" size=\"{{16}}\" aria-hidden=\"true\" />Login with Google\n      </button><button variant=\"outline\"><ritwitterxfill class=\"me-1 text-[#14171a] dark:text-white/60\" size=\"{{16}}\" aria-hidden=\"true\" />Login with X\n      </button><button variant=\"outline\"><rifacebookfill class=\"me-1 text-[#1877f2] dark:text-white/60\" size=\"{{16}}\" aria-hidden=\"true\" />Login with Facebook\n      </button><button variant=\"outline\"><rigithubfill class=\"me-1 text-[#333333] dark:text-white/60\" size=\"{{16}}\" aria-hidden=\"true\" />Login with GitHub\n      </button></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "social",
          "login",
          "authentication"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-47",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-47",
              "path": "registry/default/components/button/button-47.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-47",
              "path": "registry/default/components/button/button-47.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-47",
              "path": "registry/default/components/button/button-47.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-47",
              "path": "registry/default/components/button/button-47.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@remixicon/react",
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ]
    },
    {
      "name": "button-48",
      "type": "registry:component",
      "dependencies": [
        "@remixicon/react",
        "@timui/react"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-48.tsx",
          "type": "registry:component",
          "target": "components/ui/button-48.tsx",
          "content": "import { RiFacebookFill, RiGithubFill, RiGoogleFill, RiTwitterXFill } from '@remixicon/react'\nimport { Button } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"flex flex-col gap-2\">\n      <Button className=\"bg-[#DB4437] text-white after:flex-1 hover:bg-[#DB4437]/90\">\n        <span className=\"pointer-events-none me-2 flex-1\">\n          <RiGoogleFill className=\"opacity-60\" size={16} aria-hidden=\"true\" />\n        </span>\n        Login with Google\n      </Button>\n      <Button className=\"bg-[#14171a] text-white after:flex-1 hover:bg-[#14171a]/90\">\n        <span className=\"pointer-events-none me-2 flex-1\">\n          <RiTwitterXFill className=\"opacity-60\" size={16} aria-hidden=\"true\" />\n        </span>\n        Login with X\n      </Button>\n      <Button className=\"bg-[#1877f2] text-white after:flex-1 hover:bg-[#1877f2]/90\">\n        <span className=\"pointer-events-none me-2 flex-1\">\n          <RiFacebookFill className=\"opacity-60\" size={16} aria-hidden=\"true\" />\n        </span>\n        Login with Facebook\n      </Button>\n      <Button className=\"bg-[#333333] text-white after:flex-1 hover:bg-[#333333]/90\">\n        <span className=\"pointer-events-none me-2 flex-1\">\n          <RiGithubFill className=\"opacity-60\" size={16} aria-hidden=\"true\" />\n        </span>\n        Login with GitHub\n      </Button>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-48.vue",
          "target": "components/ui/button-48.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ChromeIcon, FacebookIcon, GithubIcon, TwitterIcon } from 'lucide-vue-next'\nimport { Button } from '@timui/vue'\n</script>\n\n<template>\n  <div class=\"flex flex-col gap-2\">\n    <Button class=\"bg-[#DB4437] text-white after:flex-1 hover:bg-[#DB4437]/90\"><span class=\"pointer-events-none me-2 flex-1\"><ChromeIcon class=\"opacity-60\" :size=\"16\" aria-hidden=\"true\" /></span>Login with Google</Button>\n    <Button class=\"bg-[#14171a] text-white after:flex-1 hover:bg-[#14171a]/90\"><span class=\"pointer-events-none me-2 flex-1\"><TwitterIcon class=\"opacity-60\" :size=\"16\" aria-hidden=\"true\" /></span>Login with X</Button>\n    <Button class=\"bg-[#1877f2] text-white after:flex-1 hover:bg-[#1877f2]/90\"><span class=\"pointer-events-none me-2 flex-1\"><FacebookIcon class=\"opacity-60\" :size=\"16\" aria-hidden=\"true\" /></span>Login with Facebook</Button>\n    <Button class=\"bg-[#333333] text-white after:flex-1 hover:bg-[#333333]/90\"><span class=\"pointer-events-none me-2 flex-1\"><GithubIcon class=\"opacity-60\" :size=\"16\" aria-hidden=\"true\" /></span>Login with GitHub</Button>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-48.html",
          "target": "components/ui/button-48.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex flex-col gap-2\"><Button class=\"bg-[#DB4437] text-white after:flex-1 hover:bg-[#DB4437]/90\"><span class=\"pointer-events-none me-2 flex-1\"><RiGoogleFill class=\"opacity-60\" size=\"${16}\" aria-hidden=\"true\" /></span>Login with Google\n      </Button><Button class=\"bg-[#14171a] text-white after:flex-1 hover:bg-[#14171a]/90\"><span class=\"pointer-events-none me-2 flex-1\"><RiTwitterXFill class=\"opacity-60\" size=\"${16}\" aria-hidden=\"true\" /></span>Login with X\n      </Button><Button class=\"bg-[#1877f2] text-white after:flex-1 hover:bg-[#1877f2]/90\"><span class=\"pointer-events-none me-2 flex-1\"><RiFacebookFill class=\"opacity-60\" size=\"${16}\" aria-hidden=\"true\" /></span>Login with Facebook\n      </Button><Button class=\"bg-[#333333] text-white after:flex-1 hover:bg-[#333333]/90\"><span class=\"pointer-events-none me-2 flex-1\"><RiGithubFill class=\"opacity-60\" size=\"${16}\" aria-hidden=\"true\" /></span>Login with GitHub\n      </Button></div>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-48.wxml",
          "target": "components/ui/button-48/button-48.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex flex-col gap-2\"><button class=\"bg-[#DB4437] text-white after:flex-1 hover:bg-[#DB4437]/90\"><text class=\"pointer-events-none me-2 flex-1\"><rigooglefill class=\"opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" /></text>Login with Google\n      </button><button class=\"bg-[#14171a] text-white after:flex-1 hover:bg-[#14171a]/90\"><text class=\"pointer-events-none me-2 flex-1\"><ritwitterxfill class=\"opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" /></text>Login with X\n      </button><button class=\"bg-[#1877f2] text-white after:flex-1 hover:bg-[#1877f2]/90\"><text class=\"pointer-events-none me-2 flex-1\"><rifacebookfill class=\"opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" /></text>Login with Facebook\n      </button><button class=\"bg-[#333333] text-white after:flex-1 hover:bg-[#333333]/90\"><text class=\"pointer-events-none me-2 flex-1\"><rigithubfill class=\"opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" /></text>Login with GitHub\n      </button></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "social",
          "login",
          "authentication"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-48",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-48",
              "path": "registry/default/components/button/button-48.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-48",
              "path": "registry/default/components/button/button-48.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-48",
              "path": "registry/default/components/button/button-48.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-48",
              "path": "registry/default/components/button/button-48.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@remixicon/react",
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ]
    },
    {
      "name": "button-49",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-49.tsx",
          "type": "registry:component",
          "target": "components/ui/button-49.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Button } from '@timui/react'\nimport { ChevronDownIcon, ChevronUpIcon } from 'lucide-react'\n\nexport default function Component() {\n  const [isExpanded, setIsExpanded] = useState<boolean>(false)\n\n  const toggleExpand = () => {\n    setIsExpanded((prevState) => !prevState)\n  }\n\n  return (\n    <Button\n      className=\"gap-1\"\n      variant=\"ghost\"\n      onClick={toggleExpand}\n      aria-expanded={isExpanded}\n      aria-controls=\"expandable-content\" // Use this ID on the element that this button controls\n    >\n      {isExpanded ? 'Show less' : 'Show more'}\n      {isExpanded ? (\n        <ChevronUpIcon className=\"-me-1\" size={16} aria-hidden=\"true\" />\n      ) : (\n        <ChevronDownIcon className=\"-me-1\" size={16} aria-hidden=\"true\" />\n      )}\n    </Button>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-49.vue",
          "target": "components/ui/button-49.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { ChevronDownIcon, ChevronUpIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\nconst isExpanded = ref<boolean>(false);\n\n</script>\n\n<template>\n  <Button class=\"gap-1\" variant=\"ghost\" @click=\"toggleExpand\" :aria-expanded=\"isExpanded\" aria-controls=\"expandable-content\"><template v-if=\"isExpanded\">\n{{ 'Show less' }}\n</template>\n<template v-else>\n{{ 'Show more' }}\n</template><template v-if=\"isExpanded\">\n<ChevronUpIcon class=\"-me-1\" :size=\"16\" aria-hidden=\"true\" />\n</template>\n<template v-else>\n<ChevronDownIcon class=\"-me-1\" :size=\"16\" aria-hidden=\"true\" />\n</template></Button>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-49.html",
          "target": "components/ui/button-49.html",
          "type": "registry:component",
          "content": "<template>\n  <Button class=\"gap-1\" variant=\"ghost\" on-click=\"${toggleExpand}\" aria-expanded=\"${isExpanded}\" aria-controls=\"expandable-content\"><!-- if isExpanded -->\n${'Show less'}\n<!-- else -->\n${'Show more'}\n<!-- endif --><!-- if isExpanded -->\n<ChevronUpIcon class=\"-me-1\" size=\"${16}\" aria-hidden=\"true\" />\n<!-- else -->\n<ChevronDownIcon class=\"-me-1\" size=\"${16}\" aria-hidden=\"true\" />\n<!-- endif --></Button>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-49.wxml",
          "target": "components/ui/button-49/button-49.wxml",
          "type": "registry:component",
          "content": "<view>\n  <button class=\"gap-1\" variant=\"ghost\" bindtap=\"toggleExpand\" aria-expanded=\"{{isExpanded}}\" aria-controls=\"expandable-content\"><block wx:if=\"{{isExpanded}}\">\n{{ 'Show less' }}\n</block>\n<block wx:else>\n{{ 'Show more' }}\n</block><block wx:if=\"{{isExpanded}}\">\n<chevronupicon class=\"-me-1\" size=\"{{16}}\" aria-hidden=\"true\" />\n</block>\n<block wx:else>\n<chevrondownicon class=\"-me-1\" size=\"{{16}}\" aria-hidden=\"true\" />\n</block></button>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "collapsible"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-49",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-49",
              "path": "registry/default/components/button/button-49.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-49",
              "path": "registry/default/components/button/button-49.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-49",
              "path": "registry/default/components/button/button-49.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-49",
              "path": "registry/default/components/button/button-49.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-50",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-50.tsx",
          "type": "registry:component",
          "target": "components/ui/button-50.tsx",
          "content": "import { Button } from '@timui/react'\nimport { ChevronLeftIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <Button variant=\"link\" className=\"gap-1\">\n      <ChevronLeftIcon className=\"opacity-60\" size={16} aria-hidden=\"true\" />\n      Go back\n    </Button>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-50.vue",
          "target": "components/ui/button-50.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ChevronLeftIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Button variant=\"link\" class=\"gap-1\"><ChevronLeftIcon class=\"opacity-60\" :size=\"16\" aria-hidden=\"true\" />Go back\n    </Button>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-50.html",
          "target": "components/ui/button-50.html",
          "type": "registry:component",
          "content": "<template>\n  <Button variant=\"link\" class=\"gap-1\"><ChevronLeftIcon class=\"opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Go back\n    </Button>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-50.wxml",
          "target": "components/ui/button-50/button-50.wxml",
          "type": "registry:component",
          "content": "<view>\n  <button variant=\"link\" class=\"gap-1\"><chevronlefticon class=\"opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Go back\n    </button>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "back"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-50",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-50",
              "path": "registry/default/components/button/button-50.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-50",
              "path": "registry/default/components/button/button-50.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-50",
              "path": "registry/default/components/button/button-50.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-50",
              "path": "registry/default/components/button/button-50.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-51",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-51.tsx",
          "type": "registry:component",
          "target": "components/ui/button-51.tsx",
          "content": "'use client'\n\nimport { Button } from '@timui/react'\nimport { CircleUserRoundIcon } from 'lucide-react'\n\nimport { useFileUpload } from '@/registry/default/hooks/use-file-upload'\n\nexport default function Component() {\n  const [{ files }, { removeFile, openFileDialog, getInputProps }] = useFileUpload({\n    accept: 'image/*',\n  })\n\n  const previewUrl = files[0]?.preview || null\n  const fileName = files[0]?.file.name || null\n\n  return (\n    <div className=\"flex flex-col items-center gap-2\">\n      <div className=\"inline-flex items-center gap-2 align-top\">\n        <div\n          className=\"border-input relative flex size-9 shrink-0 items-center justify-center overflow-hidden rounded-md border\"\n          aria-label={previewUrl ? 'Preview of uploaded image' : 'Default user avatar'}\n        >\n          {previewUrl ? (\n            <img\n              className=\"size-full object-cover\"\n              src={previewUrl}\n              alt=\"Preview of uploaded image\"\n              width={32}\n              height={32}\n            />\n          ) : (\n            <div aria-hidden=\"true\">\n              <CircleUserRoundIcon className=\"opacity-60\" size={16} />\n            </div>\n          )}\n        </div>\n        <div className=\"relative inline-block\">\n          <Button onClick={openFileDialog} aria-haspopup=\"dialog\">\n            {fileName ? 'Change image' : 'Upload image'}\n          </Button>\n          <input\n            {...getInputProps()}\n            className=\"sr-only\"\n            aria-label=\"Upload image file\"\n            tabIndex={-1}\n          />\n        </div>\n      </div>\n      {fileName && (\n        <div className=\"inline-flex gap-2 text-xs\">\n          <p className=\"text-muted-foreground truncate\" aria-live=\"polite\">\n            {fileName}\n          </p>{' '}\n          <button\n            onClick={() => removeFile(files[0]?.id)}\n            className=\"text-destructive font-medium hover:underline\"\n            aria-label={`Remove ${fileName}`}\n          >\n            Remove\n          </button>\n        </div>\n      )}\n      <p aria-live=\"polite\" role=\"region\" className=\"text-muted-foreground mt-2 text-xs\">\n        Basic image uploader ∙{' '}\n        <a\n          href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\"\n          className=\"hover:text-foreground underline\"\n        >\n          Docs\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/hooks/use-file-upload.ts",
          "type": "registry:hook",
          "target": "components/ui/button-51/use-file-upload.ts",
          "content": "'use client'\n\nimport type React from 'react'\nimport {\n  useCallback,\n  useRef,\n  useState,\n  type ChangeEvent,\n  type DragEvent,\n  type InputHTMLAttributes,\n} from 'react'\n\nexport type FileMetadata = {\n  name: string\n  size: number\n  type: string\n  url: string\n  id: string\n}\n\nexport type FileWithPreview = {\n  file: File | FileMetadata\n  id: string\n  preview?: string\n}\n\nexport type FileUploadOptions = {\n  maxFiles?: number // Only used when multiple is true, defaults to Infinity\n  maxSize?: number // in bytes\n  accept?: string\n  multiple?: boolean // Defaults to false\n  initialFiles?: FileMetadata[]\n  onFilesChange?: (files: FileWithPreview[]) => void // Callback when files change\n  onFilesAdded?: (addedFiles: FileWithPreview[]) => void // Callback when new files are added\n}\n\nexport type FileUploadState = {\n  files: FileWithPreview[]\n  isDragging: boolean\n  errors: string[]\n}\n\nexport type FileUploadActions = {\n  addFiles: (files: FileList | File[]) => void\n  removeFile: (id: string) => void\n  clearFiles: () => void\n  clearErrors: () => void\n  handleDragEnter: (e: DragEvent<HTMLElement>) => void\n  handleDragLeave: (e: DragEvent<HTMLElement>) => void\n  handleDragOver: (e: DragEvent<HTMLElement>) => void\n  handleDrop: (e: DragEvent<HTMLElement>) => void\n  handleFileChange: (e: ChangeEvent<HTMLInputElement>) => void\n  openFileDialog: () => void\n  getInputProps: (\n    props?: InputHTMLAttributes<HTMLInputElement>\n  ) => InputHTMLAttributes<HTMLInputElement> & {\n    ref: React.Ref<HTMLInputElement>\n  }\n}\n\nexport const useFileUpload = (\n  options: FileUploadOptions = {}\n): [FileUploadState, FileUploadActions] => {\n  const {\n    maxFiles = Infinity,\n    maxSize = Infinity,\n    accept = '*',\n    multiple = false,\n    initialFiles = [],\n    onFilesChange,\n    onFilesAdded,\n  } = options\n\n  const [state, setState] = useState<FileUploadState>({\n    files: initialFiles.map((file) => ({\n      file,\n      id: file.id,\n      preview: file.url,\n    })),\n    isDragging: false,\n    errors: [],\n  })\n\n  const inputRef = useRef<HTMLInputElement>(null)\n\n  const validateFile = useCallback(\n    (file: File | FileMetadata): string | null => {\n      if (file instanceof File) {\n        if (file.size > maxSize) {\n          return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n        }\n      } else {\n        if (file.size > maxSize) {\n          return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n        }\n      }\n\n      if (accept !== '*') {\n        const acceptedTypes = accept.split(',').map((type) => type.trim())\n        const fileType = file instanceof File ? file.type || '' : file.type\n        const fileExtension = `.${file instanceof File ? file.name.split('.').pop() : file.name.split('.').pop()}`\n\n        const isAccepted = acceptedTypes.some((type) => {\n          if (type.startsWith('.')) {\n            return fileExtension.toLowerCase() === type.toLowerCase()\n          }\n          if (type.endsWith('/*')) {\n            const baseType = type.split('/')[0]\n            return fileType.startsWith(`${baseType}/`)\n          }\n          return fileType === type\n        })\n\n        if (!isAccepted) {\n          return `File \"${file instanceof File ? file.name : file.name}\" is not an accepted file type.`\n        }\n      }\n\n      return null\n    },\n    [accept, maxSize]\n  )\n\n  const createPreview = useCallback((file: File | FileMetadata): string | undefined => {\n    if (file instanceof File) {\n      return URL.createObjectURL(file)\n    }\n    return file.url\n  }, [])\n\n  const generateUniqueId = useCallback((file: File | FileMetadata): string => {\n    if (file instanceof File) {\n      return `${file.name}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`\n    }\n    return file.id\n  }, [])\n\n  const clearFiles = useCallback(() => {\n    setState((prev) => {\n      // Clean up object URLs\n      prev.files.forEach((file) => {\n        if (file.preview && file.file instanceof File && file.file.type.startsWith('image/')) {\n          URL.revokeObjectURL(file.preview)\n        }\n      })\n\n      if (inputRef.current) {\n        inputRef.current.value = ''\n      }\n\n      const newState = {\n        ...prev,\n        files: [],\n        errors: [],\n      }\n\n      onFilesChange?.(newState.files)\n      return newState\n    })\n  }, [onFilesChange])\n\n  const addFiles = useCallback(\n    (newFiles: FileList | File[]) => {\n      if (!newFiles || newFiles.length === 0) return\n\n      const newFilesArray = Array.from(newFiles)\n      const errors: string[] = []\n\n      // Clear existing errors when new files are uploaded\n      setState((prev) => ({ ...prev, errors: [] }))\n\n      // In single file mode, clear existing files first\n      if (!multiple) {\n        clearFiles()\n      }\n\n      // Check if adding these files would exceed maxFiles (only in multiple mode)\n      if (\n        multiple &&\n        maxFiles !== Infinity &&\n        state.files.length + newFilesArray.length > maxFiles\n      ) {\n        errors.push(`You can only upload a maximum of ${maxFiles} files.`)\n        setState((prev) => ({ ...prev, errors }))\n        return\n      }\n\n      const validFiles: FileWithPreview[] = []\n\n      newFilesArray.forEach((file) => {\n        // Only check for duplicates if multiple files are allowed\n        if (multiple) {\n          const isDuplicate = state.files.some(\n            (existingFile) =>\n              existingFile.file.name === file.name && existingFile.file.size === file.size\n          )\n\n          // Skip duplicate files silently\n          if (isDuplicate) {\n            return\n          }\n        }\n\n        // Check file size\n        if (file.size > maxSize) {\n          errors.push(\n            multiple\n              ? `Some files exceed the maximum size of ${formatBytes(maxSize)}.`\n              : `File exceeds the maximum size of ${formatBytes(maxSize)}.`\n          )\n          return\n        }\n\n        const error = validateFile(file)\n        if (error) {\n          errors.push(error)\n        } else {\n          validFiles.push({\n            file,\n            id: generateUniqueId(file),\n            preview: createPreview(file),\n          })\n        }\n      })\n\n      // Only update state if we have valid files to add\n      if (validFiles.length > 0) {\n        // Call the onFilesAdded callback with the newly added valid files\n        onFilesAdded?.(validFiles)\n\n        setState((prev) => {\n          const newFiles = !multiple ? validFiles : [...prev.files, ...validFiles]\n          onFilesChange?.(newFiles)\n          return {\n            ...prev,\n            files: newFiles,\n            errors,\n          }\n        })\n      } else if (errors.length > 0) {\n        setState((prev) => ({\n          ...prev,\n          errors,\n        }))\n      }\n\n      // Reset input value after handling files\n      if (inputRef.current) {\n        inputRef.current.value = ''\n      }\n    },\n    [\n      state.files,\n      maxFiles,\n      multiple,\n      maxSize,\n      validateFile,\n      createPreview,\n      generateUniqueId,\n      clearFiles,\n      onFilesChange,\n      onFilesAdded,\n    ]\n  )\n\n  const removeFile = useCallback(\n    (id: string) => {\n      setState((prev) => {\n        const fileToRemove = prev.files.find((file) => file.id === id)\n        if (\n          fileToRemove &&\n          fileToRemove.preview &&\n          fileToRemove.file instanceof File &&\n          fileToRemove.file.type.startsWith('image/')\n        ) {\n          URL.revokeObjectURL(fileToRemove.preview)\n        }\n\n        const newFiles = prev.files.filter((file) => file.id !== id)\n        onFilesChange?.(newFiles)\n\n        return {\n          ...prev,\n          files: newFiles,\n          errors: [],\n        }\n      })\n    },\n    [onFilesChange]\n  )\n\n  const clearErrors = useCallback(() => {\n    setState((prev) => ({\n      ...prev,\n      errors: [],\n    }))\n  }, [])\n\n  const handleDragEnter = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n    setState((prev) => ({ ...prev, isDragging: true }))\n  }, [])\n\n  const handleDragLeave = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n\n    if (e.currentTarget.contains(e.relatedTarget as Node)) {\n      return\n    }\n\n    setState((prev) => ({ ...prev, isDragging: false }))\n  }, [])\n\n  const handleDragOver = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n  }, [])\n\n  const handleDrop = useCallback(\n    (e: DragEvent<HTMLElement>) => {\n      e.preventDefault()\n      e.stopPropagation()\n      setState((prev) => ({ ...prev, isDragging: false }))\n\n      // Don't process files if the input is disabled\n      if (inputRef.current?.disabled) {\n        return\n      }\n\n      if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n        // In single file mode, only use the first file\n        if (!multiple) {\n          const file = e.dataTransfer.files[0]\n          addFiles([file])\n        } else {\n          addFiles(e.dataTransfer.files)\n        }\n      }\n    },\n    [addFiles, multiple]\n  )\n\n  const handleFileChange = useCallback(\n    (e: ChangeEvent<HTMLInputElement>) => {\n      if (e.target.files && e.target.files.length > 0) {\n        addFiles(e.target.files)\n      }\n    },\n    [addFiles]\n  )\n\n  const openFileDialog = useCallback(() => {\n    if (inputRef.current) {\n      inputRef.current.click()\n    }\n  }, [])\n\n  const getInputProps = useCallback(\n    (props: InputHTMLAttributes<HTMLInputElement> = {}) => {\n      return {\n        ...props,\n        type: 'file' as const,\n        onChange: handleFileChange,\n        accept: props.accept || accept,\n        multiple: props.multiple !== undefined ? props.multiple : multiple,\n        ref: inputRef,\n      }\n    },\n    [accept, multiple, handleFileChange]\n  )\n\n  return [\n    state,\n    {\n      addFiles,\n      removeFile,\n      clearFiles,\n      clearErrors,\n      handleDragEnter,\n      handleDragLeave,\n      handleDragOver,\n      handleDrop,\n      handleFileChange,\n      openFileDialog,\n      getInputProps,\n    },\n  ]\n}\n\n// Helper function to format bytes to human-readable format\nexport const formatBytes = (bytes: number, decimals = 2): string => {\n  if (bytes === 0) return '0 Bytes'\n\n  const k = 1024\n  const dm = decimals < 0 ? 0 : decimals\n  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']\n\n  const i = Math.floor(Math.log(bytes) / Math.log(k))\n\n  return Number.parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + sizes[i]\n}\n"
        },
        {
          "path": "registry/default/components/button/button-51.vue",
          "target": "components/ui/button-51.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { CircleUserRoundIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { useFileUpload } from '@/registry/default/hooks/use-file-upload-vue';\n\nconst [{ files }, { removeFile, openFileDialog, getInputProps }] = useFileUpload({\n  accept: 'image/*',\n});\n\nconst previewUrl = computed(() => files.value[0]?.preview ?? null);\nconst fileName = computed(() => files.value[0]?.file.name ?? null);\n\nfunction removeCurrentFile() {\n  const fileId = files.value[0]?.id;\n  if (fileId) {\n    removeFile(fileId);\n  }\n}\n</script>\n\n<template>\n  <div class=\"flex flex-col items-center gap-2\">\n    <div class=\"inline-flex items-center gap-2 align-top\">\n      <div\n        class=\"border-input relative flex size-9 shrink-0 items-center justify-center overflow-hidden rounded-md border\"\n        :aria-label=\"previewUrl ? 'Preview of uploaded image' : 'Default user avatar'\"\n      >\n        <template v-if=\"previewUrl\">\n          <img\n            class=\"size-full object-cover\"\n            :src=\"previewUrl\"\n            alt=\"Preview of uploaded image\"\n            :width=\"32\"\n            :height=\"32\"\n          />\n        </template>\n        <template v-else>\n          <div aria-hidden=\"true\">\n            <CircleUserRoundIcon class=\"opacity-60\" :size=\"16\" />\n          </div>\n        </template>\n      </div>\n      <div class=\"relative inline-block\">\n        <Button @click=\"openFileDialog\" aria-haspopup=\"dialog\">\n          {{ fileName ? 'Change image' : 'Upload image' }}\n        </Button>\n        <input\n          v-bind=\"getInputProps()\"\n          class=\"sr-only\"\n          aria-label=\"Upload image file\"\n          :tabIndex=\"-1\"\n        />\n      </div>\n    </div>\n    <div v-if=\"fileName\" class=\"inline-flex gap-2 text-xs\">\n      <p class=\"text-muted-foreground truncate\" aria-live=\"polite\">{{ fileName }}</p>\n      <button\n        @click=\"removeCurrentFile\"\n        class=\"text-destructive font-medium hover:underline\"\n        :aria-label=\"`Remove ${fileName}`\"\n      >\n        Remove\n      </button>\n    </div>\n    <p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">\n      Basic image uploader ∙\n      <a\n        href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\"\n        class=\"hover:text-foreground underline\"\n      >\n        Docs\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-51.html",
          "target": "components/ui/button-51.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex flex-col items-center gap-2\"><div class=\"inline-flex items-center gap-2 align-top\"><div class=\"border-input relative flex size-9 shrink-0 items-center justify-center overflow-hidden rounded-md border\" aria-label=\"${previewUrl ? 'Preview of uploaded image' : 'Default user avatar'}\"><!-- if previewUrl -->\n<img class=\"size-full object-cover\" src=\"${previewUrl}\" alt=\"Preview of uploaded image\" width=\"${32}\" height=\"${32}\" />\n<!-- else -->\n<div aria-hidden=\"true\"><CircleUserRoundIcon class=\"opacity-60\" size=\"${16}\" /></div>\n<!-- endif --></div><div class=\"relative inline-block\"><Button on-click=\"${openFileDialog}\" aria-haspopup=\"dialog\"><!-- if fileName -->\n${'Change image'}\n<!-- else -->\n${'Upload image'}\n<!-- endif --></Button><input class=\"sr-only\" aria-label=\"Upload image file\" tabindex=\"${-1}\" /></div></div><!-- if fileName -->\n<div class=\"inline-flex gap-2 text-xs\"><p class=\"text-muted-foreground truncate\" aria-live=\"polite\">${fileName}</p>${' '}<button on-click=\"${() => removeFile(files[0]?.id)}\" class=\"text-destructive font-medium hover:underline\" aria-label=\"${`Remove ${fileName}`}\">Remove\n          </button></div>\n<!-- endif --><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Basic image uploader ∙${' '}<a href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\" class=\"hover:text-foreground underline\">Docs\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-51.wxml",
          "target": "components/ui/button-51/button-51.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex flex-col items-center gap-2\"><view class=\"inline-flex items-center gap-2 align-top\"><view class=\"border-input relative flex size-9 shrink-0 items-center justify-center overflow-hidden rounded-md border\" aria-label=\"{{previewUrl ? 'Preview of uploaded image' : 'Default user avatar'}}\"><block wx:if=\"{{previewUrl}}\">\n<image class=\"size-full object-cover\" src=\"{{previewUrl}}\" alt=\"Preview of uploaded image\" width=\"{{32}}\" height=\"{{32}}\" />\n</block>\n<block wx:else>\n<view aria-hidden=\"true\"><circleuserroundicon class=\"opacity-60\" size=\"{{16}}\" /></view>\n</block></view><view class=\"relative inline-block\"><button bindtap=\"openFileDialog\" aria-haspopup=\"dialog\"><block wx:if=\"{{fileName}}\">\n{{ 'Change image' }}\n</block>\n<block wx:else>\n{{ 'Upload image' }}\n</block></button><input class=\"sr-only\" aria-label=\"Upload image file\" tabindex=\"{{-1}}\" /></view></view><view wx:if=\"{{fileName}}\" class=\"inline-flex gap-2 text-xs\"><text class=\"text-muted-foreground truncate\" aria-live=\"polite\">{{ fileName }}</text>{{ ' ' }}<button bindtap=\"removeFile(files[0]?.id)\" class=\"text-destructive font-medium hover:underline\" aria-label=\"{{`Remove ${fileName}`}}\">Remove\n          </button></view><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Basic image uploader ∙{{ ' ' }}<a href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\" class=\"hover:text-foreground underline\">Docs\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "upload",
          "user",
          "avatar",
          "profile",
          "image"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-51",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-51",
              "path": "registry/default/components/button/button-51.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-51",
              "path": "registry/default/components/button/button-51.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-51",
              "path": "registry/default/components/button/button-51.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-51",
              "path": "registry/default/components/button/button-51.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button",
        "file-upload"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-52",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-52.tsx",
          "type": "registry:component",
          "target": "components/ui/button-52.tsx",
          "content": "'use client'\n\nimport { Button } from '@timui/react'\nimport { CircleUserRoundIcon, XIcon } from 'lucide-react'\n\nimport { useFileUpload } from '@/registry/default/hooks/use-file-upload'\n\nexport default function Component() {\n  const [{ files }, { removeFile, openFileDialog, getInputProps }] = useFileUpload({\n    accept: 'image/*',\n  })\n\n  const previewUrl = files[0]?.preview || null\n  const fileName = files[0]?.file.name || null\n\n  return (\n    <div className=\"flex flex-col items-center gap-2\">\n      <div className=\"relative inline-flex\">\n        <Button\n          variant=\"outline\"\n          className=\"relative size-16 overflow-hidden p-0 shadow-none\"\n          onClick={openFileDialog}\n          aria-label={previewUrl ? 'Change image' : 'Upload image'}\n        >\n          {previewUrl ? (\n            <img\n              className=\"size-full object-cover\"\n              src={previewUrl}\n              alt=\"Preview of uploaded image\"\n              width={64}\n              height={64}\n              style={{ objectFit: 'cover' }}\n            />\n          ) : (\n            <div aria-hidden=\"true\">\n              <CircleUserRoundIcon className=\"size-4 opacity-60\" />\n            </div>\n          )}\n        </Button>\n        {previewUrl && (\n          <Button\n            onClick={() => removeFile(files[0]?.id)}\n            size=\"icon\"\n            className=\"border-background focus-visible:border-background absolute -top-2 -right-2 size-6 rounded-full border-2 shadow-none\"\n            aria-label=\"Remove image\"\n          >\n            <XIcon className=\"size-3.5\" />\n          </Button>\n        )}\n        <input\n          {...getInputProps()}\n          className=\"sr-only\"\n          aria-label=\"Upload image file\"\n          tabIndex={-1}\n        />\n      </div>\n      {fileName && <p className=\"text-muted-foreground text-xs\">{fileName}</p>}\n      <p aria-live=\"polite\" role=\"region\" className=\"text-muted-foreground mt-2 text-xs\">\n        Avatar upload button\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/hooks/use-file-upload.ts",
          "type": "registry:hook",
          "target": "components/ui/button-52/use-file-upload.ts",
          "content": "'use client'\n\nimport type React from 'react'\nimport {\n  useCallback,\n  useRef,\n  useState,\n  type ChangeEvent,\n  type DragEvent,\n  type InputHTMLAttributes,\n} from 'react'\n\nexport type FileMetadata = {\n  name: string\n  size: number\n  type: string\n  url: string\n  id: string\n}\n\nexport type FileWithPreview = {\n  file: File | FileMetadata\n  id: string\n  preview?: string\n}\n\nexport type FileUploadOptions = {\n  maxFiles?: number // Only used when multiple is true, defaults to Infinity\n  maxSize?: number // in bytes\n  accept?: string\n  multiple?: boolean // Defaults to false\n  initialFiles?: FileMetadata[]\n  onFilesChange?: (files: FileWithPreview[]) => void // Callback when files change\n  onFilesAdded?: (addedFiles: FileWithPreview[]) => void // Callback when new files are added\n}\n\nexport type FileUploadState = {\n  files: FileWithPreview[]\n  isDragging: boolean\n  errors: string[]\n}\n\nexport type FileUploadActions = {\n  addFiles: (files: FileList | File[]) => void\n  removeFile: (id: string) => void\n  clearFiles: () => void\n  clearErrors: () => void\n  handleDragEnter: (e: DragEvent<HTMLElement>) => void\n  handleDragLeave: (e: DragEvent<HTMLElement>) => void\n  handleDragOver: (e: DragEvent<HTMLElement>) => void\n  handleDrop: (e: DragEvent<HTMLElement>) => void\n  handleFileChange: (e: ChangeEvent<HTMLInputElement>) => void\n  openFileDialog: () => void\n  getInputProps: (\n    props?: InputHTMLAttributes<HTMLInputElement>\n  ) => InputHTMLAttributes<HTMLInputElement> & {\n    ref: React.Ref<HTMLInputElement>\n  }\n}\n\nexport const useFileUpload = (\n  options: FileUploadOptions = {}\n): [FileUploadState, FileUploadActions] => {\n  const {\n    maxFiles = Infinity,\n    maxSize = Infinity,\n    accept = '*',\n    multiple = false,\n    initialFiles = [],\n    onFilesChange,\n    onFilesAdded,\n  } = options\n\n  const [state, setState] = useState<FileUploadState>({\n    files: initialFiles.map((file) => ({\n      file,\n      id: file.id,\n      preview: file.url,\n    })),\n    isDragging: false,\n    errors: [],\n  })\n\n  const inputRef = useRef<HTMLInputElement>(null)\n\n  const validateFile = useCallback(\n    (file: File | FileMetadata): string | null => {\n      if (file instanceof File) {\n        if (file.size > maxSize) {\n          return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n        }\n      } else {\n        if (file.size > maxSize) {\n          return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n        }\n      }\n\n      if (accept !== '*') {\n        const acceptedTypes = accept.split(',').map((type) => type.trim())\n        const fileType = file instanceof File ? file.type || '' : file.type\n        const fileExtension = `.${file instanceof File ? file.name.split('.').pop() : file.name.split('.').pop()}`\n\n        const isAccepted = acceptedTypes.some((type) => {\n          if (type.startsWith('.')) {\n            return fileExtension.toLowerCase() === type.toLowerCase()\n          }\n          if (type.endsWith('/*')) {\n            const baseType = type.split('/')[0]\n            return fileType.startsWith(`${baseType}/`)\n          }\n          return fileType === type\n        })\n\n        if (!isAccepted) {\n          return `File \"${file instanceof File ? file.name : file.name}\" is not an accepted file type.`\n        }\n      }\n\n      return null\n    },\n    [accept, maxSize]\n  )\n\n  const createPreview = useCallback((file: File | FileMetadata): string | undefined => {\n    if (file instanceof File) {\n      return URL.createObjectURL(file)\n    }\n    return file.url\n  }, [])\n\n  const generateUniqueId = useCallback((file: File | FileMetadata): string => {\n    if (file instanceof File) {\n      return `${file.name}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`\n    }\n    return file.id\n  }, [])\n\n  const clearFiles = useCallback(() => {\n    setState((prev) => {\n      // Clean up object URLs\n      prev.files.forEach((file) => {\n        if (file.preview && file.file instanceof File && file.file.type.startsWith('image/')) {\n          URL.revokeObjectURL(file.preview)\n        }\n      })\n\n      if (inputRef.current) {\n        inputRef.current.value = ''\n      }\n\n      const newState = {\n        ...prev,\n        files: [],\n        errors: [],\n      }\n\n      onFilesChange?.(newState.files)\n      return newState\n    })\n  }, [onFilesChange])\n\n  const addFiles = useCallback(\n    (newFiles: FileList | File[]) => {\n      if (!newFiles || newFiles.length === 0) return\n\n      const newFilesArray = Array.from(newFiles)\n      const errors: string[] = []\n\n      // Clear existing errors when new files are uploaded\n      setState((prev) => ({ ...prev, errors: [] }))\n\n      // In single file mode, clear existing files first\n      if (!multiple) {\n        clearFiles()\n      }\n\n      // Check if adding these files would exceed maxFiles (only in multiple mode)\n      if (\n        multiple &&\n        maxFiles !== Infinity &&\n        state.files.length + newFilesArray.length > maxFiles\n      ) {\n        errors.push(`You can only upload a maximum of ${maxFiles} files.`)\n        setState((prev) => ({ ...prev, errors }))\n        return\n      }\n\n      const validFiles: FileWithPreview[] = []\n\n      newFilesArray.forEach((file) => {\n        // Only check for duplicates if multiple files are allowed\n        if (multiple) {\n          const isDuplicate = state.files.some(\n            (existingFile) =>\n              existingFile.file.name === file.name && existingFile.file.size === file.size\n          )\n\n          // Skip duplicate files silently\n          if (isDuplicate) {\n            return\n          }\n        }\n\n        // Check file size\n        if (file.size > maxSize) {\n          errors.push(\n            multiple\n              ? `Some files exceed the maximum size of ${formatBytes(maxSize)}.`\n              : `File exceeds the maximum size of ${formatBytes(maxSize)}.`\n          )\n          return\n        }\n\n        const error = validateFile(file)\n        if (error) {\n          errors.push(error)\n        } else {\n          validFiles.push({\n            file,\n            id: generateUniqueId(file),\n            preview: createPreview(file),\n          })\n        }\n      })\n\n      // Only update state if we have valid files to add\n      if (validFiles.length > 0) {\n        // Call the onFilesAdded callback with the newly added valid files\n        onFilesAdded?.(validFiles)\n\n        setState((prev) => {\n          const newFiles = !multiple ? validFiles : [...prev.files, ...validFiles]\n          onFilesChange?.(newFiles)\n          return {\n            ...prev,\n            files: newFiles,\n            errors,\n          }\n        })\n      } else if (errors.length > 0) {\n        setState((prev) => ({\n          ...prev,\n          errors,\n        }))\n      }\n\n      // Reset input value after handling files\n      if (inputRef.current) {\n        inputRef.current.value = ''\n      }\n    },\n    [\n      state.files,\n      maxFiles,\n      multiple,\n      maxSize,\n      validateFile,\n      createPreview,\n      generateUniqueId,\n      clearFiles,\n      onFilesChange,\n      onFilesAdded,\n    ]\n  )\n\n  const removeFile = useCallback(\n    (id: string) => {\n      setState((prev) => {\n        const fileToRemove = prev.files.find((file) => file.id === id)\n        if (\n          fileToRemove &&\n          fileToRemove.preview &&\n          fileToRemove.file instanceof File &&\n          fileToRemove.file.type.startsWith('image/')\n        ) {\n          URL.revokeObjectURL(fileToRemove.preview)\n        }\n\n        const newFiles = prev.files.filter((file) => file.id !== id)\n        onFilesChange?.(newFiles)\n\n        return {\n          ...prev,\n          files: newFiles,\n          errors: [],\n        }\n      })\n    },\n    [onFilesChange]\n  )\n\n  const clearErrors = useCallback(() => {\n    setState((prev) => ({\n      ...prev,\n      errors: [],\n    }))\n  }, [])\n\n  const handleDragEnter = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n    setState((prev) => ({ ...prev, isDragging: true }))\n  }, [])\n\n  const handleDragLeave = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n\n    if (e.currentTarget.contains(e.relatedTarget as Node)) {\n      return\n    }\n\n    setState((prev) => ({ ...prev, isDragging: false }))\n  }, [])\n\n  const handleDragOver = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n  }, [])\n\n  const handleDrop = useCallback(\n    (e: DragEvent<HTMLElement>) => {\n      e.preventDefault()\n      e.stopPropagation()\n      setState((prev) => ({ ...prev, isDragging: false }))\n\n      // Don't process files if the input is disabled\n      if (inputRef.current?.disabled) {\n        return\n      }\n\n      if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n        // In single file mode, only use the first file\n        if (!multiple) {\n          const file = e.dataTransfer.files[0]\n          addFiles([file])\n        } else {\n          addFiles(e.dataTransfer.files)\n        }\n      }\n    },\n    [addFiles, multiple]\n  )\n\n  const handleFileChange = useCallback(\n    (e: ChangeEvent<HTMLInputElement>) => {\n      if (e.target.files && e.target.files.length > 0) {\n        addFiles(e.target.files)\n      }\n    },\n    [addFiles]\n  )\n\n  const openFileDialog = useCallback(() => {\n    if (inputRef.current) {\n      inputRef.current.click()\n    }\n  }, [])\n\n  const getInputProps = useCallback(\n    (props: InputHTMLAttributes<HTMLInputElement> = {}) => {\n      return {\n        ...props,\n        type: 'file' as const,\n        onChange: handleFileChange,\n        accept: props.accept || accept,\n        multiple: props.multiple !== undefined ? props.multiple : multiple,\n        ref: inputRef,\n      }\n    },\n    [accept, multiple, handleFileChange]\n  )\n\n  return [\n    state,\n    {\n      addFiles,\n      removeFile,\n      clearFiles,\n      clearErrors,\n      handleDragEnter,\n      handleDragLeave,\n      handleDragOver,\n      handleDrop,\n      handleFileChange,\n      openFileDialog,\n      getInputProps,\n    },\n  ]\n}\n\n// Helper function to format bytes to human-readable format\nexport const formatBytes = (bytes: number, decimals = 2): string => {\n  if (bytes === 0) return '0 Bytes'\n\n  const k = 1024\n  const dm = decimals < 0 ? 0 : decimals\n  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']\n\n  const i = Math.floor(Math.log(bytes) / Math.log(k))\n\n  return Number.parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + sizes[i]\n}\n"
        },
        {
          "path": "registry/default/components/button/button-52.vue",
          "target": "components/ui/button-52.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { CircleUserRoundIcon, XIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { useFileUpload } from '@/registry/default/hooks/use-file-upload-vue';\n\nconst [{ files }, { removeFile, openFileDialog, getInputProps }] = useFileUpload({\n  accept: 'image/*',\n});\n\nconst previewUrl = computed(() => files.value[0]?.preview ?? null);\nconst fileName = computed(() => files.value[0]?.file.name ?? null);\n\nfunction removeCurrentFile() {\n  const fileId = files.value[0]?.id;\n  if (fileId) {\n    removeFile(fileId);\n  }\n}\n</script>\n\n<template>\n  <div class=\"flex flex-col items-center gap-2\">\n    <div class=\"relative inline-flex\">\n      <Button\n        variant=\"outline\"\n        class=\"relative size-16 overflow-hidden p-0 shadow-none\"\n        @click=\"openFileDialog\"\n        :aria-label=\"previewUrl ? 'Change image' : 'Upload image'\"\n      >\n        <template v-if=\"previewUrl\">\n          <img\n            class=\"size-full object-cover\"\n            :src=\"previewUrl\"\n            alt=\"Preview of uploaded image\"\n            :width=\"64\"\n            :height=\"64\"\n            :style=\"{ objectFit: 'cover' }\"\n          />\n        </template>\n        <template v-else>\n          <div aria-hidden=\"true\">\n            <CircleUserRoundIcon class=\"size-4 opacity-60\" />\n          </div>\n        </template>\n      </Button>\n      <Button\n        v-if=\"previewUrl\"\n        @click=\"removeCurrentFile\"\n        size=\"icon\"\n        class=\"border-background focus-visible:border-background absolute -top-2 -right-2 size-6 rounded-full border-2 shadow-none\"\n        aria-label=\"Remove image\"\n      >\n        <XIcon class=\"size-3.5\" />\n      </Button>\n      <input\n        v-bind=\"getInputProps()\"\n        class=\"sr-only\"\n        aria-label=\"Upload image file\"\n        :tabIndex=\"-1\"\n      />\n    </div>\n    <p v-if=\"fileName\" class=\"text-muted-foreground text-xs\">{{ fileName }}</p>\n    <p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Avatar upload button</p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-52.html",
          "target": "components/ui/button-52.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex flex-col items-center gap-2\"><div class=\"relative inline-flex\"><Button variant=\"outline\" class=\"relative size-16 overflow-hidden p-0 shadow-none\" on-click=\"${openFileDialog}\" aria-label=\"${previewUrl ? 'Change image' : 'Upload image'}\"><!-- if previewUrl -->\n<img class=\"size-full object-cover\" src=\"${previewUrl}\" alt=\"Preview of uploaded image\" width=\"${64}\" height=\"${64}\" style=\"${{ objectFit: 'cover' }}\" />\n<!-- else -->\n<div aria-hidden=\"true\"><CircleUserRoundIcon class=\"size-4 opacity-60\" /></div>\n<!-- endif --></Button><!-- if previewUrl -->\n<Button on-click=\"${() => removeFile(files[0]?.id)}\" size=\"icon\" class=\"border-background focus-visible:border-background absolute -top-2 -right-2 size-6 rounded-full border-2 shadow-none\" aria-label=\"Remove image\"><XIcon class=\"size-3.5\" /></Button>\n<!-- endif --><input class=\"sr-only\" aria-label=\"Upload image file\" tabindex=\"${-1}\" /></div><!-- if fileName -->\n<p class=\"text-muted-foreground text-xs\">${fileName}</p>\n<!-- endif --><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Avatar upload button\n      </p></div>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-52.wxml",
          "target": "components/ui/button-52/button-52.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex flex-col items-center gap-2\"><view class=\"relative inline-flex\"><button variant=\"outline\" class=\"relative size-16 overflow-hidden p-0 shadow-none\" bindtap=\"openFileDialog\" aria-label=\"{{previewUrl ? 'Change image' : 'Upload image'}}\"><block wx:if=\"{{previewUrl}}\">\n<image class=\"size-full object-cover\" src=\"{{previewUrl}}\" alt=\"Preview of uploaded image\" width=\"{{64}}\" height=\"{{64}}\" style=\"{{{ objectFit: 'cover' }}}\" />\n</block>\n<block wx:else>\n<view aria-hidden=\"true\"><circleuserroundicon class=\"size-4 opacity-60\" /></view>\n</block></button><button wx:if=\"{{previewUrl}}\" bindtap=\"removeFile(files[0]?.id)\" size=\"icon\" class=\"border-background focus-visible:border-background absolute -top-2 -right-2 size-6 rounded-full border-2 shadow-none\" aria-label=\"Remove image\"><xicon class=\"size-3.5\" /></button><input class=\"sr-only\" aria-label=\"Upload image file\" tabindex=\"{{-1}}\" /></view><text wx:if=\"{{fileName}}\" class=\"text-muted-foreground text-xs\">{{ fileName }}</text><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Avatar upload button\n      </text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "upload",
          "user",
          "avatar",
          "profile",
          "image"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-52",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-52",
              "path": "registry/default/components/button/button-52.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-52",
              "path": "registry/default/components/button/button-52.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-52",
              "path": "registry/default/components/button/button-52.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-52",
              "path": "registry/default/components/button/button-52.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · Rounded button"
      },
      "categories": [
        "buttons",
        "button",
        "file-upload"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-53",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-53.tsx",
          "type": "registry:component",
          "target": "components/ui/button-53.tsx",
          "content": "import { Button } from '@timui/react'\nimport {\n  ChevronDownIcon,\n  ChevronLeftIcon,\n  ChevronRightIcon,\n  ChevronUpIcon,\n  CircleIcon,\n} from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <div className=\"inline-grid w-fit grid-cols-3 gap-1\">\n      <Button className=\"col-start-2\" variant=\"outline\" size=\"icon\" aria-label=\"Pan camera up\">\n        <ChevronUpIcon size={16} aria-hidden=\"true\" />\n      </Button>\n      <Button className=\"col-start-1\" variant=\"outline\" size=\"icon\" aria-label=\"Pan camera left\">\n        <ChevronLeftIcon size={16} aria-hidden=\"true\" />\n      </Button>\n      <div className=\"flex items-center justify-center\" aria-hidden=\"true\">\n        <CircleIcon className=\"opacity-60\" size={16} />\n      </div>\n      <Button variant=\"outline\" size=\"icon\" aria-label=\"Pan camera right\">\n        <ChevronRightIcon size={16} aria-hidden=\"true\" />\n      </Button>\n      <Button className=\"col-start-2\" variant=\"outline\" size=\"icon\" aria-label=\"Pan camera down\">\n        <ChevronDownIcon size={16} aria-hidden=\"true\" />\n      </Button>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-53.vue",
          "target": "components/ui/button-53.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, CircleIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"inline-grid w-fit grid-cols-3 gap-1\"><Button class=\"col-start-2\" variant=\"outline\" size=\"icon\" aria-label=\"Pan camera up\"><ChevronUpIcon :size=\"16\" aria-hidden=\"true\" /></Button><Button class=\"col-start-1\" variant=\"outline\" size=\"icon\" aria-label=\"Pan camera left\"><ChevronLeftIcon :size=\"16\" aria-hidden=\"true\" /></Button><div class=\"flex items-center justify-center\" aria-hidden=\"true\"><CircleIcon class=\"opacity-60\" :size=\"16\" /></div><Button variant=\"outline\" size=\"icon\" aria-label=\"Pan camera right\"><ChevronRightIcon :size=\"16\" aria-hidden=\"true\" /></Button><Button class=\"col-start-2\" variant=\"outline\" size=\"icon\" aria-label=\"Pan camera down\"><ChevronDownIcon :size=\"16\" aria-hidden=\"true\" /></Button></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-53.html",
          "target": "components/ui/button-53.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"inline-grid w-fit grid-cols-3 gap-1\"><Button class=\"col-start-2\" variant=\"outline\" size=\"icon\" aria-label=\"Pan camera up\"><ChevronUpIcon size=\"${16}\" aria-hidden=\"true\" /></Button><Button class=\"col-start-1\" variant=\"outline\" size=\"icon\" aria-label=\"Pan camera left\"><ChevronLeftIcon size=\"${16}\" aria-hidden=\"true\" /></Button><div class=\"flex items-center justify-center\" aria-hidden=\"true\"><CircleIcon class=\"opacity-60\" size=\"${16}\" /></div><Button variant=\"outline\" size=\"icon\" aria-label=\"Pan camera right\"><ChevronRightIcon size=\"${16}\" aria-hidden=\"true\" /></Button><Button class=\"col-start-2\" variant=\"outline\" size=\"icon\" aria-label=\"Pan camera down\"><ChevronDownIcon size=\"${16}\" aria-hidden=\"true\" /></Button></div>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-53.wxml",
          "target": "components/ui/button-53/button-53.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"inline-grid w-fit grid-cols-3 gap-1\"><button class=\"col-start-2\" variant=\"outline\" size=\"icon\" aria-label=\"Pan camera up\"><chevronupicon size=\"{{16}}\" aria-hidden=\"true\" /></button><button class=\"col-start-1\" variant=\"outline\" size=\"icon\" aria-label=\"Pan camera left\"><chevronlefticon size=\"{{16}}\" aria-hidden=\"true\" /></button><view class=\"flex items-center justify-center\" aria-hidden=\"true\"><circleicon class=\"opacity-60\" size=\"{{16}}\" /></view><button variant=\"outline\" size=\"icon\" aria-label=\"Pan camera right\"><chevronrighticon size=\"{{16}}\" aria-hidden=\"true\" /></button><button class=\"col-start-2\" variant=\"outline\" size=\"icon\" aria-label=\"Pan camera down\"><chevrondownicon size=\"{{16}}\" aria-hidden=\"true\" /></button></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-53",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-53",
              "path": "registry/default/components/button/button-53.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-53",
              "path": "registry/default/components/button/button-53.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-53",
              "path": "registry/default/components/button/button-53.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-53",
              "path": "registry/default/components/button/button-53.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-54",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-54.tsx",
          "type": "registry:component",
          "target": "components/ui/button-54.tsx",
          "content": "import { Button } from '@timui/react'\nimport { ChevronRightIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <Button className=\"group h-auto gap-4 py-3 text-left\" variant=\"outline\">\n      <div className=\"space-y-1\">\n        <h3>Talent Agency</h3>\n        <p className=\"text-muted-foreground font-normal whitespace-break-spaces\">\n          Matches for your roster\n        </p>\n      </div>\n      <ChevronRightIcon\n        className=\"opacity-60 transition-transform group-hover:translate-x-0.5\"\n        size={16}\n        aria-hidden=\"true\"\n      />\n    </Button>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-54.vue",
          "target": "components/ui/button-54.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ChevronRightIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Button class=\"group h-auto gap-4 py-3 text-left\" variant=\"outline\"><div class=\"space-y-1\"><h3>Talent Agency</h3><p class=\"text-muted-foreground font-normal whitespace-break-spaces\">Matches for your roster\n        </p></div><ChevronRightIcon class=\"opacity-60 transition-transform group-hover:translate-x-0.5\" :size=\"16\" aria-hidden=\"true\" /></Button>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-54.html",
          "target": "components/ui/button-54.html",
          "type": "registry:component",
          "content": "<template>\n  <Button class=\"group h-auto gap-4 py-3 text-left\" variant=\"outline\"><div class=\"space-y-1\"><h3>Talent Agency</h3><p class=\"text-muted-foreground font-normal whitespace-break-spaces\">Matches for your roster\n        </p></div><ChevronRightIcon class=\"opacity-60 transition-transform group-hover:translate-x-0.5\" size=\"${16}\" aria-hidden=\"true\" /></Button>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-54.wxml",
          "target": "components/ui/button-54/button-54.wxml",
          "type": "registry:component",
          "content": "<view>\n  <button class=\"group h-auto gap-4 py-3 text-left\" variant=\"outline\"><view class=\"space-y-1\"><h3>Talent Agency</h3><text class=\"text-muted-foreground font-normal whitespace-break-spaces\">Matches for your roster\n        </text></view><chevronrighticon class=\"opacity-60 transition-transform group-hover:translate-x-0.5\" size=\"{{16}}\" aria-hidden=\"true\" /></button>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-54",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-54",
              "path": "registry/default/components/button/button-54.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-54",
              "path": "registry/default/components/button/button-54.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-54",
              "path": "registry/default/components/button/button-54.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-54",
              "path": "registry/default/components/button/button-54.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · Talent Agency"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-25",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/badge.json",
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-25.tsx",
          "type": "registry:component",
          "target": "components/ui/button-25.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Badge, Button } from '@timui/react'\nimport { BellIcon } from 'lucide-react'\n\nexport default function Component() {\n  const [count, setCount] = useState(3)\n\n  const handleClick = () => {\n    setCount(0)\n  }\n\n  return (\n    <Button\n      variant=\"outline\"\n      size=\"icon\"\n      className=\"relative\"\n      onClick={handleClick}\n      aria-label=\"Notifications\"\n    >\n      <BellIcon size={16} aria-hidden=\"true\" />\n      {count > 0 && (\n        <Badge className=\"absolute -top-2 left-full min-w-5 -translate-x-1/2 px-1\">\n          {count > 99 ? '99+' : count}\n        </Badge>\n      )}\n    </Button>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-25.vue",
          "target": "components/ui/button-25.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { BellIcon } from 'lucide-vue-next';\nimport { Badge } from '@timui/vue';\nimport { Button } from '@timui/vue';\n\n\n\nconst count = ref(3);\n\n</script>\n\n<template>\n  <Button variant=\"outline\" size=\"icon\" class=\"relative\" @click=\"handleClick\" aria-label=\"Notifications\"><BellIcon :size=\"16\" aria-hidden=\"true\" /><Badge v-if=\"count > 0\" class=\"absolute -top-2 left-full min-w-5 -translate-x-1/2 px-1\"><template v-if=\"count > 99\">\n{{ '99+' }}\n</template>\n<template v-else>\n{{ count }}\n</template></Badge></Button>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-25.html",
          "target": "components/ui/button-25.html",
          "type": "registry:component",
          "content": "<template>\n  <Button variant=\"outline\" size=\"icon\" class=\"relative\" on-click=\"${handleClick}\" aria-label=\"Notifications\"><BellIcon size=\"${16}\" aria-hidden=\"true\" /><!-- if count > 0 -->\n<Badge class=\"absolute -top-2 left-full min-w-5 -translate-x-1/2 px-1\"><!-- if count > 99 -->\n${'99+'}\n<!-- else -->\n${count}\n<!-- endif --></Badge>\n<!-- endif --></Button>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-25.wxml",
          "target": "components/ui/button-25/button-25.wxml",
          "type": "registry:component",
          "content": "<view>\n  <button variant=\"outline\" size=\"icon\" class=\"relative\" bindtap=\"handleClick\" aria-label=\"Notifications\"><bellicon size=\"{{16}}\" aria-hidden=\"true\" /><badge wx:if=\"{{count > 0}}\" class=\"absolute -top-2 left-full min-w-5 -translate-x-1/2 px-1\"><block wx:if=\"{{count > 99}}\">\n{{ '99+' }}\n</block>\n<block wx:else>\n{{ count }}\n</block></badge></button>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "dropdown",
          "notification"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-25",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-25",
              "path": "registry/default/components/button/button-25.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-25",
              "path": "registry/default/components/button/button-25.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-25",
              "path": "registry/default/components/button/button-25.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-25",
              "path": "registry/default/components/button/button-25.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-26",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/toggle.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-26.tsx",
          "type": "registry:component",
          "target": "components/ui/button-26.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Toggle } from '@timui/react'\nimport { MoonIcon, SunIcon } from 'lucide-react'\n\nexport default function Component() {\n  const [theme, setTheme] = useState<string>('light')\n\n  return (\n    <div>\n      <Toggle\n        variant=\"outline\"\n        className=\"group data-[state=on]:hover:bg-muted size-9 data-[state=on]:bg-transparent\"\n        pressed={theme === 'dark'}\n        onPressedChange={() => setTheme((prev) => (prev === 'dark' ? 'light' : 'dark'))}\n        aria-label={`Switch to ${theme === 'dark' ? 'light' : 'dark'} mode`}\n      >\n        {/* Note: After dark mode implementation, rely on dark: prefix rather than group-data-[state=on]: */}\n        <MoonIcon\n          size={16}\n          className=\"shrink-0 scale-0 opacity-0 transition-all group-data-[state=on]:scale-100 group-data-[state=on]:opacity-100\"\n          aria-hidden=\"true\"\n        />\n        <SunIcon\n          size={16}\n          className=\"absolute shrink-0 scale-100 opacity-100 transition-all group-data-[state=on]:scale-0 group-data-[state=on]:opacity-0\"\n          aria-hidden=\"true\"\n        />\n      </Toggle>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-26.vue",
          "target": "components/ui/button-26.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { MoonIcon, SunIcon } from 'lucide-vue-next';\nimport { Toggle } from '@timui/vue';\n\n\n\nconst theme = ref<string>('light');\n\n\nfunction setTheme(next: typeof theme.value | ((prev: typeof theme.value) => typeof theme.value)) {\n  theme.value = typeof next === 'function'\n    ? (next as (prev: typeof theme.value) => typeof theme.value)(theme.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <div><Toggle variant=\"outline\" class=\"group data-[state=on]:hover:bg-muted size-9 data-[state=on]:bg-transparent\" :pressed=\"theme === 'dark'\" :onPressedChange=\"() => setTheme((prev) => (prev === 'dark' ? 'light' : 'dark'))\" :aria-label=\"`Switch to ${theme === 'dark' ? 'light' : 'dark'} mode`\"><MoonIcon :size=\"16\" class=\"shrink-0 scale-0 opacity-0 transition-all group-data-[state=on]:scale-100 group-data-[state=on]:opacity-100\" aria-hidden=\"true\" /><SunIcon :size=\"16\" class=\"absolute shrink-0 scale-100 opacity-100 transition-all group-data-[state=on]:scale-0 group-data-[state=on]:opacity-0\" aria-hidden=\"true\" /></Toggle></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-26.html",
          "target": "components/ui/button-26.html",
          "type": "registry:component",
          "content": "<template>\n  <div><Toggle variant=\"outline\" class=\"group data-[state=on]:hover:bg-muted size-9 data-[state=on]:bg-transparent\" pressed=\"${theme === 'dark'}\" onpressedchange=\"${() => setTheme((prev) => (prev === 'dark' ? 'light' : 'dark'))}\" aria-label=\"${`Switch to ${theme === 'dark' ? 'light' : 'dark'} mode`}\"><MoonIcon size=\"${16}\" class=\"shrink-0 scale-0 opacity-0 transition-all group-data-[state=on]:scale-100 group-data-[state=on]:opacity-100\" aria-hidden=\"true\" /><SunIcon size=\"${16}\" class=\"absolute shrink-0 scale-100 opacity-100 transition-all group-data-[state=on]:scale-0 group-data-[state=on]:opacity-0\" aria-hidden=\"true\" /></Toggle></div>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-26.wxml",
          "target": "components/ui/button-26/button-26.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><toggle variant=\"outline\" class=\"group data-[state=on]:hover:bg-muted size-9 data-[state=on]:bg-transparent\" pressed=\"{{theme === 'dark'}}\" onpressedchange=\"{{() => setTheme((prev) => (prev === 'dark' ? 'light' : 'dark'))}}\" aria-label=\"{{`Switch to ${theme === 'dark' ? 'light' : 'dark'} mode`}}\"><moonicon size=\"{{16}}\" class=\"shrink-0 scale-0 opacity-0 transition-all group-data-[state=on]:scale-100 group-data-[state=on]:opacity-100\" aria-hidden=\"true\" /><sunicon size=\"{{16}}\" class=\"absolute shrink-0 scale-100 opacity-100 transition-all group-data-[state=on]:scale-0 group-data-[state=on]:opacity-0\" aria-hidden=\"true\" /></toggle></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "toggle",
          "darkmode"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-26",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-26",
              "path": "registry/default/components/button/button-26.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-26",
              "path": "registry/default/components/button/button-26.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-26",
              "path": "registry/default/components/button/button-26.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-26",
              "path": "registry/default/components/button/button-26.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "button-40",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dropdown-menu.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/button/button-40.tsx",
          "type": "registry:component",
          "target": "components/ui/button-40.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport {\n  Button,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuRadioGroup,\n  DropdownMenuRadioItem,\n  DropdownMenuTrigger,\n} from '@timui/react'\nimport { ChevronDownIcon } from 'lucide-react'\n\nconst options = [\n  {\n    label: 'Merge pull request',\n    description:\n      'All commits from this branch will be added to the base branch via a commit version.',\n  },\n  {\n    label: 'Squash and merge',\n    description:\n      'The 6 commits from this branch will be combined into one commit in the base branch.',\n  },\n  {\n    label: 'Rebase and merge',\n    description: 'The 6 commits from this branch will be rebased and added to the base branch.',\n  },\n]\n\nexport default function Component() {\n  const [selectedIndex, setSelectedIndex] = useState('0')\n\n  return (\n    <div className=\"divide-primary-foreground/30 inline-flex divide-x rounded-md shadow-xs rtl:space-x-reverse\">\n      <Button className=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\">\n        {options[Number(selectedIndex)].label}\n      </Button>\n      <DropdownMenu>\n        <DropdownMenuTrigger asChild>\n          <Button\n            className=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\"\n            size=\"icon\"\n            aria-label=\"Options\"\n          >\n            <ChevronDownIcon size={16} aria-hidden=\"true\" />\n          </Button>\n        </DropdownMenuTrigger>\n        <DropdownMenuContent\n          className=\"max-w-64 md:max-w-xs\"\n          side=\"bottom\"\n          sideOffset={4}\n          align=\"end\"\n        >\n          <DropdownMenuRadioGroup value={selectedIndex} onValueChange={setSelectedIndex}>\n            {options.map((option, index) => (\n              <DropdownMenuRadioItem\n                key={option.label}\n                value={String(index)}\n                className=\"items-start [&>span]:pt-1.5\"\n              >\n                <div className=\"flex flex-col gap-1\">\n                  <span className=\"text-sm font-medium\">{option.label}</span>\n                  <span className=\"text-muted-foreground text-xs\">{option.description}</span>\n                </div>\n              </DropdownMenuRadioItem>\n            ))}\n          </DropdownMenuRadioGroup>\n        </DropdownMenuContent>\n      </DropdownMenu>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/button/button-40.vue",
          "target": "components/ui/button-40.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { ChevronDownIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuTrigger } from '@timui/vue';\n\n\n\nconst selectedIndex = ref('0');\n\n\nfunction setSelectedIndex(next: typeof selectedIndex.value | ((prev: typeof selectedIndex.value) => typeof selectedIndex.value)) {\n  selectedIndex.value = typeof next === 'function'\n    ? (next as (prev: typeof selectedIndex.value) => typeof selectedIndex.value)(selectedIndex.value)\n    : next;\n}\n\n\nconst options = [\n  {\n    label: 'Merge pull request',\n    description:\n      'All commits from this branch will be added to the base branch via a commit version.',\n  },\n  {\n    label: 'Squash and merge',\n    description:\n      'The 6 commits from this branch will be combined into one commit in the base branch.',\n  },\n  {\n    label: 'Rebase and merge',\n    description: 'The 6 commits from this branch will be rebased and added to the base branch.',\n  },\n]\n\n</script>\n\n<template>\n  <div class=\"divide-primary-foreground/30 inline-flex divide-x rounded-md shadow-xs rtl:space-x-reverse\"><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\">{{ options[Number(selectedIndex)].label }}</Button><DropdownMenu><DropdownMenuTrigger as-child><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" size=\"icon\" aria-label=\"Options\"><ChevronDownIcon :size=\"16\" aria-hidden=\"true\" /></Button></DropdownMenuTrigger><DropdownMenuContent class=\"max-w-64 md:max-w-xs\" side=\"bottom\" :sideOffset=\"4\" align=\"end\"><DropdownMenuRadioGroup :value=\"selectedIndex\" @update:modelValue=\"setSelectedIndex\"><DropdownMenuRadioItem v-for=\"(option, index) in options\" :key=\"option.label\" :value=\"String(index)\" class=\"items-start [&>span]:pt-1.5\"><div class=\"flex flex-col gap-1\"><span class=\"text-sm font-medium\">{{ option.label }}</span><span class=\"text-muted-foreground text-xs\">{{ option.description }}</span></div></DropdownMenuRadioItem></DropdownMenuRadioGroup></DropdownMenuContent></DropdownMenu></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/button/button-40.html",
          "target": "components/ui/button-40.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"divide-primary-foreground/30 inline-flex divide-x rounded-md shadow-xs rtl:space-x-reverse\"><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\">${options[Number(selectedIndex)].label}</Button><DropdownMenu><DropdownMenuTrigger aschild><Button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" size=\"icon\" aria-label=\"Options\"><ChevronDownIcon size=\"${16}\" aria-hidden=\"true\" /></Button></DropdownMenuTrigger><DropdownMenuContent class=\"max-w-64 md:max-w-xs\" side=\"bottom\" sideoffset=\"${4}\" align=\"end\"><DropdownMenuRadioGroup value=\"${selectedIndex}\" on-value-change=\"${setSelectedIndex}\"><!-- Loop options -->\n<DropdownMenuRadioItem key=\"${option.label}\" value=\"${String(index)}\" class=\"items-start [&>span]:pt-1.5\"><div class=\"flex flex-col gap-1\"><span class=\"text-sm font-medium\">${option.label}</span><span class=\"text-muted-foreground text-xs\">${option.description}</span></div></DropdownMenuRadioItem>\n<!-- End Loop --></DropdownMenuRadioGroup></DropdownMenuContent></DropdownMenu></div>\n</template>"
        },
        {
          "path": "registry/default/components/button/button-40.wxml",
          "target": "components/ui/button-40/button-40.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"divide-primary-foreground/30 inline-flex divide-x rounded-md shadow-xs rtl:space-x-reverse\"><button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\">{{ options[Number(selectedIndex)].label }}</button><dropdownmenu><dropdownmenutrigger aschild><button class=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\" size=\"icon\" aria-label=\"Options\"><chevrondownicon size=\"{{16}}\" aria-hidden=\"true\" /></button></dropdownmenutrigger><dropdownmenucontent class=\"max-w-64 md:max-w-xs\" side=\"bottom\" sideoffset=\"{{4}}\" align=\"end\"><dropdownmenuradiogroup value=\"{{selectedIndex}}\" bindchange=\"setSelectedIndex\"><dropdownmenuradioitem wx:for=\"{{options}}\" wx:for-item=\"option\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{option.label}}\" value=\"{{String(index)}}\" class=\"items-start [&>span]:pt-1.5\"><view class=\"flex flex-col gap-1\"><text class=\"text-sm font-medium\">{{ option.label }}</text><text class=\"text-muted-foreground text-xs\">{{ option.description }}</text></view></dropdownmenuradioitem></dropdownmenuradiogroup></dropdownmenucontent></dropdownmenu></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "button",
          "dropdown"
        ],
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "button-40",
          "group": "button",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "button-40",
              "path": "registry/default/components/button/button-40.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "button-40",
              "path": "registry/default/components/button/button-40.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "button-40",
              "path": "registry/default/components/button/button-40.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "button-40",
              "path": "registry/default/components/button/button-40.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "buttons",
        "title": "Button · With icon"
      },
      "categories": [
        "buttons",
        "button"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "checkbox-01",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/checkbox.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/checkbox/checkbox-01.tsx",
          "type": "registry:component",
          "target": "components/ui/checkbox-01.tsx",
          "content": "import { useId } from 'react'\nimport { Checkbox, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"flex items-center gap-2\">\n      <Checkbox id={id} />\n      <Label htmlFor={id}>Simple checkbox</Label>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-01.vue",
          "target": "components/ui/checkbox-01.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Checkbox } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'checkbox-01';\n\n</script>\n\n<template>\n  <div class=\"flex items-center gap-2\"><Checkbox :id=\"id\" /><Label :htmlFor=\"id\">Simple checkbox</Label></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-01.html",
          "target": "components/ui/checkbox-01.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex items-center gap-2\"><Checkbox id=\"${id}\" /><Label htmlfor=\"${id}\">Simple checkbox</Label></div>\n</template>"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-01.wxml",
          "target": "components/ui/checkbox-01/checkbox-01.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex items-center gap-2\"><checkbox id=\"{{id}}\" /><label htmlfor=\"{{id}}\">Simple checkbox</label></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "checkbox",
          "label",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "checkbox-01",
          "group": "checkbox",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "checkbox-01",
              "path": "registry/default/components/checkbox/checkbox-01.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "checkbox-01",
              "path": "registry/default/components/checkbox/checkbox-01.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "checkbox-01",
              "path": "registry/default/components/checkbox/checkbox-01.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "checkbox-01",
              "path": "registry/default/components/checkbox/checkbox-01.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "checkbox",
        "title": "Checkbox · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "checkbox"
      ]
    },
    {
      "name": "checkbox-02",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/checkbox.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/checkbox/checkbox-02.tsx",
          "type": "registry:component",
          "target": "components/ui/checkbox-02.tsx",
          "content": "'use client'\n\nimport { useId, useState } from 'react'\nimport { Checkbox, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  const [checked, setChecked] = useState<boolean | 'indeterminate'>('indeterminate')\n\n  return (\n    <div className=\"flex items-center gap-2\">\n      <Checkbox id={id} checked={checked} onCheckedChange={setChecked} />\n      <Label htmlFor={id}>Indeterminate checkbox</Label>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-02.vue",
          "target": "components/ui/checkbox-02.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Checkbox } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\nconst checked = ref<boolean | 'indeterminate'>('indeterminate');\n\n\nconst id = 'checkbox-02';\n\n\nfunction setChecked(next: typeof checked.value | ((prev: typeof checked.value) => typeof checked.value)) {\n  checked.value = typeof next === 'function'\n    ? (next as (prev: typeof checked.value) => typeof checked.value)(checked.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <div class=\"flex items-center gap-2\"><Checkbox :id=\"id\" :checked=\"checked\" :onCheckedChange=\"setChecked\" /><Label :htmlFor=\"id\">Indeterminate checkbox</Label></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-02.html",
          "target": "components/ui/checkbox-02.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex items-center gap-2\"><Checkbox id=\"${id}\" checked=\"${checked}\" oncheckedchange=\"${setChecked}\" /><Label htmlfor=\"${id}\">Indeterminate checkbox</Label></div>\n</template>"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-02.wxml",
          "target": "components/ui/checkbox-02/checkbox-02.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex items-center gap-2\"><checkbox id=\"{{id}}\" checked=\"{{checked}}\" oncheckedchange=\"{{setChecked}}\" /><label htmlfor=\"{{id}}\">Indeterminate checkbox</label></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "checkbox",
          "label",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "checkbox-02",
          "group": "checkbox",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "checkbox-02",
              "path": "registry/default/components/checkbox/checkbox-02.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "checkbox-02",
              "path": "registry/default/components/checkbox/checkbox-02.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "checkbox-02",
              "path": "registry/default/components/checkbox/checkbox-02.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "checkbox-02",
              "path": "registry/default/components/checkbox/checkbox-02.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "checkbox",
        "title": "Checkbox · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "checkbox"
      ]
    },
    {
      "name": "checkbox-03",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/checkbox.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/checkbox/checkbox-03.tsx",
          "type": "registry:component",
          "target": "components/ui/checkbox-03.tsx",
          "content": "import { useId } from 'react'\nimport { Checkbox, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"flex items-center gap-2 [--primary:var(--color-indigo-500)] [--ring:var(--color-indigo-300)] in-[.dark]:[--primary:var(--color-indigo-500)] in-[.dark]:[--ring:var(--color-indigo-900)]\">\n      <Checkbox id={id} defaultChecked />\n      <Label htmlFor={id}>Colored checkbox</Label>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-03.vue",
          "target": "components/ui/checkbox-03.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Checkbox } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'checkbox-03';\n\n</script>\n\n<template>\n  <div class=\"flex items-center gap-2 [--primary:var(--color-indigo-500)] [--ring:var(--color-indigo-300)] in-[.dark]:[--primary:var(--color-indigo-500)] in-[.dark]:[--ring:var(--color-indigo-900)]\"><Checkbox :id=\"id\" defaultChecked /><Label :htmlFor=\"id\">Colored checkbox</Label></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-03.html",
          "target": "components/ui/checkbox-03.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex items-center gap-2 [--primary:var(--color-indigo-500)] [--ring:var(--color-indigo-300)] in-[.dark]:[--primary:var(--color-indigo-500)] in-[.dark]:[--ring:var(--color-indigo-900)]\"><Checkbox id=\"${id}\" defaultchecked /><Label htmlfor=\"${id}\">Colored checkbox</Label></div>\n</template>"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-03.wxml",
          "target": "components/ui/checkbox-03/checkbox-03.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex items-center gap-2 [--primary:var(--color-indigo-500)] [--ring:var(--color-indigo-300)] in-[.dark]:[--primary:var(--color-indigo-500)] in-[.dark]:[--ring:var(--color-indigo-900)]\"><checkbox id=\"{{id}}\" defaultchecked /><label htmlfor=\"{{id}}\">Colored checkbox</label></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "checkbox",
          "label",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "checkbox-03",
          "group": "checkbox",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "checkbox-03",
              "path": "registry/default/components/checkbox/checkbox-03.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "checkbox-03",
              "path": "registry/default/components/checkbox/checkbox-03.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "checkbox-03",
              "path": "registry/default/components/checkbox/checkbox-03.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "checkbox-03",
              "path": "registry/default/components/checkbox/checkbox-03.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "checkbox",
        "title": "Checkbox · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "checkbox"
      ]
    },
    {
      "name": "checkbox-04",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/checkbox.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/checkbox/checkbox-04.tsx",
          "type": "registry:component",
          "target": "components/ui/checkbox-04.tsx",
          "content": "import { useId } from 'react'\nimport { Checkbox, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"flex items-center gap-2\">\n      <Checkbox id={id} disabled />\n      <Label htmlFor={id}>Disabled checkbox</Label>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-04.vue",
          "target": "components/ui/checkbox-04.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Checkbox } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'checkbox-04';\n\n</script>\n\n<template>\n  <div class=\"flex items-center gap-2\"><Checkbox :id=\"id\" disabled /><Label :htmlFor=\"id\">Disabled checkbox</Label></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-04.html",
          "target": "components/ui/checkbox-04.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex items-center gap-2\"><Checkbox id=\"${id}\" disabled /><Label htmlfor=\"${id}\">Disabled checkbox</Label></div>\n</template>"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-04.wxml",
          "target": "components/ui/checkbox-04/checkbox-04.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex items-center gap-2\"><checkbox id=\"{{id}}\" disabled /><label htmlfor=\"{{id}}\">Disabled checkbox</label></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "checkbox",
          "label",
          "disabled",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "checkbox-04",
          "group": "checkbox",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "checkbox-04",
              "path": "registry/default/components/checkbox/checkbox-04.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "checkbox-04",
              "path": "registry/default/components/checkbox/checkbox-04.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "checkbox-04",
              "path": "registry/default/components/checkbox/checkbox-04.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "checkbox-04",
              "path": "registry/default/components/checkbox/checkbox-04.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "checkbox",
        "title": "Checkbox · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "checkbox"
      ]
    },
    {
      "name": "checkbox-05",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/checkbox.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/checkbox/checkbox-05.tsx",
          "type": "registry:component",
          "target": "components/ui/checkbox-05.tsx",
          "content": "import { useId } from 'react'\nimport { Checkbox, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"flex items-center gap-2\">\n      <Checkbox id={id} defaultChecked />\n      <Label htmlFor={id} className=\"peer-data-[state=checked]:line-through\">\n        Simple todo item\n      </Label>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-05.vue",
          "target": "components/ui/checkbox-05.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Checkbox } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'checkbox-05';\n\n</script>\n\n<template>\n  <div class=\"flex items-center gap-2\"><Checkbox :id=\"id\" defaultChecked /><Label :htmlFor=\"id\" class=\"peer-data-[state=checked]:line-through\">Simple todo item\n      </Label></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-05.html",
          "target": "components/ui/checkbox-05.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex items-center gap-2\"><Checkbox id=\"${id}\" defaultchecked /><Label htmlfor=\"${id}\" class=\"peer-data-[state=checked]:line-through\">Simple todo item\n      </Label></div>\n</template>"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-05.wxml",
          "target": "components/ui/checkbox-05/checkbox-05.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex items-center gap-2\"><checkbox id=\"{{id}}\" defaultchecked /><label htmlfor=\"{{id}}\" class=\"peer-data-[state=checked]:line-through\">Simple todo item\n      </label></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "checkbox",
          "label",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "checkbox-05",
          "group": "checkbox",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "checkbox-05",
              "path": "registry/default/components/checkbox/checkbox-05.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "checkbox-05",
              "path": "registry/default/components/checkbox/checkbox-05.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "checkbox-05",
              "path": "registry/default/components/checkbox/checkbox-05.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "checkbox-05",
              "path": "registry/default/components/checkbox/checkbox-05.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "checkbox",
        "title": "Checkbox · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "checkbox"
      ]
    },
    {
      "name": "checkbox-06",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/checkbox.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/checkbox/checkbox-06.tsx",
          "type": "registry:component",
          "target": "components/ui/checkbox-06.tsx",
          "content": "import { useId } from 'react'\nimport { Checkbox, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"flex items-center gap-2\">\n      <Checkbox\n        style={\n          {\n            '--primary': 'var(--color-emerald-500)',\n          } as React.CSSProperties\n        }\n        id={id}\n        className=\"rounded-full\"\n        defaultChecked\n      />\n      <Label\n        htmlFor={id}\n        className=\"peer-data-[state=checked]:line-throgh after:bg-muted-foreground peer-data-[state=checked]:text-muted-foreground relative after:absolute after:top-1/2 after:left-0 after:h-px after:w-full after:origin-bottom after:-translate-y-1/2 after:scale-x-0 after:transition-transform after:ease-in-out peer-data-[state=checked]:after:origin-bottom peer-data-[state=checked]:after:scale-x-100\"\n      >\n        Fancy todo item\n      </Label>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-06.vue",
          "target": "components/ui/checkbox-06.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Checkbox } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\nconst id = 'checkbox-06';\nconst checkboxStyle: Record<string, string> = {\n  '--primary': 'var(--color-emerald-500)',\n};\n</script>\n\n<template>\n  <div class=\"flex items-center gap-2\">\n    <Checkbox :style=\"checkboxStyle\" :id=\"id\" class=\"rounded-full\" defaultChecked />\n    <Label\n      :htmlFor=\"id\"\n      class=\"peer-data-[state=checked]:line-through after:bg-muted-foreground peer-data-[state=checked]:text-muted-foreground relative after:absolute after:top-1/2 after:left-0 after:h-px after:w-full after:origin-bottom after:-translate-y-1/2 after:scale-x-0 after:transition-transform after:ease-in-out peer-data-[state=checked]:after:origin-bottom peer-data-[state=checked]:after:scale-x-100\"\n    >\n      Fancy todo item\n    </Label>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-06.html",
          "target": "components/ui/checkbox-06.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex items-center gap-2\"><Checkbox style=\"${{\n            '--primary': 'var(--color-emerald-500)',\n          } as React.CSSProperties}\" id=\"${id}\" class=\"rounded-full\" defaultchecked /><Label htmlfor=\"${id}\" class=\"peer-data-[state=checked]:line-throgh after:bg-muted-foreground peer-data-[state=checked]:text-muted-foreground relative after:absolute after:top-1/2 after:left-0 after:h-px after:w-full after:origin-bottom after:-translate-y-1/2 after:scale-x-0 after:transition-transform after:ease-in-out peer-data-[state=checked]:after:origin-bottom peer-data-[state=checked]:after:scale-x-100\">Fancy todo item\n      </Label></div>\n</template>"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-06.wxml",
          "target": "components/ui/checkbox-06/checkbox-06.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex items-center gap-2\"><checkbox style=\"{{{\n            '--primary': 'var(--color-emerald-500)',\n          } as React.CSSProperties}}\" id=\"{{id}}\" class=\"rounded-full\" defaultchecked /><label htmlfor=\"{{id}}\" class=\"peer-data-[state=checked]:line-throgh after:bg-muted-foreground peer-data-[state=checked]:text-muted-foreground relative after:absolute after:top-1/2 after:left-0 after:h-px after:w-full after:origin-bottom after:-translate-y-1/2 after:scale-x-0 after:transition-transform after:ease-in-out peer-data-[state=checked]:after:origin-bottom peer-data-[state=checked]:after:scale-x-100\">Fancy todo item\n      </label></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "checkbox",
          "label",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "checkbox-06",
          "group": "checkbox",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "checkbox-06",
              "path": "registry/default/components/checkbox/checkbox-06.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "checkbox-06",
              "path": "registry/default/components/checkbox/checkbox-06.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "checkbox-06",
              "path": "registry/default/components/checkbox/checkbox-06.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "checkbox-06",
              "path": "registry/default/components/checkbox/checkbox-06.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "checkbox",
        "title": "Checkbox · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "checkbox"
      ]
    },
    {
      "name": "checkbox-07",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/checkbox.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/checkbox/checkbox-07.tsx",
          "type": "registry:component",
          "target": "components/ui/checkbox-07.tsx",
          "content": "import { useId } from 'react'\nimport { Checkbox, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"flex items-center gap-2\">\n      <Checkbox id={id} />\n      <Label htmlFor={id}>\n        I agree to the{' '}\n        <a className=\"underline\" href=\"https://ui.timkit.cn\" target=\"_blank\">\n          terms of service\n        </a>\n      </Label>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-07.vue",
          "target": "components/ui/checkbox-07.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Checkbox } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'checkbox-07';\n\n</script>\n\n<template>\n  <div class=\"flex items-center gap-2\"><Checkbox :id=\"id\" /><Label :htmlFor=\"id\">I agree to the{{ ' ' }}<a class=\"underline\" href=\"https://ui.timkit.cn\" target=\"_blank\">terms of service\n        </a></Label></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-07.html",
          "target": "components/ui/checkbox-07.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex items-center gap-2\"><Checkbox id=\"${id}\" /><Label htmlfor=\"${id}\">I agree to the${' '}<a class=\"underline\" href=\"https://ui.timkit.cn\" target=\"_blank\">terms of service\n        </a></Label></div>\n</template>"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-07.wxml",
          "target": "components/ui/checkbox-07/checkbox-07.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex items-center gap-2\"><checkbox id=\"{{id}}\" /><label htmlfor=\"{{id}}\">I agree to the{{ ' ' }}<a class=\"underline\" href=\"https://ui.timkit.cn\" target=\"_blank\">terms of service\n        </a></label></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "checkbox",
          "label",
          "login",
          "authentication",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "checkbox-07",
          "group": "checkbox",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "checkbox-07",
              "path": "registry/default/components/checkbox/checkbox-07.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "checkbox-07",
              "path": "registry/default/components/checkbox/checkbox-07.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "checkbox-07",
              "path": "registry/default/components/checkbox/checkbox-07.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "checkbox-07",
              "path": "registry/default/components/checkbox/checkbox-07.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "checkbox",
        "title": "Checkbox · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "checkbox"
      ]
    },
    {
      "name": "checkbox-08",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/checkbox.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/checkbox/checkbox-08.tsx",
          "type": "registry:component",
          "target": "components/ui/checkbox-08.tsx",
          "content": "import { useId } from 'react'\nimport { Checkbox, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"flex gap-6\">\n      <div className=\"flex items-center gap-2\">\n        <Checkbox id={`${id}-a`} />\n        <Label htmlFor={`${id}-a`}>React</Label>\n      </div>\n      <div className=\"flex items-center gap-2\">\n        <Checkbox id={`${id}-b`} />\n        <Label htmlFor={`${id}-b`}>Next.js</Label>\n      </div>\n      <div className=\"flex items-center gap-2\">\n        <Checkbox id={`${id}-c`} />\n        <Label htmlFor={`${id}-c`}>Astro</Label>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-08.vue",
          "target": "components/ui/checkbox-08.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Checkbox } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'checkbox-08';\n\n</script>\n\n<template>\n  <div class=\"flex gap-6\"><div class=\"flex items-center gap-2\"><Checkbox :id=\"`${id}-a`\" /><Label :htmlFor=\"`${id}-a`\">React</Label></div><div class=\"flex items-center gap-2\"><Checkbox :id=\"`${id}-b`\" /><Label :htmlFor=\"`${id}-b`\">Next.js</Label></div><div class=\"flex items-center gap-2\"><Checkbox :id=\"`${id}-c`\" /><Label :htmlFor=\"`${id}-c`\">Astro</Label></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-08.html",
          "target": "components/ui/checkbox-08.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex gap-6\"><div class=\"flex items-center gap-2\"><Checkbox id=\"${`${id}-a`}\" /><Label htmlfor=\"${`${id}-a`}\">React</Label></div><div class=\"flex items-center gap-2\"><Checkbox id=\"${`${id}-b`}\" /><Label htmlfor=\"${`${id}-b`}\">Next.js</Label></div><div class=\"flex items-center gap-2\"><Checkbox id=\"${`${id}-c`}\" /><Label htmlfor=\"${`${id}-c`}\">Astro</Label></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-08.wxml",
          "target": "components/ui/checkbox-08/checkbox-08.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex gap-6\"><view class=\"flex items-center gap-2\"><checkbox id=\"{{`${id}-a`}}\" /><label htmlfor=\"{{`${id}-a`}}\">React</label></view><view class=\"flex items-center gap-2\"><checkbox id=\"{{`${id}-b`}}\" /><label htmlfor=\"{{`${id}-b`}}\">Next.js</label></view><view class=\"flex items-center gap-2\"><checkbox id=\"{{`${id}-c`}}\" /><label htmlfor=\"{{`${id}-c`}}\">Astro</label></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "checkbox",
          "label",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "checkbox-08",
          "group": "checkbox",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "checkbox-08",
              "path": "registry/default/components/checkbox/checkbox-08.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "checkbox-08",
              "path": "registry/default/components/checkbox/checkbox-08.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "checkbox-08",
              "path": "registry/default/components/checkbox/checkbox-08.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "checkbox-08",
              "path": "registry/default/components/checkbox/checkbox-08.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "checkbox",
        "title": "Checkbox · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "checkbox"
      ]
    },
    {
      "name": "checkbox-10",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/checkbox.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/checkbox/checkbox-10.tsx",
          "type": "registry:component",
          "target": "components/ui/checkbox-10.tsx",
          "content": "import { useId } from 'react'\nimport { Checkbox, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"flex items-center justify-between gap-2\">\n      <Checkbox id={id} className=\"order-1\" />\n      <Label htmlFor={id}>Right aligned checkbox</Label>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-10.vue",
          "target": "components/ui/checkbox-10.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Checkbox } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'checkbox-10';\n\n</script>\n\n<template>\n  <div class=\"flex items-center justify-between gap-2\"><Checkbox :id=\"id\" class=\"order-1\" /><Label :htmlFor=\"id\">Right aligned checkbox</Label></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-10.html",
          "target": "components/ui/checkbox-10.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex items-center justify-between gap-2\"><Checkbox id=\"${id}\" class=\"order-1\" /><Label htmlfor=\"${id}\">Right aligned checkbox</Label></div>\n</template>"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-10.wxml",
          "target": "components/ui/checkbox-10/checkbox-10.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex items-center justify-between gap-2\"><checkbox id=\"{{id}}\" class=\"order-1\" /><label htmlfor=\"{{id}}\">Right aligned checkbox</label></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "checkbox",
          "label",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "checkbox-10",
          "group": "checkbox",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "checkbox-10",
              "path": "registry/default/components/checkbox/checkbox-10.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "checkbox-10",
              "path": "registry/default/components/checkbox/checkbox-10.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "checkbox-10",
              "path": "registry/default/components/checkbox/checkbox-10.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "checkbox-10",
              "path": "registry/default/components/checkbox/checkbox-10.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "checkbox",
        "title": "Checkbox · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "checkbox"
      ]
    },
    {
      "name": "checkbox-11",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/checkbox.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/checkbox/checkbox-11.tsx",
          "type": "registry:component",
          "target": "components/ui/checkbox-11.tsx",
          "content": "import { useId } from 'react'\nimport { Checkbox, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"flex items-start gap-2\">\n      <Checkbox id={id} aria-describedby={`${id}-description`} />\n      <div className=\"grid grow gap-2\">\n        <Label htmlFor={id}>\n          Label{' '}\n          <span className=\"text-muted-foreground text-xs leading-[inherit] font-normal\">\n            (Sublabel)\n          </span>\n        </Label>\n        <p id={`${id}-description`} className=\"text-muted-foreground text-xs\">\n          You can use this checkbox with a label and a description.\n        </p>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-11.vue",
          "target": "components/ui/checkbox-11.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Checkbox } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'checkbox-11';\n\n</script>\n\n<template>\n  <div class=\"flex items-start gap-2\"><Checkbox :id=\"id\" :aria-describedby=\"`${id}-description`\" /><div class=\"grid grow gap-2\"><Label :htmlFor=\"id\">Label{{ ' ' }}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n          </span></Label><p :id=\"`${id}-description`\" class=\"text-muted-foreground text-xs\">You can use this checkbox with a label and a description.\n        </p></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-11.html",
          "target": "components/ui/checkbox-11.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex items-start gap-2\"><Checkbox id=\"${id}\" aria-describedby=\"${`${id}-description`}\" /><div class=\"grid grow gap-2\"><Label htmlfor=\"${id}\">Label${' '}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n          </span></Label><p id=\"${`${id}-description`}\" class=\"text-muted-foreground text-xs\">You can use this checkbox with a label and a description.\n        </p></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-11.wxml",
          "target": "components/ui/checkbox-11/checkbox-11.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex items-start gap-2\"><checkbox id=\"{{id}}\" aria-describedby=\"{{`${id}-description`}}\" /><view class=\"grid grow gap-2\"><label htmlfor=\"{{id}}\">Label{{ ' ' }}<text class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n          </text></label><text id=\"{{`${id}-description`}}\" class=\"text-muted-foreground text-xs\">You can use this checkbox with a label and a description.\n        </text></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "checkbox",
          "label",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "checkbox-11",
          "group": "checkbox",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "checkbox-11",
              "path": "registry/default/components/checkbox/checkbox-11.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "checkbox-11",
              "path": "registry/default/components/checkbox/checkbox-11.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "checkbox-11",
              "path": "registry/default/components/checkbox/checkbox-11.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "checkbox-11",
              "path": "registry/default/components/checkbox/checkbox-11.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "checkbox",
        "title": "Checkbox · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "checkbox"
      ]
    },
    {
      "name": "checkbox-12",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/checkbox.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/input.json"
      ],
      "files": [
        {
          "path": "registry/default/components/checkbox/checkbox-12.tsx",
          "type": "registry:component",
          "target": "components/ui/checkbox-12.tsx",
          "content": "'use client'\n\nimport { useEffect, useId, useRef, useState } from 'react'\nimport { Checkbox, Input, Label } from '@timui/react'\n\nexport default function Component() {\n  const checkboxId = useId()\n  const inputId = useId()\n  const [checked, setChecked] = useState<boolean | 'indeterminate'>(false)\n  const inputRef = useRef<HTMLInputElement>(null)\n\n  useEffect(() => {\n    if (checked === true && inputRef.current) {\n      inputRef.current.focus()\n    }\n  }, [checked])\n\n  return (\n    <div>\n      <div className=\"flex items-start gap-2\">\n        <Checkbox\n          id={checkboxId}\n          checked={checked}\n          onCheckedChange={setChecked}\n          aria-describedby={`${checkboxId}-description`}\n          aria-controls={inputId}\n        />\n        <div className=\"grow\">\n          <div className=\"grid gap-2\">\n            <Label htmlFor={checkboxId}>Checkbox with expansion</Label>\n            <p id={`${checkboxId}-description`} className=\"text-muted-foreground text-xs\">\n              You can use this checkbox with a label and a description.\n            </p>\n          </div>\n          {/* Expandable field */}\n          <div\n            role=\"region\"\n            id={inputId}\n            aria-labelledby={checkboxId}\n            className=\"grid transition-all ease-in-out data-[state=collapsed]:grid-rows-[0fr] data-[state=collapsed]:opacity-0 data-[state=expanded]:grid-rows-[1fr] data-[state=expanded]:opacity-100\"\n            data-state={checked ? 'expanded' : 'collapsed'}\n          >\n            <div className=\"pointer-events-none -m-2 overflow-hidden p-2\">\n              <div className=\"pointer-events-auto mt-3\">\n                <Input\n                  ref={inputRef}\n                  type=\"text\"\n                  id=\"checkbox-11-additional-info\"\n                  placeholder=\"Enter details\"\n                  aria-label=\"Additional Information\"\n                  disabled={!checked}\n                />\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-12.vue",
          "target": "components/ui/checkbox-12.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Checkbox } from '@timui/vue';\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\nconst checked = ref<boolean | 'indeterminate'>(false);\n\n\nfunction setChecked(next: typeof checked.value | ((prev: typeof checked.value) => typeof checked.value)) {\n  checked.value = typeof next === 'function'\n    ? (next as (prev: typeof checked.value) => typeof checked.value)(checked.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <div><div class=\"flex items-start gap-2\"><Checkbox :id=\"checkboxId\" :checked=\"checked\" :onCheckedChange=\"setChecked\" :aria-describedby=\"`${checkboxId}-description`\" :aria-controls=\"inputId\" /><div class=\"grow\"><div class=\"grid gap-2\"><Label :htmlFor=\"checkboxId\">Checkbox with expansion</Label><p :id=\"`${checkboxId}-description`\" class=\"text-muted-foreground text-xs\">You can use this checkbox with a label and a description.\n            </p></div><div role=\"region\" :id=\"inputId\" :aria-labelledby=\"checkboxId\" class=\"grid transition-all ease-in-out data-[state=collapsed]:grid-rows-[0fr] data-[state=collapsed]:opacity-0 data-[state=expanded]:grid-rows-[1fr] data-[state=expanded]:opacity-100\" :data-state=\"checked ? 'expanded' : 'collapsed'\"><div class=\"pointer-events-none -m-2 overflow-hidden p-2\"><div class=\"pointer-events-auto mt-3\"><Input :ref=\"inputRef\" type=\"text\" id=\"checkbox-11-additional-info\" placeholder=\"Enter details\" aria-label=\"Additional Information\" :disabled=\"!checked\" /></div></div></div></div></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-12.html",
          "target": "components/ui/checkbox-12.html",
          "type": "registry:component",
          "content": "<template>\n  <div><div class=\"flex items-start gap-2\"><Checkbox id=\"${checkboxId}\" checked=\"${checked}\" oncheckedchange=\"${setChecked}\" aria-describedby=\"${`${checkboxId}-description`}\" aria-controls=\"${inputId}\" /><div class=\"grow\"><div class=\"grid gap-2\"><Label htmlfor=\"${checkboxId}\">Checkbox with expansion</Label><p id=\"${`${checkboxId}-description`}\" class=\"text-muted-foreground text-xs\">You can use this checkbox with a label and a description.\n            </p></div><div role=\"region\" id=\"${inputId}\" aria-labelledby=\"${checkboxId}\" class=\"grid transition-all ease-in-out data-[state=collapsed]:grid-rows-[0fr] data-[state=collapsed]:opacity-0 data-[state=expanded]:grid-rows-[1fr] data-[state=expanded]:opacity-100\" data-state=\"${checked ? 'expanded' : 'collapsed'}\"><div class=\"pointer-events-none -m-2 overflow-hidden p-2\"><div class=\"pointer-events-auto mt-3\"><Input ref=\"${inputRef}\" type=\"text\" id=\"checkbox-11-additional-info\" placeholder=\"Enter details\" aria-label=\"Additional Information\" disabled=\"${!checked}\" /></div></div></div></div></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-12.wxml",
          "target": "components/ui/checkbox-12/checkbox-12.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><view class=\"flex items-start gap-2\"><checkbox id=\"{{checkboxId}}\" checked=\"{{checked}}\" oncheckedchange=\"{{setChecked}}\" aria-describedby=\"{{`${checkboxId}-description`}}\" aria-controls=\"{{inputId}}\" /><view class=\"grow\"><view class=\"grid gap-2\"><label htmlfor=\"{{checkboxId}}\">Checkbox with expansion</label><text id=\"{{`${checkboxId}-description`}}\" class=\"text-muted-foreground text-xs\">You can use this checkbox with a label and a description.\n            </text></view><view role=\"region\" id=\"{{inputId}}\" aria-labelledby=\"{{checkboxId}}\" class=\"grid transition-all ease-in-out data-[state=collapsed]:grid-rows-[0fr] data-[state=collapsed]:opacity-0 data-[state=expanded]:grid-rows-[1fr] data-[state=expanded]:opacity-100\" data-state=\"{{checked ? 'expanded' : 'collapsed'}}\"><view class=\"pointer-events-none -m-2 overflow-hidden p-2\"><view class=\"pointer-events-auto mt-3\"><input ref=\"{{inputRef}}\" type=\"text\" id=\"checkbox-11-additional-info\" placeholder=\"Enter details\" aria-label=\"Additional Information\" disabled=\"{{!checked}}\" /></view></view></view></view></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "checkbox",
          "label",
          "collapsible",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "checkbox-12",
          "group": "checkbox",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "checkbox-12",
              "path": "registry/default/components/checkbox/checkbox-12.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "checkbox-12",
              "path": "registry/default/components/checkbox/checkbox-12.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "checkbox-12",
              "path": "registry/default/components/checkbox/checkbox-12.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "checkbox-12",
              "path": "registry/default/components/checkbox/checkbox-12.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "checkbox",
        "title": "Checkbox · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "checkbox"
      ]
    },
    {
      "name": "checkbox-13",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/checkbox.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/checkbox/checkbox-13.tsx",
          "type": "registry:component",
          "target": "components/ui/checkbox-13.tsx",
          "content": "import { useId } from 'react'\nimport { Checkbox, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"flex items-start gap-2\">\n      <Checkbox id={id} className=\"order-1\" aria-describedby={`${id}-description`} />\n      <div className=\"grid grow gap-2\">\n        <Label htmlFor={id}>\n          Label{' '}\n          <span className=\"text-muted-foreground text-xs leading-[inherit] font-normal\">\n            (Sublabel)\n          </span>\n        </Label>\n        <p id={`${id}-description`} className=\"text-muted-foreground text-xs\">\n          You can use this checkbox with a label and a description.\n        </p>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-13.vue",
          "target": "components/ui/checkbox-13.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Checkbox } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'checkbox-13';\n\n</script>\n\n<template>\n  <div class=\"flex items-start gap-2\"><Checkbox :id=\"id\" class=\"order-1\" :aria-describedby=\"`${id}-description`\" /><div class=\"grid grow gap-2\"><Label :htmlFor=\"id\">Label{{ ' ' }}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n          </span></Label><p :id=\"`${id}-description`\" class=\"text-muted-foreground text-xs\">You can use this checkbox with a label and a description.\n        </p></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-13.html",
          "target": "components/ui/checkbox-13.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex items-start gap-2\"><Checkbox id=\"${id}\" class=\"order-1\" aria-describedby=\"${`${id}-description`}\" /><div class=\"grid grow gap-2\"><Label htmlfor=\"${id}\">Label${' '}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n          </span></Label><p id=\"${`${id}-description`}\" class=\"text-muted-foreground text-xs\">You can use this checkbox with a label and a description.\n        </p></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-13.wxml",
          "target": "components/ui/checkbox-13/checkbox-13.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex items-start gap-2\"><checkbox id=\"{{id}}\" class=\"order-1\" aria-describedby=\"{{`${id}-description`}}\" /><view class=\"grid grow gap-2\"><label htmlfor=\"{{id}}\">Label{{ ' ' }}<text class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n          </text></label><text id=\"{{`${id}-description`}}\" class=\"text-muted-foreground text-xs\">You can use this checkbox with a label and a description.\n        </text></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "checkbox",
          "label",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "checkbox-13",
          "group": "checkbox",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "checkbox-13",
              "path": "registry/default/components/checkbox/checkbox-13.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "checkbox-13",
              "path": "registry/default/components/checkbox/checkbox-13.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "checkbox-13",
              "path": "registry/default/components/checkbox/checkbox-13.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "checkbox-13",
              "path": "registry/default/components/checkbox/checkbox-13.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "checkbox",
        "title": "Checkbox · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "checkbox"
      ]
    },
    {
      "name": "checkbox-14",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/checkbox.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/checkbox/checkbox-14.tsx",
          "type": "registry:component",
          "target": "components/ui/checkbox-14.tsx",
          "content": "import { useId } from 'react'\nimport { Checkbox, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\">\n      <Checkbox\n        id={id}\n        className=\"order-1 after:absolute after:inset-0\"\n        aria-describedby={`${id}-description`}\n      />\n      <div className=\"grid grow gap-2\">\n        <Label htmlFor={id}>\n          Label{' '}\n          <span className=\"text-muted-foreground text-xs leading-[inherit] font-normal\">\n            (Sublabel)\n          </span>\n        </Label>\n        <p id={`${id}-description`} className=\"text-muted-foreground text-xs\">\n          A short description goes here.\n        </p>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-14.vue",
          "target": "components/ui/checkbox-14.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Checkbox } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'checkbox-14';\n\n</script>\n\n<template>\n  <div class=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\"><Checkbox :id=\"id\" class=\"order-1 after:absolute after:inset-0\" :aria-describedby=\"`${id}-description`\" /><div class=\"grid grow gap-2\"><Label :htmlFor=\"id\">Label{{ ' ' }}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n          </span></Label><p :id=\"`${id}-description`\" class=\"text-muted-foreground text-xs\">A short description goes here.\n        </p></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-14.html",
          "target": "components/ui/checkbox-14.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\"><Checkbox id=\"${id}\" class=\"order-1 after:absolute after:inset-0\" aria-describedby=\"${`${id}-description`}\" /><div class=\"grid grow gap-2\"><Label htmlfor=\"${id}\">Label${' '}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n          </span></Label><p id=\"${`${id}-description`}\" class=\"text-muted-foreground text-xs\">A short description goes here.\n        </p></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-14.wxml",
          "target": "components/ui/checkbox-14/checkbox-14.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\"><checkbox id=\"{{id}}\" class=\"order-1 after:absolute after:inset-0\" aria-describedby=\"{{`${id}-description`}}\" /><view class=\"grid grow gap-2\"><label htmlfor=\"{{id}}\">Label{{ ' ' }}<text class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n          </text></label><text id=\"{{`${id}-description`}}\" class=\"text-muted-foreground text-xs\">A short description goes here.\n        </text></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "checkbox",
          "label",
          "card",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "checkbox-14",
          "group": "checkbox",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "checkbox-14",
              "path": "registry/default/components/checkbox/checkbox-14.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "checkbox-14",
              "path": "registry/default/components/checkbox/checkbox-14.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "checkbox-14",
              "path": "registry/default/components/checkbox/checkbox-14.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "checkbox-14",
              "path": "registry/default/components/checkbox/checkbox-14.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "checkbox",
        "title": "Checkbox · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "checkbox"
      ]
    },
    {
      "name": "checkbox-15",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/checkbox.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/checkbox/checkbox-15.tsx",
          "type": "registry:component",
          "target": "components/ui/checkbox-15.tsx",
          "content": "import { useId } from 'react'\nimport { Checkbox, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\">\n      <Checkbox\n        id={id}\n        className=\"order-1 after:absolute after:inset-0\"\n        aria-describedby={`${id}-description`}\n      />\n      <div className=\"flex grow items-start gap-3\">\n        <svg\n          className=\"shrink-0\"\n          width={32}\n          height={24}\n          viewBox=\"0 0 32 24\"\n          xmlns=\"http://www.w3.org/2000/svg\"\n          aria-hidden=\"true\"\n        >\n          <rect width=\"32\" height=\"24\" rx=\"4\" fill=\"#252525\" />\n          <path d=\"M19.0537 6.49742H12.9282V17.5026H19.0537V6.49742Z\" fill=\"#FF5A00\" />\n          <path\n            d=\"M13.3359 12C13.3359 9.76408 14.3871 7.77961 16 6.49741C14.8129 5.56408 13.3155 5 11.6822 5C7.81295 5 4.68221 8.13074 4.68221 12C4.68221 15.8693 7.81295 19 11.6822 19C13.3155 19 14.8129 18.4359 16 17.5026C14.3848 16.2385 13.3359 14.2359 13.3359 12Z\"\n            fill=\"#EB001B\"\n          />\n          <path\n            d=\"M27.3178 12C27.3178 15.8693 24.1871 19 20.3178 19C18.6845 19 17.1871 18.4359 16 17.5026C17.6333 16.2181 18.6641 14.2359 18.6641 12C18.6641 9.76408 17.6129 7.77961 16 6.49741C17.1848 5.56408 18.6822 5 20.3155 5C24.1871 5 27.3178 8.15113 27.3178 12Z\"\n            fill=\"#F79E1B\"\n          />\n        </svg>\n        <div className=\"grid gap-2\">\n          <Label htmlFor={id}>\n            Label{' '}\n            <span className=\"text-muted-foreground text-xs leading-[inherit] font-normal\">\n              (Sublabel)\n            </span>\n          </Label>\n          <p id={`${id}-description`} className=\"text-muted-foreground text-xs\">\n            A short description goes here.\n          </p>\n        </div>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-15.vue",
          "target": "components/ui/checkbox-15.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Checkbox } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'checkbox-15';\n\n</script>\n\n<template>\n  <div class=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\"><Checkbox :id=\"id\" class=\"order-1 after:absolute after:inset-0\" :aria-describedby=\"`${id}-description`\" /><div class=\"flex grow items-start gap-3\"><svg class=\"shrink-0\" :width=\"32\" :height=\"24\" viewBox=\"0 0 32 24\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\"><rect width=\"32\" height=\"24\" rx=\"4\" fill=\"#252525\" /><path d=\"M19.0537 6.49742H12.9282V17.5026H19.0537V6.49742Z\" fill=\"#FF5A00\" /><path d=\"M13.3359 12C13.3359 9.76408 14.3871 7.77961 16 6.49741C14.8129 5.56408 13.3155 5 11.6822 5C7.81295 5 4.68221 8.13074 4.68221 12C4.68221 15.8693 7.81295 19 11.6822 19C13.3155 19 14.8129 18.4359 16 17.5026C14.3848 16.2385 13.3359 14.2359 13.3359 12Z\" fill=\"#EB001B\" /><path d=\"M27.3178 12C27.3178 15.8693 24.1871 19 20.3178 19C18.6845 19 17.1871 18.4359 16 17.5026C17.6333 16.2181 18.6641 14.2359 18.6641 12C18.6641 9.76408 17.6129 7.77961 16 6.49741C17.1848 5.56408 18.6822 5 20.3155 5C24.1871 5 27.3178 8.15113 27.3178 12Z\" fill=\"#F79E1B\" /></svg><div class=\"grid gap-2\"><Label :htmlFor=\"id\">Label{{ ' ' }}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n            </span></Label><p :id=\"`${id}-description`\" class=\"text-muted-foreground text-xs\">A short description goes here.\n          </p></div></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-15.html",
          "target": "components/ui/checkbox-15.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\"><Checkbox id=\"${id}\" class=\"order-1 after:absolute after:inset-0\" aria-describedby=\"${`${id}-description`}\" /><div class=\"flex grow items-start gap-3\"><svg class=\"shrink-0\" width=\"${32}\" height=\"${24}\" viewbox=\"0 0 32 24\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\"><rect width=\"32\" height=\"24\" rx=\"4\" fill=\"#252525\" /><path d=\"M19.0537 6.49742H12.9282V17.5026H19.0537V6.49742Z\" fill=\"#FF5A00\" /><path d=\"M13.3359 12C13.3359 9.76408 14.3871 7.77961 16 6.49741C14.8129 5.56408 13.3155 5 11.6822 5C7.81295 5 4.68221 8.13074 4.68221 12C4.68221 15.8693 7.81295 19 11.6822 19C13.3155 19 14.8129 18.4359 16 17.5026C14.3848 16.2385 13.3359 14.2359 13.3359 12Z\" fill=\"#EB001B\" /><path d=\"M27.3178 12C27.3178 15.8693 24.1871 19 20.3178 19C18.6845 19 17.1871 18.4359 16 17.5026C17.6333 16.2181 18.6641 14.2359 18.6641 12C18.6641 9.76408 17.6129 7.77961 16 6.49741C17.1848 5.56408 18.6822 5 20.3155 5C24.1871 5 27.3178 8.15113 27.3178 12Z\" fill=\"#F79E1B\" /></svg><div class=\"grid gap-2\"><Label htmlfor=\"${id}\">Label${' '}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n            </span></Label><p id=\"${`${id}-description`}\" class=\"text-muted-foreground text-xs\">A short description goes here.\n          </p></div></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-15.wxml",
          "target": "components/ui/checkbox-15/checkbox-15.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\"><checkbox id=\"{{id}}\" class=\"order-1 after:absolute after:inset-0\" aria-describedby=\"{{`${id}-description`}}\" /><view class=\"flex grow items-start gap-3\"><svg class=\"shrink-0\" width=\"{{32}}\" height=\"{{24}}\" viewbox=\"0 0 32 24\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\"><rect width=\"32\" height=\"24\" rx=\"4\" fill=\"#252525\" /><path d=\"M19.0537 6.49742H12.9282V17.5026H19.0537V6.49742Z\" fill=\"#FF5A00\" /><path d=\"M13.3359 12C13.3359 9.76408 14.3871 7.77961 16 6.49741C14.8129 5.56408 13.3155 5 11.6822 5C7.81295 5 4.68221 8.13074 4.68221 12C4.68221 15.8693 7.81295 19 11.6822 19C13.3155 19 14.8129 18.4359 16 17.5026C14.3848 16.2385 13.3359 14.2359 13.3359 12Z\" fill=\"#EB001B\" /><path d=\"M27.3178 12C27.3178 15.8693 24.1871 19 20.3178 19C18.6845 19 17.1871 18.4359 16 17.5026C17.6333 16.2181 18.6641 14.2359 18.6641 12C18.6641 9.76408 17.6129 7.77961 16 6.49741C17.1848 5.56408 18.6822 5 20.3155 5C24.1871 5 27.3178 8.15113 27.3178 12Z\" fill=\"#F79E1B\" /></svg><view class=\"grid gap-2\"><label htmlfor=\"{{id}}\">Label{{ ' ' }}<text class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n            </text></label><text id=\"{{`${id}-description`}}\" class=\"text-muted-foreground text-xs\">A short description goes here.\n          </text></view></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "checkbox",
          "label",
          "card",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "checkbox-15",
          "group": "checkbox",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "checkbox-15",
              "path": "registry/default/components/checkbox/checkbox-15.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "checkbox-15",
              "path": "registry/default/components/checkbox/checkbox-15.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "checkbox-15",
              "path": "registry/default/components/checkbox/checkbox-15.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "checkbox-15",
              "path": "registry/default/components/checkbox/checkbox-15.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "checkbox",
        "title": "Checkbox · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "checkbox"
      ]
    },
    {
      "name": "checkbox-16",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/checkbox.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/checkbox/checkbox-16.tsx",
          "type": "registry:component",
          "target": "components/ui/checkbox-16.tsx",
          "content": "import { useId } from 'react'\nimport { Checkbox, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\">\n      <Checkbox\n        id={id}\n        className=\"order-1 after:absolute after:inset-0\"\n        aria-describedby={`${id}-description`}\n      />\n      <div className=\"flex grow items-center gap-3\">\n        <svg\n          className=\"shrink-0\"\n          xmlns=\"http://www.w3.org/2000/svg\"\n          width={32}\n          height={32}\n          aria-hidden=\"true\"\n        >\n          <circle cx=\"16\" cy=\"16\" r=\"16\" fill=\"#121212\" />\n          <g clipPath=\"url(#sb-a)\">\n            <path\n              fill=\"url(#sb-b)\"\n              d=\"M17.63 25.52c-.506.637-1.533.287-1.545-.526l-.178-11.903h8.003c1.45 0 2.259 1.674 1.357 2.81l-7.637 9.618Z\"\n            />\n            <path\n              fill=\"url(#sb-c)\"\n              fillOpacity=\".2\"\n              d=\"M17.63 25.52c-.506.637-1.533.287-1.545-.526l-.178-11.903h8.003c1.45 0 2.259 1.674 1.357 2.81l-7.637 9.618Z\"\n            />\n            <path\n              fill=\"#3ECF8E\"\n              d=\"M14.375 6.367c.506-.638 1.532-.289 1.544.525l.078 11.903H8.094c-1.45 0-2.258-1.674-1.357-2.81l7.638-9.618Z\"\n            />\n          </g>\n          <defs>\n            <linearGradient\n              id=\"sb-b\"\n              x1=\"15.907\"\n              x2=\"23.02\"\n              y1=\"15.73\"\n              y2=\"18.713\"\n              gradientUnits=\"userSpaceOnUse\"\n            >\n              <stop stopColor=\"#249361\" />\n              <stop offset=\"1\" stopColor=\"#3ECF8E\" />\n            </linearGradient>\n            <linearGradient\n              id=\"sb-c\"\n              x1=\"12.753\"\n              x2=\"15.997\"\n              y1=\"11.412\"\n              y2=\"17.519\"\n              gradientUnits=\"userSpaceOnUse\"\n            >\n              <stop />\n              <stop offset=\"1\" stopOpacity=\"0\" />\n            </linearGradient>\n            <clipPath id=\"sb-a\">\n              <path fill=\"#fff\" d=\"M6.354 6h19.292v20H6.354z\" />\n            </clipPath>\n          </defs>\n        </svg>\n        <div className=\"grid gap-2\">\n          <Label htmlFor={id}>\n            Label{' '}\n            <span className=\"text-muted-foreground text-xs leading-[inherit] font-normal\">\n              (Sublabel)\n            </span>\n          </Label>\n          <p id={`${id}-description`} className=\"text-muted-foreground text-xs\">\n            A short description goes here.\n          </p>\n        </div>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-16.vue",
          "target": "components/ui/checkbox-16.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Checkbox } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'checkbox-16';\n\n</script>\n\n<template>\n  <div class=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\"><Checkbox :id=\"id\" class=\"order-1 after:absolute after:inset-0\" :aria-describedby=\"`${id}-description`\" /><div class=\"flex grow items-center gap-3\"><svg class=\"shrink-0\" xmlns=\"http://www.w3.org/2000/svg\" :width=\"32\" :height=\"32\" aria-hidden=\"true\"><circle cx=\"16\" cy=\"16\" r=\"16\" fill=\"#121212\" /><g clipPath=\"url(#sb-a)\"><path fill=\"url(#sb-b)\" d=\"M17.63 25.52c-.506.637-1.533.287-1.545-.526l-.178-11.903h8.003c1.45 0 2.259 1.674 1.357 2.81l-7.637 9.618Z\" /><path fill=\"url(#sb-c)\" fillOpacity=\".2\" d=\"M17.63 25.52c-.506.637-1.533.287-1.545-.526l-.178-11.903h8.003c1.45 0 2.259 1.674 1.357 2.81l-7.637 9.618Z\" /><path fill=\"#3ECF8E\" d=\"M14.375 6.367c.506-.638 1.532-.289 1.544.525l.078 11.903H8.094c-1.45 0-2.258-1.674-1.357-2.81l7.638-9.618Z\" /></g><defs><linearGradient id=\"sb-b\" x1=\"15.907\" x2=\"23.02\" y1=\"15.73\" y2=\"18.713\" gradientUnits=\"userSpaceOnUse\"><stop stopColor=\"#249361\" /><stop offset=\"1\" stopColor=\"#3ECF8E\" /></linearGradient><linearGradient id=\"sb-c\" x1=\"12.753\" x2=\"15.997\" y1=\"11.412\" y2=\"17.519\" gradientUnits=\"userSpaceOnUse\"><stop /><stop offset=\"1\" stopOpacity=\"0\" /></linearGradient><clipPath id=\"sb-a\"><path fill=\"#fff\" d=\"M6.354 6h19.292v20H6.354z\" /></clipPath></defs></svg><div class=\"grid gap-2\"><Label :htmlFor=\"id\">Label{{ ' ' }}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n            </span></Label><p :id=\"`${id}-description`\" class=\"text-muted-foreground text-xs\">A short description goes here.\n          </p></div></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-16.html",
          "target": "components/ui/checkbox-16.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\"><Checkbox id=\"${id}\" class=\"order-1 after:absolute after:inset-0\" aria-describedby=\"${`${id}-description`}\" /><div class=\"flex grow items-center gap-3\"><svg class=\"shrink-0\" xmlns=\"http://www.w3.org/2000/svg\" width=\"${32}\" height=\"${32}\" aria-hidden=\"true\"><circle cx=\"16\" cy=\"16\" r=\"16\" fill=\"#121212\" /><g clippath=\"url(#sb-a)\"><path fill=\"url(#sb-b)\" d=\"M17.63 25.52c-.506.637-1.533.287-1.545-.526l-.178-11.903h8.003c1.45 0 2.259 1.674 1.357 2.81l-7.637 9.618Z\" /><path fill=\"url(#sb-c)\" fillopacity=\".2\" d=\"M17.63 25.52c-.506.637-1.533.287-1.545-.526l-.178-11.903h8.003c1.45 0 2.259 1.674 1.357 2.81l-7.637 9.618Z\" /><path fill=\"#3ECF8E\" d=\"M14.375 6.367c.506-.638 1.532-.289 1.544.525l.078 11.903H8.094c-1.45 0-2.258-1.674-1.357-2.81l7.638-9.618Z\" /></g><defs><linearGradient id=\"sb-b\" x1=\"15.907\" x2=\"23.02\" y1=\"15.73\" y2=\"18.713\" gradientunits=\"userSpaceOnUse\"><stop stopcolor=\"#249361\" /><stop offset=\"1\" stopcolor=\"#3ECF8E\" /></linearGradient><linearGradient id=\"sb-c\" x1=\"12.753\" x2=\"15.997\" y1=\"11.412\" y2=\"17.519\" gradientunits=\"userSpaceOnUse\"><stop /><stop offset=\"1\" stopopacity=\"0\" /></linearGradient><clipPath id=\"sb-a\"><path fill=\"#fff\" d=\"M6.354 6h19.292v20H6.354z\" /></clipPath></defs></svg><div class=\"grid gap-2\"><Label htmlfor=\"${id}\">Label${' '}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n            </span></Label><p id=\"${`${id}-description`}\" class=\"text-muted-foreground text-xs\">A short description goes here.\n          </p></div></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-16.wxml",
          "target": "components/ui/checkbox-16/checkbox-16.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\"><checkbox id=\"{{id}}\" class=\"order-1 after:absolute after:inset-0\" aria-describedby=\"{{`${id}-description`}}\" /><view class=\"flex grow items-center gap-3\"><svg class=\"shrink-0\" xmlns=\"http://www.w3.org/2000/svg\" width=\"{{32}}\" height=\"{{32}}\" aria-hidden=\"true\"><circle cx=\"16\" cy=\"16\" r=\"16\" fill=\"#121212\" /><g clippath=\"url(#sb-a)\"><path fill=\"url(#sb-b)\" d=\"M17.63 25.52c-.506.637-1.533.287-1.545-.526l-.178-11.903h8.003c1.45 0 2.259 1.674 1.357 2.81l-7.637 9.618Z\" /><path fill=\"url(#sb-c)\" fillopacity=\".2\" d=\"M17.63 25.52c-.506.637-1.533.287-1.545-.526l-.178-11.903h8.003c1.45 0 2.259 1.674 1.357 2.81l-7.637 9.618Z\" /><path fill=\"#3ECF8E\" d=\"M14.375 6.367c.506-.638 1.532-.289 1.544.525l.078 11.903H8.094c-1.45 0-2.258-1.674-1.357-2.81l7.638-9.618Z\" /></g><defs><lineargradient id=\"sb-b\" x1=\"15.907\" x2=\"23.02\" y1=\"15.73\" y2=\"18.713\" gradientunits=\"userSpaceOnUse\"><stop stopcolor=\"#249361\" /><stop offset=\"1\" stopcolor=\"#3ECF8E\" /></lineargradient><lineargradient id=\"sb-c\" x1=\"12.753\" x2=\"15.997\" y1=\"11.412\" y2=\"17.519\" gradientunits=\"userSpaceOnUse\"><stop /><stop offset=\"1\" stopopacity=\"0\" /></lineargradient><clippath id=\"sb-a\"><path fill=\"#fff\" d=\"M6.354 6h19.292v20H6.354z\" /></clippath></defs></svg><view class=\"grid gap-2\"><label htmlfor=\"{{id}}\">Label{{ ' ' }}<text class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n            </text></label><text id=\"{{`${id}-description`}}\" class=\"text-muted-foreground text-xs\">A short description goes here.\n          </text></view></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "checkbox",
          "label",
          "card",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "checkbox-16",
          "group": "checkbox",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "checkbox-16",
              "path": "registry/default/components/checkbox/checkbox-16.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "checkbox-16",
              "path": "registry/default/components/checkbox/checkbox-16.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "checkbox-16",
              "path": "registry/default/components/checkbox/checkbox-16.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "checkbox-16",
              "path": "registry/default/components/checkbox/checkbox-16.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "checkbox",
        "title": "Checkbox · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "checkbox"
      ]
    },
    {
      "name": "checkbox-17",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/checkbox.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/checkbox/checkbox-17.tsx",
          "type": "registry:component",
          "target": "components/ui/checkbox-17.tsx",
          "content": "import { useId } from 'react'\nimport { Checkbox, Label } from '@timui/react'\nimport { Brush, Eraser, Scissors, SwatchBook } from 'lucide-react'\n\nexport default function Component() {\n  const id = useId()\n\n  const items = [\n    { value: '1', label: 'Palette', Icon: SwatchBook, defaultChecked: true },\n    { value: '2', label: 'Brush', Icon: Brush },\n    { value: '3', label: 'Eraser', Icon: Eraser },\n    { value: '4', label: 'Cut', Icon: Scissors },\n  ]\n\n  return (\n    <div className=\"grid grid-cols-2 gap-3\">\n      {items.map((item) => (\n        <div\n          key={`${id}-${item.value}`}\n          className=\"border-input has-data-[state=checked]:border-primary/50 relative flex cursor-pointer flex-col gap-4 rounded-md border p-4 shadow-xs outline-none\"\n        >\n          <div className=\"flex justify-between gap-2\">\n            <Checkbox\n              id={`${id}-${item.value}`}\n              value={item.value}\n              className=\"order-1 after:absolute after:inset-0\"\n              defaultChecked={item.defaultChecked}\n            />\n            <item.Icon className=\"opacity-60\" size={16} aria-hidden=\"true\" />\n          </div>\n          <Label htmlFor={`${id}-${item.value}`}>{item.label}</Label>\n        </div>\n      ))}\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-17.vue",
          "target": "components/ui/checkbox-17.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Brush, Eraser, Scissors, SwatchBook } from 'lucide-vue-next';\nimport { Checkbox } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'checkbox-17';\n\n\nconst items = [\n    { value: '1', label: 'Palette', Icon: SwatchBook, defaultChecked: true },\n    { value: '2', label: 'Brush', Icon: Brush },\n    { value: '3', label: 'Eraser', Icon: Eraser },\n    { value: '4', label: 'Cut', Icon: Scissors },\n  ]\n\n</script>\n\n<template>\n  <div class=\"grid grid-cols-2 gap-3\"><div v-for=\"(item, index) in items\" :key=\"`${id}-${item.value}`\" class=\"border-input has-data-[state=checked]:border-primary/50 relative flex cursor-pointer flex-col gap-4 rounded-md border p-4 shadow-xs outline-none\"><div class=\"flex justify-between gap-2\"><Checkbox :id=\"`${id}-${item.value}`\" :value=\"item.value\" class=\"order-1 after:absolute after:inset-0\" :defaultChecked=\"item.defaultChecked\" /><item.Icon class=\"opacity-60\" :size=\"16\" aria-hidden=\"true\" /></div><Label :htmlFor=\"`${id}-${item.value}`\">{{ item.label }}</Label></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-17.html",
          "target": "components/ui/checkbox-17.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"grid grid-cols-2 gap-3\"><!-- Loop items -->\n<div key=\"${`${id}-${item.value}`}\" class=\"border-input has-data-[state=checked]:border-primary/50 relative flex cursor-pointer flex-col gap-4 rounded-md border p-4 shadow-xs outline-none\"><div class=\"flex justify-between gap-2\"><Checkbox id=\"${`${id}-${item.value}`}\" value=\"${item.value}\" class=\"order-1 after:absolute after:inset-0\" defaultchecked=\"${item.defaultChecked}\" /><item.Icon class=\"opacity-60\" size=\"${16}\" aria-hidden=\"true\" /></div><Label htmlfor=\"${`${id}-${item.value}`}\">${item.label}</Label></div>\n<!-- End Loop --></div>\n</template>"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-17.wxml",
          "target": "components/ui/checkbox-17/checkbox-17.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"grid grid-cols-2 gap-3\"><view wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{`${id}-${item.value}`}}\" class=\"border-input has-data-[state=checked]:border-primary/50 relative flex cursor-pointer flex-col gap-4 rounded-md border p-4 shadow-xs outline-none\"><view class=\"flex justify-between gap-2\"><checkbox id=\"{{`${id}-${item.value}`}}\" value=\"{{item.value}}\" class=\"order-1 after:absolute after:inset-0\" defaultchecked=\"{{item.defaultChecked}}\" /><item.icon class=\"opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" /></view><label htmlfor=\"{{`${id}-${item.value}`}}\">{{ item.label }}</label></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "checkbox",
          "label",
          "card",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "checkbox-17",
          "group": "checkbox",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "checkbox-17",
              "path": "registry/default/components/checkbox/checkbox-17.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "checkbox-17",
              "path": "registry/default/components/checkbox/checkbox-17.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "checkbox-17",
              "path": "registry/default/components/checkbox/checkbox-17.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "checkbox-17",
              "path": "registry/default/components/checkbox/checkbox-17.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "checkbox",
        "title": "Checkbox · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "checkbox"
      ]
    },
    {
      "name": "checkbox-18",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/checkbox.json",
        "https://ui.timkit.cn/r/checkbox-tree.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/checkbox/checkbox-18.tsx",
          "type": "registry:component",
          "target": "components/ui/checkbox-18.tsx",
          "content": "'use client'\n\nimport { Fragment, useId } from 'react'\nimport { Checkbox, CheckboxTree, Label } from '@timui/react'\n\ninterface TreeNode {\n  id: string\n  label: string\n  defaultChecked?: boolean\n  children?: TreeNode[]\n}\n\nconst initialTree: TreeNode = {\n  id: '1',\n  label: 'Natural Wonders',\n  children: [\n    { id: '2', label: 'Mountains', defaultChecked: true },\n    {\n      id: '3',\n      label: 'Waterfalls',\n      children: [\n        { id: '4', label: 'Niagara Falls' },\n        { id: '5', label: 'Angel Falls', defaultChecked: true },\n      ],\n    },\n    { id: '6', label: 'Grand Canyon' },\n  ],\n}\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"space-y-3\">\n      <CheckboxTree\n        tree={initialTree}\n        renderNode={({ node, isChecked, onCheckedChange, children }) => (\n          <Fragment key={`${id}-${node.id}`}>\n            <div className=\"flex items-center gap-2\">\n              <Checkbox\n                id={`${id}-${node.id}`}\n                checked={isChecked}\n                onCheckedChange={onCheckedChange}\n              />\n              <Label htmlFor={`${id}-${node.id}`}>{node.label}</Label>\n            </div>\n            {children && <div className=\"ms-6 space-y-3\">{children}</div>}\n          </Fragment>\n        )}\n      />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-18.vue",
          "target": "components/ui/checkbox-18.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { h, type VNodeChild } from 'vue'\nimport type { CheckboxTreeNode } from '@timui/core'\nimport { Checkbox } from '@timui/vue'\nimport { CheckboxTree } from '@timui/vue'\nimport { Label } from '@timui/vue'\n\nconst id = 'checkbox-18'\n\nconst initialTree: CheckboxTreeNode = {\n  id: '1',\n  label: 'Natural Wonders',\n  children: [\n    { id: '2', label: 'Mountains', defaultChecked: true },\n    {\n      id: '3',\n      label: 'Waterfalls',\n      children: [\n        { id: '4', label: 'Niagara Falls' },\n        { id: '5', label: 'Angel Falls', defaultChecked: true },\n      ],\n    },\n    { id: '6', label: 'Grand Canyon' },\n  ],\n}\n\nfunction renderNode({\n  node,\n  isChecked,\n  onCheckedChange,\n  children,\n}: {\n  node: CheckboxTreeNode\n  isChecked: boolean | 'indeterminate'\n  onCheckedChange: () => void\n  children: VNodeChild[] | undefined\n}) {\n  const nodeId = `${id}-${node.id}`\n  return h('div', { class: 'space-y-3' }, [\n    h('div', { class: 'flex items-center gap-2' }, [\n      h(Checkbox, {\n        id: nodeId,\n        checked: isChecked,\n        onCheckedChange,\n      }),\n      h(Label, { htmlFor: nodeId }, () => node.label),\n    ]),\n    children ? h('div', { class: 'ms-6 space-y-3' }, children as VNodeChild[]) : null,\n  ])\n}\n</script>\n\n<template>\n  <div class=\"space-y-3\">\n    <CheckboxTree :tree=\"initialTree\" :renderNode=\"renderNode\" />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-18.html",
          "target": "components/ui/checkbox-18.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-3\"><CheckboxTree tree=\"${initialTree}\" rendernode=\"${({ node, isChecked, onCheckedChange, children }) => (\n          <Fragment key={`${id}-${node.id}`}>\n            <div className=\"flex items-center gap-2\">\n              <Checkbox\n                id={`${id}-${node.id}`}\n                checked={isChecked}\n                onCheckedChange={onCheckedChange}\n              />\n              <Label htmlFor={`${id}-${node.id}`}>{node.label}</Label>\n            </div>\n            {children && <div className=\"ms-6 space-y-3\">{children}</div>}\n          </Fragment>\n        )}\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-18.wxml",
          "target": "components/ui/checkbox-18/checkbox-18.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-3\"><checkboxtree tree=\"{{initialTree}}\" rendernode=\"{{({ node, isChecked, onCheckedChange, children }) => (\n          <Fragment key={`${id}-${node.id}`}>\n            <div className=\"flex items-center gap-2\">\n              <Checkbox\n                id={`${id}-${node.id}`}\n                checked={isChecked}\n                onCheckedChange={onCheckedChange}\n              />\n              <Label htmlFor={`${id}-${node.id}`}>{node.label}</Label>\n            </div>\n            {children && <div className=\"ms-6 space-y-3\">{children}</div>}\n          </Fragment>\n        )}}\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "checkbox",
          "label",
          "tree",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "checkbox-18",
          "group": "checkbox",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "checkbox-18",
              "path": "registry/default/components/checkbox/checkbox-18.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "checkbox-18",
              "path": "registry/default/components/checkbox/checkbox-18.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "checkbox-18",
              "path": "registry/default/components/checkbox/checkbox-18.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "checkbox-18",
              "path": "registry/default/components/checkbox/checkbox-18.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "checkbox",
        "title": "Checkbox · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "checkbox"
      ]
    },
    {
      "name": "checkbox-19",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/checkbox.json"
      ],
      "files": [
        {
          "path": "registry/default/components/checkbox/checkbox-19.tsx",
          "type": "registry:component",
          "target": "components/ui/checkbox-19.tsx",
          "content": "import { useId } from 'react'\nimport { Checkbox } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n\n  const items = [\n    { value: '1', label: 'Monday', defaultChecked: true },\n    { value: '2', label: 'Tuesday', defaultChecked: true },\n    { value: '3', label: 'Wednesday' },\n    { value: '4', label: 'Thursday', defaultChecked: true },\n    { value: '5', label: 'Friday', defaultChecked: true },\n    { value: '6', label: 'Saturday' },\n    { value: '7', label: 'Sunday', disabled: true },\n  ]\n\n  return (\n    <fieldset className=\"space-y-4\">\n      <legend className=\"text-foreground text-sm leading-none font-medium\">Days of the week</legend>\n      <div className=\"flex gap-1.5\">\n        {items.map((item) => (\n          <label\n            key={`${id}-${item.value}`}\n            className=\"border-input has-data-[state=checked]:border-primary has-data-[state=checked]:bg-primary has-data-[state=checked]:text-primary-foreground has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex size-9 cursor-pointer flex-col items-center justify-center gap-3 rounded-full border text-center shadow-xs transition-[color,box-shadow] outline-none has-focus-visible:ring-[3px] has-data-disabled:cursor-not-allowed has-data-disabled:opacity-50\"\n          >\n            <Checkbox\n              id={`${id}-${item.value}`}\n              value={item.value}\n              className=\"sr-only after:absolute after:inset-0\"\n              defaultChecked={item.defaultChecked}\n              disabled={item.disabled}\n            />\n            <span aria-hidden=\"true\" className=\"text-sm font-medium\">\n              {item.label[0]}\n            </span>\n            <span className=\"sr-only\">{item.label}</span>\n          </label>\n        ))}\n      </div>\n    </fieldset>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-19.vue",
          "target": "components/ui/checkbox-19.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Checkbox } from '@timui/vue';\n\n\n\n\n\nconst id = 'checkbox-19';\n\n\nconst items = [\n    { value: '1', label: 'Monday', defaultChecked: true },\n    { value: '2', label: 'Tuesday', defaultChecked: true },\n    { value: '3', label: 'Wednesday' },\n    { value: '4', label: 'Thursday', defaultChecked: true },\n    { value: '5', label: 'Friday', defaultChecked: true },\n    { value: '6', label: 'Saturday' },\n    { value: '7', label: 'Sunday', disabled: true },\n  ]\n\n</script>\n\n<template>\n  <fieldset class=\"space-y-4\"><legend class=\"text-foreground text-sm leading-none font-medium\">Days of the week</legend><div class=\"flex gap-1.5\"><label v-for=\"(item, index) in items\" :key=\"`${id}-${item.value}`\" class=\"border-input has-data-[state=checked]:border-primary has-data-[state=checked]:bg-primary has-data-[state=checked]:text-primary-foreground has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex size-9 cursor-pointer flex-col items-center justify-center gap-3 rounded-full border text-center shadow-xs transition-[color,box-shadow] outline-none has-focus-visible:ring-[3px] has-data-disabled:cursor-not-allowed has-data-disabled:opacity-50\"><Checkbox :id=\"`${id}-${item.value}`\" :value=\"item.value\" class=\"sr-only after:absolute after:inset-0\" :defaultChecked=\"item.defaultChecked\" :disabled=\"item.disabled\" /><span aria-hidden=\"true\" class=\"text-sm font-medium\">{{ item.label[0] }}</span><span class=\"sr-only\">{{ item.label }}</span></label></div></fieldset>\n</template>\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-19.html",
          "target": "components/ui/checkbox-19.html",
          "type": "registry:component",
          "content": "<template>\n  <fieldset class=\"space-y-4\"><legend class=\"text-foreground text-sm leading-none font-medium\">Days of the week</legend><div class=\"flex gap-1.5\"><!-- Loop items -->\n<label key=\"${`${id}-${item.value}`}\" class=\"border-input has-data-[state=checked]:border-primary has-data-[state=checked]:bg-primary has-data-[state=checked]:text-primary-foreground has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex size-9 cursor-pointer flex-col items-center justify-center gap-3 rounded-full border text-center shadow-xs transition-[color,box-shadow] outline-none has-focus-visible:ring-[3px] has-data-disabled:cursor-not-allowed has-data-disabled:opacity-50\"><Checkbox id=\"${`${id}-${item.value}`}\" value=\"${item.value}\" class=\"sr-only after:absolute after:inset-0\" defaultchecked=\"${item.defaultChecked}\" disabled=\"${item.disabled}\" /><span aria-hidden=\"true\" class=\"text-sm font-medium\">${item.label[0]}</span><span class=\"sr-only\">${item.label}</span></label>\n<!-- End Loop --></div></fieldset>\n</template>"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-19.wxml",
          "target": "components/ui/checkbox-19/checkbox-19.wxml",
          "type": "registry:component",
          "content": "<view>\n  <fieldset class=\"space-y-4\"><legend class=\"text-foreground text-sm leading-none font-medium\">Days of the week</legend><view class=\"flex gap-1.5\"><label wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{`${id}-${item.value}`}}\" class=\"border-input has-data-[state=checked]:border-primary has-data-[state=checked]:bg-primary has-data-[state=checked]:text-primary-foreground has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex size-9 cursor-pointer flex-col items-center justify-center gap-3 rounded-full border text-center shadow-xs transition-[color,box-shadow] outline-none has-focus-visible:ring-[3px] has-data-disabled:cursor-not-allowed has-data-disabled:opacity-50\"><checkbox id=\"{{`${id}-${item.value}`}}\" value=\"{{item.value}}\" class=\"sr-only after:absolute after:inset-0\" defaultchecked=\"{{item.defaultChecked}}\" disabled=\"{{item.disabled}}\" /><text aria-hidden=\"true\" class=\"text-sm font-medium\">{{ item.label[0] }}</text><text class=\"sr-only\">{{ item.label }}</text></label></view></fieldset>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "checkbox",
          "label",
          "week",
          "calendar",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "checkbox-19",
          "group": "checkbox",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "checkbox-19",
              "path": "registry/default/components/checkbox/checkbox-19.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "checkbox-19",
              "path": "registry/default/components/checkbox/checkbox-19.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "checkbox-19",
              "path": "registry/default/components/checkbox/checkbox-19.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "checkbox-19",
              "path": "registry/default/components/checkbox/checkbox-19.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "checkbox",
        "title": "Checkbox · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "checkbox"
      ]
    },
    {
      "name": "checkbox-20",
      "type": "registry:component",
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/checkbox/checkbox-20.tsx",
          "type": "registry:component",
          "target": "components/ui/checkbox-20.tsx",
          "content": "'use client'\n\nimport { useId, useState } from 'react'\nimport { Checkbox, Label } from '@timui/react'\nimport { MoonIcon, SunIcon } from 'lucide-react'\n\nexport default function Component() {\n  const id = useId()\n  const [isDark, setIsDark] = useState(false)\n\n  return (\n    <fieldset className=\"space-y-4\">\n      <legend className=\"text-foreground text-sm leading-none font-medium\">\n        Dark mode toggle checkbox\n      </legend>\n      <div className=\"flex items-center gap-2\">\n        <Checkbox\n          id={id}\n          checked={isDark}\n          onCheckedChange={(checked) => setIsDark(checked === true)}\n        />\n        <Label htmlFor={id} className=\"inline-flex items-center gap-2\">\n          <span className=\"border-input bg-background inline-flex size-9 items-center justify-center rounded-md border\">\n            {isDark ? (\n              <MoonIcon size={16} aria-hidden=\"true\" />\n            ) : (\n              <SunIcon size={16} aria-hidden=\"true\" />\n            )}\n          </span>\n          <span className=\"text-sm\">{isDark ? 'Dark' : 'Light'} mode</span>\n        </Label>\n      </div>\n    </fieldset>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-20.vue",
          "target": "components/ui/checkbox-20.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { MoonIcon, SunIcon } from 'lucide-vue-next'\nimport { Checkbox } from '@timui/vue'\nimport { Label } from '@timui/vue'\n\nconst id = 'checkbox-20'\nconst isDark = ref(false)\n\nfunction setChecked(checked: boolean | 'indeterminate') {\n  isDark.value = checked === true\n}\n</script>\n\n<template>\n  <fieldset class=\"space-y-4\">\n    <legend class=\"text-foreground text-sm leading-none font-medium\">Dark mode toggle checkbox</legend>\n    <div class=\"flex items-center gap-2\">\n      <Checkbox :id=\"id\" :checked=\"isDark\" :onCheckedChange=\"setChecked\" />\n      <Label :htmlFor=\"id\" class=\"inline-flex items-center gap-2\">\n        <span class=\"border-input bg-background inline-flex size-9 items-center justify-center rounded-md border\">\n          <MoonIcon v-if=\"isDark\" :size=\"16\" aria-hidden=\"true\" />\n          <SunIcon v-else :size=\"16\" aria-hidden=\"true\" />\n        </span>\n        <span class=\"text-sm\">{{ isDark ? 'Dark' : 'Light' }} mode</span>\n      </Label>\n    </div>\n  </fieldset>\n</template>\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-20.html",
          "target": "components/ui/checkbox-20.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-4\"><legend class=\"text-foreground text-sm leading-none font-medium\">Dark mode toggle checkbox\n      </legend><div class=\"flex flex-col justify-center\"><input type=\"checkbox\" name=\"${id}\" id=\"${id}\" class=\"peer sr-only\" checked=\"${theme === 'dark'}\" onchange=\"${() => setTheme((prev) => (prev === 'dark' ? 'light' : 'dark'))}\" /><label class=\"group border-input bg-background text-foreground hover:bg-accent hover:text-accent-foreground peer-focus-visible:border-ring peer-focus-visible:ring-ring/50 relative inline-flex size-9 items-center justify-center rounded-md border shadow-xs transition-[color,box-shadow] outline-none peer-focus-visible:ring-[3px]\" htmlfor=\"${id}\" aria-label=\"${`Switch to ${theme === 'dark' ? 'light' : 'dark'} mode`}\"><MoonIcon size=\"${16}\" class=\"shrink-0 scale-0 opacity-0 transition-all group-peer-checked:scale-100 group-peer-checked:opacity-100\" aria-hidden=\"true\" /><SunIcon size=\"${16}\" class=\"absolute shrink-0 scale-100 opacity-100 transition-all group-peer-checked:scale-0 group-peer-checked:opacity-0\" aria-hidden=\"true\" /></label></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-20.wxml",
          "target": "components/ui/checkbox-20/checkbox-20.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-4\"><legend class=\"text-foreground text-sm leading-none font-medium\">Dark mode toggle checkbox\n      </legend><view class=\"flex flex-col justify-center\"><input type=\"checkbox\" name=\"{{id}}\" id=\"{{id}}\" class=\"peer sr-only\" checked=\"{{theme === 'dark'}}\" onchange=\"{{() => setTheme((prev) => (prev === 'dark' ? 'light' : 'dark'))}}\" /><label class=\"group border-input bg-background text-foreground hover:bg-accent hover:text-accent-foreground peer-focus-visible:border-ring peer-focus-visible:ring-ring/50 relative inline-flex size-9 items-center justify-center rounded-md border shadow-xs transition-[color,box-shadow] outline-none peer-focus-visible:ring-[3px]\" htmlfor=\"{{id}}\" aria-label=\"{{`Switch to ${theme === 'dark' ? 'light' : 'dark'} mode`}}\"><moonicon size=\"{{16}}\" class=\"shrink-0 scale-0 opacity-0 transition-all group-peer-checked:scale-100 group-peer-checked:opacity-100\" aria-hidden=\"true\" /><sunicon size=\"{{16}}\" class=\"absolute shrink-0 scale-100 opacity-100 transition-all group-peer-checked:scale-0 group-peer-checked:opacity-0\" aria-hidden=\"true\" /></label></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "checkbox",
          "label",
          "toggle",
          "darkmode",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "checkbox-20",
          "group": "checkbox",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "checkbox-20",
              "path": "registry/default/components/checkbox/checkbox-20.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "checkbox-20",
              "path": "registry/default/components/checkbox/checkbox-20.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "checkbox-20",
              "path": "registry/default/components/checkbox/checkbox-20.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "checkbox-20",
              "path": "registry/default/components/checkbox/checkbox-20.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "checkbox",
        "title": "Checkbox · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "checkbox"
      ]
    },
    {
      "name": "checkbox-09",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/checkbox.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/checkbox/checkbox-09.tsx",
          "type": "registry:component",
          "target": "components/ui/checkbox-09.tsx",
          "content": "import { useId } from 'react'\nimport { Checkbox, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"grid gap-3\">\n      <div className=\"flex items-center gap-2\">\n        <Checkbox id={`${id}-1`} />\n        <Label htmlFor={`${id}-1`}>React</Label>\n      </div>\n      <div className=\"flex items-center gap-2\">\n        <Checkbox id={`${id}-2`} />\n        <Label htmlFor={`${id}-2`}>Next.js</Label>\n      </div>\n      <div className=\"flex items-center gap-2\">\n        <Checkbox id={`${id}-3`} />\n        <Label htmlFor={`${id}-3`}>Astro</Label>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-09.vue",
          "target": "components/ui/checkbox-09.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Checkbox } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'checkbox-09';\n\n</script>\n\n<template>\n  <div class=\"grid gap-3\"><div class=\"flex items-center gap-2\"><Checkbox :id=\"`${id}-1`\" /><Label :htmlFor=\"`${id}-1`\">React</Label></div><div class=\"flex items-center gap-2\"><Checkbox :id=\"`${id}-2`\" /><Label :htmlFor=\"`${id}-2`\">Next.js</Label></div><div class=\"flex items-center gap-2\"><Checkbox :id=\"`${id}-3`\" /><Label :htmlFor=\"`${id}-3`\">Astro</Label></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-09.html",
          "target": "components/ui/checkbox-09.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"grid gap-3\"><div class=\"flex items-center gap-2\"><Checkbox id=\"${`${id}-1`}\" /><Label htmlfor=\"${`${id}-1`}\">React</Label></div><div class=\"flex items-center gap-2\"><Checkbox id=\"${`${id}-2`}\" /><Label htmlfor=\"${`${id}-2`}\">Next.js</Label></div><div class=\"flex items-center gap-2\"><Checkbox id=\"${`${id}-3`}\" /><Label htmlfor=\"${`${id}-3`}\">Astro</Label></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/checkbox/checkbox-09.wxml",
          "target": "components/ui/checkbox-09/checkbox-09.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"grid gap-3\"><view class=\"flex items-center gap-2\"><checkbox id=\"{{`${id}-1`}}\" /><label htmlfor=\"{{`${id}-1`}}\">React</label></view><view class=\"flex items-center gap-2\"><checkbox id=\"{{`${id}-2`}}\" /><label htmlfor=\"{{`${id}-2`}}\">Next.js</label></view><view class=\"flex items-center gap-2\"><checkbox id=\"{{`${id}-3`}}\" /><label htmlfor=\"{{`${id}-3`}}\">Astro</label></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "checkbox",
          "label",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "checkbox-09",
          "group": "checkbox",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "checkbox-09",
              "path": "registry/default/components/checkbox/checkbox-09.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "checkbox-09",
              "path": "registry/default/components/checkbox/checkbox-09.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "checkbox-09",
              "path": "registry/default/components/checkbox/checkbox-09.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "checkbox-09",
              "path": "registry/default/components/checkbox/checkbox-09.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "checkbox",
        "title": "Checkbox · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "checkbox"
      ]
    },
    {
      "name": "radio-01",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/radio-group.json"
      ],
      "files": [
        {
          "path": "registry/default/components/radio/radio-01.tsx",
          "type": "registry:component",
          "target": "components/ui/radio-01.tsx",
          "content": "import { useId } from 'react'\nimport { Label, RadioGroup, RadioGroupItem } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <RadioGroup defaultValue=\"1\">\n      <div className=\"flex items-center gap-2\">\n        <RadioGroupItem value=\"1\" id={`${id}-1`} />\n        <Label htmlFor={`${id}-1`}>Option 1</Label>\n      </div>\n      <div className=\"flex items-center gap-2\">\n        <RadioGroupItem value=\"2\" id={`${id}-2`} />\n        <Label htmlFor={`${id}-2`}>Option 2</Label>\n      </div>\n      <div className=\"flex items-center gap-2\">\n        <RadioGroupItem value=\"3\" id={`${id}-3`} />\n        <Label htmlFor={`${id}-3`}>Option 3</Label>\n      </div>\n    </RadioGroup>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/radio/radio-01.vue",
          "target": "components/ui/radio-01.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { RadioGroup } from '@timui/vue';\nimport { RadioGroupItem } from '@timui/vue';\n\n\n\n\n\nconst id = 'radio-01';\n\n</script>\n\n<template>\n  <RadioGroup default-value=\"1\"><div class=\"flex items-center gap-2\"><RadioGroupItem value=\"1\" :id=\"`${id}-1`\" /><Label :htmlFor=\"`${id}-1`\">Option 1</Label></div><div class=\"flex items-center gap-2\"><RadioGroupItem value=\"2\" :id=\"`${id}-2`\" /><Label :htmlFor=\"`${id}-2`\">Option 2</Label></div><div class=\"flex items-center gap-2\"><RadioGroupItem value=\"3\" :id=\"`${id}-3`\" /><Label :htmlFor=\"`${id}-3`\">Option 3</Label></div></RadioGroup>\n</template>\n"
        },
        {
          "path": "registry/default/components/radio/radio-01.html",
          "target": "components/ui/radio-01.html",
          "type": "registry:component",
          "content": "<template>\n  <RadioGroup default-value=\"1\"><div class=\"flex items-center gap-2\"><RadioGroupItem value=\"1\" id=\"${`${id}-1`}\" /><Label htmlfor=\"${`${id}-1`}\">Option 1</Label></div><div class=\"flex items-center gap-2\"><RadioGroupItem value=\"2\" id=\"${`${id}-2`}\" /><Label htmlfor=\"${`${id}-2`}\">Option 2</Label></div><div class=\"flex items-center gap-2\"><RadioGroupItem value=\"3\" id=\"${`${id}-3`}\" /><Label htmlfor=\"${`${id}-3`}\">Option 3</Label></div></RadioGroup>\n</template>"
        },
        {
          "path": "registry/default/components/radio/radio-01.wxml",
          "target": "components/ui/radio-01/radio-01.wxml",
          "type": "registry:component",
          "content": "<view>\n  <radiogroup default-value=\"1\"><view class=\"flex items-center gap-2\"><radiogroupitem value=\"1\" id=\"{{`${id}-1`}}\" /><label htmlfor=\"{{`${id}-1`}}\">Option 1</label></view><view class=\"flex items-center gap-2\"><radiogroupitem value=\"2\" id=\"{{`${id}-2`}}\" /><label htmlfor=\"{{`${id}-2`}}\">Option 2</label></view><view class=\"flex items-center gap-2\"><radiogroupitem value=\"3\" id=\"{{`${id}-3`}}\" /><label htmlfor=\"{{`${id}-3`}}\">Option 3</label></view></radiogroup>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "radio",
          "label",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "radio-01",
          "group": "radio",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "radio-01",
              "path": "registry/default/components/radio/radio-01.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "radio-01",
              "path": "registry/default/components/radio/radio-01.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "radio-01",
              "path": "registry/default/components/radio/radio-01.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "radio-01",
              "path": "registry/default/components/radio/radio-01.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "radio",
        "title": "Radio · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "radio"
      ]
    },
    {
      "name": "radio-02",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/radio-group.json"
      ],
      "files": [
        {
          "path": "registry/default/components/radio/radio-02.tsx",
          "type": "registry:component",
          "target": "components/ui/radio-02.tsx",
          "content": "import { useId } from 'react'\nimport { Label, RadioGroup, RadioGroupItem } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <RadioGroup\n      defaultValue=\"1\"\n      className=\"[--primary:var(--color-indigo-500)] [--ring:var(--color-indigo-300)] in-[.dark]:[--primary:var(--color-indigo-500)] in-[.dark]:[--ring:var(--color-indigo-900)]\"\n    >\n      <div className=\"flex items-center gap-2\">\n        <RadioGroupItem value=\"1\" id={`${id}-1`} />\n        <Label htmlFor={`${id}-1`}>Option 1</Label>\n      </div>\n      <div className=\"flex items-center gap-2\">\n        <RadioGroupItem value=\"2\" id={`${id}-2`} />\n        <Label htmlFor={`${id}-2`}>Option 2</Label>\n      </div>\n      <div className=\"flex items-center gap-2\">\n        <RadioGroupItem value=\"3\" id={`${id}-3`} />\n        <Label htmlFor={`${id}-3`}>Option 3</Label>\n      </div>\n    </RadioGroup>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/radio/radio-02.vue",
          "target": "components/ui/radio-02.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { RadioGroup } from '@timui/vue';\nimport { RadioGroupItem } from '@timui/vue';\n\n\n\n\n\nconst id = 'radio-02';\n\n</script>\n\n<template>\n  <RadioGroup default-value=\"1\" class=\"[--primary:var(--color-indigo-500)] [--ring:var(--color-indigo-300)] in-[.dark]:[--primary:var(--color-indigo-500)] in-[.dark]:[--ring:var(--color-indigo-900)]\"><div class=\"flex items-center gap-2\"><RadioGroupItem value=\"1\" :id=\"`${id}-1`\" /><Label :htmlFor=\"`${id}-1`\">Option 1</Label></div><div class=\"flex items-center gap-2\"><RadioGroupItem value=\"2\" :id=\"`${id}-2`\" /><Label :htmlFor=\"`${id}-2`\">Option 2</Label></div><div class=\"flex items-center gap-2\"><RadioGroupItem value=\"3\" :id=\"`${id}-3`\" /><Label :htmlFor=\"`${id}-3`\">Option 3</Label></div></RadioGroup>\n</template>\n"
        },
        {
          "path": "registry/default/components/radio/radio-02.html",
          "target": "components/ui/radio-02.html",
          "type": "registry:component",
          "content": "<template>\n  <RadioGroup default-value=\"1\" class=\"[--primary:var(--color-indigo-500)] [--ring:var(--color-indigo-300)] in-[.dark]:[--primary:var(--color-indigo-500)] in-[.dark]:[--ring:var(--color-indigo-900)]\"><div class=\"flex items-center gap-2\"><RadioGroupItem value=\"1\" id=\"${`${id}-1`}\" /><Label htmlfor=\"${`${id}-1`}\">Option 1</Label></div><div class=\"flex items-center gap-2\"><RadioGroupItem value=\"2\" id=\"${`${id}-2`}\" /><Label htmlfor=\"${`${id}-2`}\">Option 2</Label></div><div class=\"flex items-center gap-2\"><RadioGroupItem value=\"3\" id=\"${`${id}-3`}\" /><Label htmlfor=\"${`${id}-3`}\">Option 3</Label></div></RadioGroup>\n</template>"
        },
        {
          "path": "registry/default/components/radio/radio-02.wxml",
          "target": "components/ui/radio-02/radio-02.wxml",
          "type": "registry:component",
          "content": "<view>\n  <radiogroup default-value=\"1\" class=\"[--primary:var(--color-indigo-500)] [--ring:var(--color-indigo-300)] in-[.dark]:[--primary:var(--color-indigo-500)] in-[.dark]:[--ring:var(--color-indigo-900)]\"><view class=\"flex items-center gap-2\"><radiogroupitem value=\"1\" id=\"{{`${id}-1`}}\" /><label htmlfor=\"{{`${id}-1`}}\">Option 1</label></view><view class=\"flex items-center gap-2\"><radiogroupitem value=\"2\" id=\"{{`${id}-2`}}\" /><label htmlfor=\"{{`${id}-2`}}\">Option 2</label></view><view class=\"flex items-center gap-2\"><radiogroupitem value=\"3\" id=\"{{`${id}-3`}}\" /><label htmlfor=\"{{`${id}-3`}}\">Option 3</label></view></radiogroup>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "radio",
          "label",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "radio-02",
          "group": "radio",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "radio-02",
              "path": "registry/default/components/radio/radio-02.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "radio-02",
              "path": "registry/default/components/radio/radio-02.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "radio-02",
              "path": "registry/default/components/radio/radio-02.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "radio-02",
              "path": "registry/default/components/radio/radio-02.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "radio",
        "title": "Radio · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "radio"
      ]
    },
    {
      "name": "radio-03",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/radio-group.json"
      ],
      "files": [
        {
          "path": "registry/default/components/radio/radio-03.tsx",
          "type": "registry:component",
          "target": "components/ui/radio-03.tsx",
          "content": "import { useId } from 'react'\nimport { Label, RadioGroup, RadioGroupItem } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <RadioGroup defaultValue=\"2\" disabled>\n      <div className=\"flex items-center gap-2\">\n        <RadioGroupItem value=\"1\" id={`${id}-1`} />\n        <Label htmlFor={`${id}-1`}>Option 1</Label>\n      </div>\n      <div className=\"flex items-center gap-2\">\n        <RadioGroupItem value=\"2\" id={`${id}-2`} />\n        <Label htmlFor={`${id}-2`}>Option 2</Label>\n      </div>\n      <div className=\"flex items-center gap-2\">\n        <RadioGroupItem value=\"3\" id={`${id}-3`} />\n        <Label htmlFor={`${id}-3`}>Option 3</Label>\n      </div>\n    </RadioGroup>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/radio/radio-03.vue",
          "target": "components/ui/radio-03.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { RadioGroup } from '@timui/vue';\nimport { RadioGroupItem } from '@timui/vue';\n\n\n\n\n\nconst id = 'radio-03';\n\n</script>\n\n<template>\n  <RadioGroup default-value=\"2\" disabled><div class=\"flex items-center gap-2\"><RadioGroupItem value=\"1\" :id=\"`${id}-1`\" /><Label :htmlFor=\"`${id}-1`\">Option 1</Label></div><div class=\"flex items-center gap-2\"><RadioGroupItem value=\"2\" :id=\"`${id}-2`\" /><Label :htmlFor=\"`${id}-2`\">Option 2</Label></div><div class=\"flex items-center gap-2\"><RadioGroupItem value=\"3\" :id=\"`${id}-3`\" /><Label :htmlFor=\"`${id}-3`\">Option 3</Label></div></RadioGroup>\n</template>\n"
        },
        {
          "path": "registry/default/components/radio/radio-03.html",
          "target": "components/ui/radio-03.html",
          "type": "registry:component",
          "content": "<template>\n  <RadioGroup default-value=\"2\" disabled><div class=\"flex items-center gap-2\"><RadioGroupItem value=\"1\" id=\"${`${id}-1`}\" /><Label htmlfor=\"${`${id}-1`}\">Option 1</Label></div><div class=\"flex items-center gap-2\"><RadioGroupItem value=\"2\" id=\"${`${id}-2`}\" /><Label htmlfor=\"${`${id}-2`}\">Option 2</Label></div><div class=\"flex items-center gap-2\"><RadioGroupItem value=\"3\" id=\"${`${id}-3`}\" /><Label htmlfor=\"${`${id}-3`}\">Option 3</Label></div></RadioGroup>\n</template>"
        },
        {
          "path": "registry/default/components/radio/radio-03.wxml",
          "target": "components/ui/radio-03/radio-03.wxml",
          "type": "registry:component",
          "content": "<view>\n  <radiogroup default-value=\"2\" disabled><view class=\"flex items-center gap-2\"><radiogroupitem value=\"1\" id=\"{{`${id}-1`}}\" /><label htmlfor=\"{{`${id}-1`}}\">Option 1</label></view><view class=\"flex items-center gap-2\"><radiogroupitem value=\"2\" id=\"{{`${id}-2`}}\" /><label htmlfor=\"{{`${id}-2`}}\">Option 2</label></view><view class=\"flex items-center gap-2\"><radiogroupitem value=\"3\" id=\"{{`${id}-3`}}\" /><label htmlfor=\"{{`${id}-3`}}\">Option 3</label></view></radiogroup>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "radio",
          "label",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "radio-03",
          "group": "radio",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "radio-03",
              "path": "registry/default/components/radio/radio-03.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "radio-03",
              "path": "registry/default/components/radio/radio-03.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "radio-03",
              "path": "registry/default/components/radio/radio-03.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "radio-03",
              "path": "registry/default/components/radio/radio-03.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "radio",
        "title": "Radio · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "radio"
      ]
    },
    {
      "name": "radio-04",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/radio-group.json"
      ],
      "files": [
        {
          "path": "registry/default/components/radio/radio-04.tsx",
          "type": "registry:component",
          "target": "components/ui/radio-04.tsx",
          "content": "import { useId } from 'react'\nimport { Label, RadioGroup, RadioGroupItem } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <RadioGroup className=\"gap-6\" defaultValue=\"1\">\n      <div className=\"flex items-start gap-2\">\n        <RadioGroupItem value=\"1\" id={`${id}-1`} aria-describedby={`${id}-1-description`} />\n        <div className=\"grid grow gap-2\">\n          <Label htmlFor={`${id}-1`}>\n            Small{' '}\n            <span className=\"text-muted-foreground text-xs leading-[inherit] font-normal\">\n              (Sublabel)\n            </span>\n          </Label>\n          <p id={`${id}-1-description`} className=\"text-muted-foreground text-xs\">\n            You can use this card with a label and a description.\n          </p>\n        </div>\n      </div>\n      <div className=\"flex items-start gap-2\">\n        <RadioGroupItem value=\"2\" id={`${id}-2`} aria-describedby={`${id}-2-description`} />\n        <div className=\"grid grow gap-2\">\n          <Label htmlFor={`${id}-2`}>\n            Large{' '}\n            <span className=\"text-muted-foreground text-xs leading-[inherit] font-normal\">\n              (Sublabel)\n            </span>\n          </Label>\n          <p id={`${id}-2-description`} className=\"text-muted-foreground text-xs\">\n            You can use this card with a label and a description.\n          </p>\n        </div>\n      </div>\n    </RadioGroup>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/radio/radio-04.vue",
          "target": "components/ui/radio-04.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { RadioGroup } from '@timui/vue';\nimport { RadioGroupItem } from '@timui/vue';\n\n\n\n\n\nconst id = 'radio-04';\n\n</script>\n\n<template>\n  <RadioGroup class=\"gap-6\" default-value=\"1\"><div class=\"flex items-start gap-2\"><RadioGroupItem value=\"1\" :id=\"`${id}-1`\" :aria-describedby=\"`${id}-1-description`\" /><div class=\"grid grow gap-2\"><Label :htmlFor=\"`${id}-1`\">Small{{ ' ' }}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n            </span></Label><p :id=\"`${id}-1-description`\" class=\"text-muted-foreground text-xs\">You can use this card with a label and a description.\n          </p></div></div><div class=\"flex items-start gap-2\"><RadioGroupItem value=\"2\" :id=\"`${id}-2`\" :aria-describedby=\"`${id}-2-description`\" /><div class=\"grid grow gap-2\"><Label :htmlFor=\"`${id}-2`\">Large{{ ' ' }}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n            </span></Label><p :id=\"`${id}-2-description`\" class=\"text-muted-foreground text-xs\">You can use this card with a label and a description.\n          </p></div></div></RadioGroup>\n</template>\n"
        },
        {
          "path": "registry/default/components/radio/radio-04.html",
          "target": "components/ui/radio-04.html",
          "type": "registry:component",
          "content": "<template>\n  <RadioGroup class=\"gap-6\" default-value=\"1\"><div class=\"flex items-start gap-2\"><RadioGroupItem value=\"1\" id=\"${`${id}-1`}\" aria-describedby=\"${`${id}-1-description`}\" /><div class=\"grid grow gap-2\"><Label htmlfor=\"${`${id}-1`}\">Small${' '}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n            </span></Label><p id=\"${`${id}-1-description`}\" class=\"text-muted-foreground text-xs\">You can use this card with a label and a description.\n          </p></div></div><div class=\"flex items-start gap-2\"><RadioGroupItem value=\"2\" id=\"${`${id}-2`}\" aria-describedby=\"${`${id}-2-description`}\" /><div class=\"grid grow gap-2\"><Label htmlfor=\"${`${id}-2`}\">Large${' '}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n            </span></Label><p id=\"${`${id}-2-description`}\" class=\"text-muted-foreground text-xs\">You can use this card with a label and a description.\n          </p></div></div></RadioGroup>\n</template>"
        },
        {
          "path": "registry/default/components/radio/radio-04.wxml",
          "target": "components/ui/radio-04/radio-04.wxml",
          "type": "registry:component",
          "content": "<view>\n  <radiogroup class=\"gap-6\" default-value=\"1\"><view class=\"flex items-start gap-2\"><radiogroupitem value=\"1\" id=\"{{`${id}-1`}}\" aria-describedby=\"{{`${id}-1-description`}}\" /><view class=\"grid grow gap-2\"><label htmlfor=\"{{`${id}-1`}}\">Small{{ ' ' }}<text class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n            </text></label><text id=\"{{`${id}-1-description`}}\" class=\"text-muted-foreground text-xs\">You can use this card with a label and a description.\n          </text></view></view><view class=\"flex items-start gap-2\"><radiogroupitem value=\"2\" id=\"{{`${id}-2`}}\" aria-describedby=\"{{`${id}-2-description`}}\" /><view class=\"grid grow gap-2\"><label htmlfor=\"{{`${id}-2`}}\">Large{{ ' ' }}<text class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n            </text></label><text id=\"{{`${id}-2-description`}}\" class=\"text-muted-foreground text-xs\">You can use this card with a label and a description.\n          </text></view></view></radiogroup>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "radio",
          "label",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "radio-04",
          "group": "radio",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "radio-04",
              "path": "registry/default/components/radio/radio-04.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "radio-04",
              "path": "registry/default/components/radio/radio-04.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "radio-04",
              "path": "registry/default/components/radio/radio-04.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "radio-04",
              "path": "registry/default/components/radio/radio-04.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "radio",
        "title": "Radio · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "radio"
      ]
    },
    {
      "name": "radio-05",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/radio-group.json"
      ],
      "files": [
        {
          "path": "registry/default/components/radio/radio-05.tsx",
          "type": "registry:component",
          "target": "components/ui/radio-05.tsx",
          "content": "'use client'\n\nimport { useEffect, useId, useRef, useState } from 'react'\nimport { Input, Label, RadioGroup, RadioGroupItem } from '@timui/react'\n\nexport default function Component() {\n  const radioId = useId()\n  const inputId = useId()\n  const [selectedValue, setSelectedValue] = useState('without-expansion')\n  const inputRef = useRef<HTMLInputElement>(null)\n\n  useEffect(() => {\n    if (selectedValue === 'with-expansion' && inputRef.current) {\n      inputRef.current.focus()\n    }\n  }, [selectedValue])\n\n  return (\n    <RadioGroup className=\"gap-6\" value={selectedValue} onValueChange={setSelectedValue}>\n      <div>\n        <div className=\"flex items-start gap-2\">\n          <RadioGroupItem\n            value=\"with-expansion\"\n            id={`${radioId}-1`}\n            aria-describedby={`${radioId}-1-description`}\n            aria-controls={inputId}\n          />\n          <div className=\"grow\">\n            <div className=\"grid grow gap-2\">\n              <Label htmlFor={`${radioId}-1`}>Radio with expansion</Label>\n              <p id={`${radioId}-1-description`} className=\"text-muted-foreground text-xs\">\n                You can use this radio with a label and a description.\n              </p>\n            </div>\n            {/* Expandable field */}\n            <div\n              role=\"region\"\n              id={inputId}\n              aria-labelledby={`${radioId}-1`}\n              className=\"grid transition-all ease-in-out data-[state=collapsed]:grid-rows-[0fr] data-[state=collapsed]:opacity-0 data-[state=expanded]:grid-rows-[1fr] data-[state=expanded]:opacity-100\"\n              data-state={selectedValue === 'with-expansion' ? 'expanded' : 'collapsed'}\n            >\n              <div className=\"pointer-events-none -m-2 overflow-hidden p-2\">\n                <div className=\"pointer-events-auto mt-3\">\n                  <Input\n                    ref={inputRef}\n                    type=\"text\"\n                    id=\"radio-05-additional-info\"\n                    placeholder=\"Enter details\"\n                    aria-label=\"Additional Information\"\n                    disabled={selectedValue !== 'with-expansion'}\n                  />\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n\n      <div className=\"flex items-start gap-2\">\n        <RadioGroupItem\n          value=\"without-expansion\"\n          id={`${radioId}-2`}\n          aria-describedby={`${radioId}-2-description`}\n        />\n        <div className=\"grid grow gap-2\">\n          <Label htmlFor={`${radioId}-2`}>Radio without expansion</Label>\n          <p id={`${radioId}-2-description`} className=\"text-muted-foreground text-xs\">\n            You can use this checkbox with a label and a description.\n          </p>\n        </div>\n      </div>\n    </RadioGroup>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/radio/radio-05.vue",
          "target": "components/ui/radio-05.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\nimport { RadioGroup } from '@timui/vue';\nimport { RadioGroupItem } from '@timui/vue';\n\n\n\nconst selectedValue = ref('without-expansion');\n\n\nfunction setSelectedValue(next: typeof selectedValue.value | ((prev: typeof selectedValue.value) => typeof selectedValue.value)) {\n  selectedValue.value = typeof next === 'function'\n    ? (next as (prev: typeof selectedValue.value) => typeof selectedValue.value)(selectedValue.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <RadioGroup class=\"gap-6\" :value=\"selectedValue\" @update:modelValue=\"setSelectedValue\"><div><div class=\"flex items-start gap-2\"><RadioGroupItem value=\"with-expansion\" :id=\"`${radioId}-1`\" :aria-describedby=\"`${radioId}-1-description`\" :aria-controls=\"inputId\" /><div class=\"grow\"><div class=\"grid grow gap-2\"><Label :htmlFor=\"`${radioId}-1`\">Radio with expansion</Label><p :id=\"`${radioId}-1-description`\" class=\"text-muted-foreground text-xs\">You can use this radio with a label and a description.\n              </p></div><div role=\"region\" :id=\"inputId\" :aria-labelledby=\"`${radioId}-1`\" class=\"grid transition-all ease-in-out data-[state=collapsed]:grid-rows-[0fr] data-[state=collapsed]:opacity-0 data-[state=expanded]:grid-rows-[1fr] data-[state=expanded]:opacity-100\" :data-state=\"selectedValue === 'with-expansion' ? 'expanded' : 'collapsed'\"><div class=\"pointer-events-none -m-2 overflow-hidden p-2\"><div class=\"pointer-events-auto mt-3\"><Input :ref=\"inputRef\" type=\"text\" id=\"radio-05-additional-info\" placeholder=\"Enter details\" aria-label=\"Additional Information\" :disabled=\"selectedValue !== 'with-expansion'\" /></div></div></div></div></div></div><div class=\"flex items-start gap-2\"><RadioGroupItem value=\"without-expansion\" :id=\"`${radioId}-2`\" :aria-describedby=\"`${radioId}-2-description`\" /><div class=\"grid grow gap-2\"><Label :htmlFor=\"`${radioId}-2`\">Radio without expansion</Label><p :id=\"`${radioId}-2-description`\" class=\"text-muted-foreground text-xs\">You can use this checkbox with a label and a description.\n          </p></div></div></RadioGroup>\n</template>\n"
        },
        {
          "path": "registry/default/components/radio/radio-05.html",
          "target": "components/ui/radio-05.html",
          "type": "registry:component",
          "content": "<template>\n  <RadioGroup class=\"gap-6\" value=\"${selectedValue}\" on-value-change=\"${setSelectedValue}\"><div><div class=\"flex items-start gap-2\"><RadioGroupItem value=\"with-expansion\" id=\"${`${radioId}-1`}\" aria-describedby=\"${`${radioId}-1-description`}\" aria-controls=\"${inputId}\" /><div class=\"grow\"><div class=\"grid grow gap-2\"><Label htmlfor=\"${`${radioId}-1`}\">Radio with expansion</Label><p id=\"${`${radioId}-1-description`}\" class=\"text-muted-foreground text-xs\">You can use this radio with a label and a description.\n              </p></div><div role=\"region\" id=\"${inputId}\" aria-labelledby=\"${`${radioId}-1`}\" class=\"grid transition-all ease-in-out data-[state=collapsed]:grid-rows-[0fr] data-[state=collapsed]:opacity-0 data-[state=expanded]:grid-rows-[1fr] data-[state=expanded]:opacity-100\" data-state=\"${selectedValue === 'with-expansion' ? 'expanded' : 'collapsed'}\"><div class=\"pointer-events-none -m-2 overflow-hidden p-2\"><div class=\"pointer-events-auto mt-3\"><Input ref=\"${inputRef}\" type=\"text\" id=\"radio-05-additional-info\" placeholder=\"Enter details\" aria-label=\"Additional Information\" disabled=\"${selectedValue !== 'with-expansion'}\" /></div></div></div></div></div></div><div class=\"flex items-start gap-2\"><RadioGroupItem value=\"without-expansion\" id=\"${`${radioId}-2`}\" aria-describedby=\"${`${radioId}-2-description`}\" /><div class=\"grid grow gap-2\"><Label htmlfor=\"${`${radioId}-2`}\">Radio without expansion</Label><p id=\"${`${radioId}-2-description`}\" class=\"text-muted-foreground text-xs\">You can use this checkbox with a label and a description.\n          </p></div></div></RadioGroup>\n</template>"
        },
        {
          "path": "registry/default/components/radio/radio-05.wxml",
          "target": "components/ui/radio-05/radio-05.wxml",
          "type": "registry:component",
          "content": "<view>\n  <radiogroup class=\"gap-6\" value=\"{{selectedValue}}\" bindchange=\"setSelectedValue\"><view><view class=\"flex items-start gap-2\"><radiogroupitem value=\"with-expansion\" id=\"{{`${radioId}-1`}}\" aria-describedby=\"{{`${radioId}-1-description`}}\" aria-controls=\"{{inputId}}\" /><view class=\"grow\"><view class=\"grid grow gap-2\"><label htmlfor=\"{{`${radioId}-1`}}\">Radio with expansion</label><text id=\"{{`${radioId}-1-description`}}\" class=\"text-muted-foreground text-xs\">You can use this radio with a label and a description.\n              </text></view><view role=\"region\" id=\"{{inputId}}\" aria-labelledby=\"{{`${radioId}-1`}}\" class=\"grid transition-all ease-in-out data-[state=collapsed]:grid-rows-[0fr] data-[state=collapsed]:opacity-0 data-[state=expanded]:grid-rows-[1fr] data-[state=expanded]:opacity-100\" data-state=\"{{selectedValue === 'with-expansion' ? 'expanded' : 'collapsed'}}\"><view class=\"pointer-events-none -m-2 overflow-hidden p-2\"><view class=\"pointer-events-auto mt-3\"><input ref=\"{{inputRef}}\" type=\"text\" id=\"radio-05-additional-info\" placeholder=\"Enter details\" aria-label=\"Additional Information\" disabled=\"{{selectedValue !== 'with-expansion'}}\" /></view></view></view></view></view></view><view class=\"flex items-start gap-2\"><radiogroupitem value=\"without-expansion\" id=\"{{`${radioId}-2`}}\" aria-describedby=\"{{`${radioId}-2-description`}}\" /><view class=\"grid grow gap-2\"><label htmlfor=\"{{`${radioId}-2`}}\">Radio without expansion</label><text id=\"{{`${radioId}-2-description`}}\" class=\"text-muted-foreground text-xs\">You can use this checkbox with a label and a description.\n          </text></view></view></radiogroup>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "radio",
          "label",
          "collapsible",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "radio-05",
          "group": "radio",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "radio-05",
              "path": "registry/default/components/radio/radio-05.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "radio-05",
              "path": "registry/default/components/radio/radio-05.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "radio-05",
              "path": "registry/default/components/radio/radio-05.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "radio-05",
              "path": "registry/default/components/radio/radio-05.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "radio",
        "title": "Radio · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "radio"
      ]
    },
    {
      "name": "radio-06",
      "type": "registry:component",
      "dependencies": [
        "@remixicon/react",
        "@timui/react"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/radio-group.json"
      ],
      "files": [
        {
          "path": "registry/default/components/radio/radio-06.tsx",
          "type": "registry:component",
          "target": "components/ui/radio-06.tsx",
          "content": "import { useId } from 'react'\nimport { RiStarFill } from '@remixicon/react'\nimport { Label, RadioGroup, RadioGroupItem } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <RadioGroup defaultValue=\"all\">\n      <div className=\"flex items-center gap-2\">\n        <RadioGroupItem value=\"all\" id={`${id}-1`} />\n        <Label htmlFor={`${id}-1`}>\n          All reviews{' '}\n          <span className=\"text-muted-foreground text-xs leading-[inherit] font-normal\">\n            (12,921)\n          </span>\n        </Label>\n      </div>\n      <div className=\"flex items-center gap-2\">\n        <RadioGroupItem value=\"5-stars\" id={`${id}-2`} />\n        <Label htmlFor={`${id}-2`} className=\"inline-flex items-center gap-1\">\n          <span className=\"inline-flex items-center text-amber-500\" aria-hidden=\"true\">\n            <RiStarFill size={16} />\n            <RiStarFill size={16} />\n            <RiStarFill size={16} />\n            <RiStarFill size={16} />\n            <RiStarFill size={16} />\n          </span>\n          <span className=\"sr-only\">5 stars</span>{' '}\n          <span className=\"text-muted-foreground text-xs leading-[inherit] font-normal\">\n            (5,168)\n          </span>\n        </Label>\n      </div>\n      <div className=\"flex items-center gap-2\">\n        <RadioGroupItem value=\"4-stars\" id={`${id}-3`} />\n        <Label htmlFor={`${id}-3`} className=\"inline-flex items-center gap-1\">\n          <span className=\"inline-flex items-center text-amber-500\" aria-hidden=\"true\">\n            <RiStarFill size={16} />\n            <RiStarFill size={16} />\n            <RiStarFill size={16} />\n            <RiStarFill size={16} />\n            <RiStarFill size={16} className=\"opacity-30\" />\n          </span>\n          <span className=\"sr-only\">4 stars</span>{' '}\n          <span className=\"text-muted-foreground text-xs leading-[inherit] font-normal\">\n            (4,726)\n          </span>\n        </Label>\n      </div>\n      <div className=\"flex items-center gap-2\">\n        <RadioGroupItem value=\"3-stars\" id={`${id}-4`} />\n        <Label htmlFor={`${id}-4`} className=\"inline-flex items-center gap-1\">\n          <span className=\"inline-flex items-center text-amber-500\" aria-hidden=\"true\">\n            <RiStarFill size={16} />\n            <RiStarFill size={16} />\n            <RiStarFill size={16} />\n            <RiStarFill size={16} className=\"opacity-30\" />\n            <RiStarFill size={16} className=\"opacity-30\" />\n          </span>\n          <span className=\"sr-only\">3 stars</span>{' '}\n          <span className=\"text-muted-foreground text-xs leading-[inherit] font-normal\">\n            (3,234)\n          </span>\n        </Label>\n      </div>\n      <div className=\"flex items-center gap-2\">\n        <RadioGroupItem value=\"2-stars\" id={`${id}-5`} />\n        <Label htmlFor={`${id}-5`} className=\"inline-flex items-center gap-1\">\n          <span className=\"inline-flex items-center text-amber-500\" aria-hidden=\"true\">\n            <RiStarFill size={16} />\n            <RiStarFill size={16} />\n            <RiStarFill size={16} className=\"opacity-30\" />\n            <RiStarFill size={16} className=\"opacity-30\" />\n            <RiStarFill size={16} className=\"opacity-30\" />\n          </span>\n          <span className=\"sr-only\">2 stars</span>{' '}\n          <span className=\"text-muted-foreground text-xs leading-[inherit] font-normal\">\n            (1,842)\n          </span>\n        </Label>\n      </div>\n      <div className=\"flex items-center gap-2\">\n        <RadioGroupItem value=\"1-star\" id={`${id}-6`} />\n        <Label htmlFor={`${id}-6`} className=\"inline-flex items-center gap-1\">\n          <span className=\"inline-flex items-center text-amber-500\" aria-hidden=\"true\">\n            <RiStarFill size={16} />\n            <RiStarFill size={16} className=\"opacity-30\" />\n            <RiStarFill size={16} className=\"opacity-30\" />\n            <RiStarFill size={16} className=\"opacity-30\" />\n            <RiStarFill size={16} className=\"opacity-30\" />\n          </span>\n          <span className=\"sr-only\">1 star</span>{' '}\n          <span className=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(452)</span>\n        </Label>\n      </div>\n    </RadioGroup>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/radio/radio-06.vue",
          "target": "components/ui/radio-06.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { StarIcon } from 'lucide-vue-next'\nimport { Label } from '@timui/vue'\nimport { RadioGroup } from '@timui/vue'\nimport { RadioGroupItem } from '@timui/vue'\n\nconst id = 'radio-06'\n</script>\n\n<template>\n  <RadioGroup default-value=\"all\">\n    <div class=\"flex items-center gap-2\">\n      <RadioGroupItem value=\"all\" :id=\"`${id}-1`\" />\n      <Label :htmlFor=\"`${id}-1`\">\n        All reviews <span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(12,921)</span>\n      </Label>\n    </div>\n    <div class=\"flex items-center gap-2\">\n      <RadioGroupItem value=\"5-stars\" :id=\"`${id}-2`\" />\n      <Label :htmlFor=\"`${id}-2`\" class=\"inline-flex items-center gap-1\">\n        <span class=\"inline-flex items-center text-amber-500\" aria-hidden=\"true\">\n          <StarIcon class=\"fill-current\" :size=\"16\" />\n          <StarIcon class=\"fill-current\" :size=\"16\" />\n          <StarIcon class=\"fill-current\" :size=\"16\" />\n          <StarIcon class=\"fill-current\" :size=\"16\" />\n          <StarIcon class=\"fill-current\" :size=\"16\" />\n        </span>\n        <span class=\"sr-only\">5 stars</span>\n        <span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(5,168)</span>\n      </Label>\n    </div>\n    <div class=\"flex items-center gap-2\">\n      <RadioGroupItem value=\"4-stars\" :id=\"`${id}-3`\" />\n      <Label :htmlFor=\"`${id}-3`\" class=\"inline-flex items-center gap-1\">\n        <span class=\"inline-flex items-center text-amber-500\" aria-hidden=\"true\">\n          <StarIcon class=\"fill-current\" :size=\"16\" />\n          <StarIcon class=\"fill-current\" :size=\"16\" />\n          <StarIcon class=\"fill-current\" :size=\"16\" />\n          <StarIcon class=\"fill-current\" :size=\"16\" />\n          <StarIcon class=\"fill-current opacity-30\" :size=\"16\" />\n        </span>\n        <span class=\"sr-only\">4 stars</span>\n        <span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(4,726)</span>\n      </Label>\n    </div>\n    <div class=\"flex items-center gap-2\">\n      <RadioGroupItem value=\"3-stars\" :id=\"`${id}-4`\" />\n      <Label :htmlFor=\"`${id}-4`\" class=\"inline-flex items-center gap-1\">\n        <span class=\"inline-flex items-center text-amber-500\" aria-hidden=\"true\">\n          <StarIcon class=\"fill-current\" :size=\"16\" />\n          <StarIcon class=\"fill-current\" :size=\"16\" />\n          <StarIcon class=\"fill-current\" :size=\"16\" />\n          <StarIcon class=\"fill-current opacity-30\" :size=\"16\" />\n          <StarIcon class=\"fill-current opacity-30\" :size=\"16\" />\n        </span>\n        <span class=\"sr-only\">3 stars</span>\n        <span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(3,234)</span>\n      </Label>\n    </div>\n    <div class=\"flex items-center gap-2\">\n      <RadioGroupItem value=\"2-stars\" :id=\"`${id}-5`\" />\n      <Label :htmlFor=\"`${id}-5`\" class=\"inline-flex items-center gap-1\">\n        <span class=\"inline-flex items-center text-amber-500\" aria-hidden=\"true\">\n          <StarIcon class=\"fill-current\" :size=\"16\" />\n          <StarIcon class=\"fill-current\" :size=\"16\" />\n          <StarIcon class=\"fill-current opacity-30\" :size=\"16\" />\n          <StarIcon class=\"fill-current opacity-30\" :size=\"16\" />\n          <StarIcon class=\"fill-current opacity-30\" :size=\"16\" />\n        </span>\n        <span class=\"sr-only\">2 stars</span>\n        <span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(1,842)</span>\n      </Label>\n    </div>\n    <div class=\"flex items-center gap-2\">\n      <RadioGroupItem value=\"1-star\" :id=\"`${id}-6`\" />\n      <Label :htmlFor=\"`${id}-6`\" class=\"inline-flex items-center gap-1\">\n        <span class=\"inline-flex items-center text-amber-500\" aria-hidden=\"true\">\n          <StarIcon class=\"fill-current\" :size=\"16\" />\n          <StarIcon class=\"fill-current opacity-30\" :size=\"16\" />\n          <StarIcon class=\"fill-current opacity-30\" :size=\"16\" />\n          <StarIcon class=\"fill-current opacity-30\" :size=\"16\" />\n          <StarIcon class=\"fill-current opacity-30\" :size=\"16\" />\n        </span>\n        <span class=\"sr-only\">1 star</span>\n        <span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(452)</span>\n      </Label>\n    </div>\n  </RadioGroup>\n</template>\n"
        },
        {
          "path": "registry/default/components/radio/radio-06.html",
          "target": "components/ui/radio-06.html",
          "type": "registry:component",
          "content": "<template>\n  <RadioGroup default-value=\"all\"><div class=\"flex items-center gap-2\"><RadioGroupItem value=\"all\" id=\"${`${id}-1`}\" /><Label htmlfor=\"${`${id}-1`}\">All reviews${' '}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(12,921)\n          </span></Label></div><div class=\"flex items-center gap-2\"><RadioGroupItem value=\"5-stars\" id=\"${`${id}-2`}\" /><Label htmlfor=\"${`${id}-2`}\" class=\"inline-flex items-center gap-1\"><span class=\"inline-flex items-center text-amber-500\" aria-hidden=\"true\"><RiStarFill size=\"${16}\" /><RiStarFill size=\"${16}\" /><RiStarFill size=\"${16}\" /><RiStarFill size=\"${16}\" /><RiStarFill size=\"${16}\" /></span><span class=\"sr-only\">5 stars</span>${' '}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(5,168)\n          </span></Label></div><div class=\"flex items-center gap-2\"><RadioGroupItem value=\"4-stars\" id=\"${`${id}-3`}\" /><Label htmlfor=\"${`${id}-3`}\" class=\"inline-flex items-center gap-1\"><span class=\"inline-flex items-center text-amber-500\" aria-hidden=\"true\"><RiStarFill size=\"${16}\" /><RiStarFill size=\"${16}\" /><RiStarFill size=\"${16}\" /><RiStarFill size=\"${16}\" /><RiStarFill size=\"${16}\" class=\"opacity-30\" /></span><span class=\"sr-only\">4 stars</span>${' '}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(4,726)\n          </span></Label></div><div class=\"flex items-center gap-2\"><RadioGroupItem value=\"3-stars\" id=\"${`${id}-4`}\" /><Label htmlfor=\"${`${id}-4`}\" class=\"inline-flex items-center gap-1\"><span class=\"inline-flex items-center text-amber-500\" aria-hidden=\"true\"><RiStarFill size=\"${16}\" /><RiStarFill size=\"${16}\" /><RiStarFill size=\"${16}\" /><RiStarFill size=\"${16}\" class=\"opacity-30\" /><RiStarFill size=\"${16}\" class=\"opacity-30\" /></span><span class=\"sr-only\">3 stars</span>${' '}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(3,234)\n          </span></Label></div><div class=\"flex items-center gap-2\"><RadioGroupItem value=\"2-stars\" id=\"${`${id}-5`}\" /><Label htmlfor=\"${`${id}-5`}\" class=\"inline-flex items-center gap-1\"><span class=\"inline-flex items-center text-amber-500\" aria-hidden=\"true\"><RiStarFill size=\"${16}\" /><RiStarFill size=\"${16}\" /><RiStarFill size=\"${16}\" class=\"opacity-30\" /><RiStarFill size=\"${16}\" class=\"opacity-30\" /><RiStarFill size=\"${16}\" class=\"opacity-30\" /></span><span class=\"sr-only\">2 stars</span>${' '}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(1,842)\n          </span></Label></div><div class=\"flex items-center gap-2\"><RadioGroupItem value=\"1-star\" id=\"${`${id}-6`}\" /><Label htmlfor=\"${`${id}-6`}\" class=\"inline-flex items-center gap-1\"><span class=\"inline-flex items-center text-amber-500\" aria-hidden=\"true\"><RiStarFill size=\"${16}\" /><RiStarFill size=\"${16}\" class=\"opacity-30\" /><RiStarFill size=\"${16}\" class=\"opacity-30\" /><RiStarFill size=\"${16}\" class=\"opacity-30\" /><RiStarFill size=\"${16}\" class=\"opacity-30\" /></span><span class=\"sr-only\">1 star</span>${' '}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(452)</span></Label></div></RadioGroup>\n</template>"
        },
        {
          "path": "registry/default/components/radio/radio-06.wxml",
          "target": "components/ui/radio-06/radio-06.wxml",
          "type": "registry:component",
          "content": "<view>\n  <radiogroup default-value=\"all\"><view class=\"flex items-center gap-2\"><radiogroupitem value=\"all\" id=\"{{`${id}-1`}}\" /><label htmlfor=\"{{`${id}-1`}}\">All reviews{{ ' ' }}<text class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(12,921)\n          </text></label></view><view class=\"flex items-center gap-2\"><radiogroupitem value=\"5-stars\" id=\"{{`${id}-2`}}\" /><label htmlfor=\"{{`${id}-2`}}\" class=\"inline-flex items-center gap-1\"><text class=\"inline-flex items-center text-amber-500\" aria-hidden=\"true\"><ristarfill size=\"{{16}}\" /><ristarfill size=\"{{16}}\" /><ristarfill size=\"{{16}}\" /><ristarfill size=\"{{16}}\" /><ristarfill size=\"{{16}}\" /></text><text class=\"sr-only\">5 stars</text>{{ ' ' }}<text class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(5,168)\n          </text></label></view><view class=\"flex items-center gap-2\"><radiogroupitem value=\"4-stars\" id=\"{{`${id}-3`}}\" /><label htmlfor=\"{{`${id}-3`}}\" class=\"inline-flex items-center gap-1\"><text class=\"inline-flex items-center text-amber-500\" aria-hidden=\"true\"><ristarfill size=\"{{16}}\" /><ristarfill size=\"{{16}}\" /><ristarfill size=\"{{16}}\" /><ristarfill size=\"{{16}}\" /><ristarfill size=\"{{16}}\" class=\"opacity-30\" /></text><text class=\"sr-only\">4 stars</text>{{ ' ' }}<text class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(4,726)\n          </text></label></view><view class=\"flex items-center gap-2\"><radiogroupitem value=\"3-stars\" id=\"{{`${id}-4`}}\" /><label htmlfor=\"{{`${id}-4`}}\" class=\"inline-flex items-center gap-1\"><text class=\"inline-flex items-center text-amber-500\" aria-hidden=\"true\"><ristarfill size=\"{{16}}\" /><ristarfill size=\"{{16}}\" /><ristarfill size=\"{{16}}\" /><ristarfill size=\"{{16}}\" class=\"opacity-30\" /><ristarfill size=\"{{16}}\" class=\"opacity-30\" /></text><text class=\"sr-only\">3 stars</text>{{ ' ' }}<text class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(3,234)\n          </text></label></view><view class=\"flex items-center gap-2\"><radiogroupitem value=\"2-stars\" id=\"{{`${id}-5`}}\" /><label htmlfor=\"{{`${id}-5`}}\" class=\"inline-flex items-center gap-1\"><text class=\"inline-flex items-center text-amber-500\" aria-hidden=\"true\"><ristarfill size=\"{{16}}\" /><ristarfill size=\"{{16}}\" /><ristarfill size=\"{{16}}\" class=\"opacity-30\" /><ristarfill size=\"{{16}}\" class=\"opacity-30\" /><ristarfill size=\"{{16}}\" class=\"opacity-30\" /></text><text class=\"sr-only\">2 stars</text>{{ ' ' }}<text class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(1,842)\n          </text></label></view><view class=\"flex items-center gap-2\"><radiogroupitem value=\"1-star\" id=\"{{`${id}-6`}}\" /><label htmlfor=\"{{`${id}-6`}}\" class=\"inline-flex items-center gap-1\"><text class=\"inline-flex items-center text-amber-500\" aria-hidden=\"true\"><ristarfill size=\"{{16}}\" /><ristarfill size=\"{{16}}\" class=\"opacity-30\" /><ristarfill size=\"{{16}}\" class=\"opacity-30\" /><ristarfill size=\"{{16}}\" class=\"opacity-30\" /><ristarfill size=\"{{16}}\" class=\"opacity-30\" /></text><text class=\"sr-only\">1 star</text>{{ ' ' }}<text class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(452)</text></label></view></radiogroup>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "radio",
          "label",
          "rating",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "radio-06",
          "group": "radio",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "radio-06",
              "path": "registry/default/components/radio/radio-06.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "radio-06",
              "path": "registry/default/components/radio/radio-06.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "radio-06",
              "path": "registry/default/components/radio/radio-06.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "radio-06",
              "path": "registry/default/components/radio/radio-06.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@remixicon/react",
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "radio",
        "title": "Radio · With label"
      },
      "categories": [
        "radio"
      ]
    },
    {
      "name": "radio-07",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/radio-group.json"
      ],
      "files": [
        {
          "path": "registry/default/components/radio/radio-07.tsx",
          "type": "registry:component",
          "target": "components/ui/radio-07.tsx",
          "content": "import { RadioGroup, RadioGroupItem } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <fieldset className=\"space-y-4\">\n      <legend className=\"text-foreground text-sm leading-none font-medium\">Choose a color</legend>\n      <RadioGroup className=\"flex gap-1.5\" defaultValue=\"blue\">\n        <RadioGroupItem\n          value=\"blue\"\n          aria-label=\"Blue\"\n          className=\"size-6 border-blue-500 bg-blue-500 shadow-none data-[state=checked]:border-blue-500 data-[state=checked]:bg-blue-500\"\n        />\n        <RadioGroupItem\n          value=\"indigo\"\n          aria-label=\"Indigo\"\n          className=\"size-6 border-indigo-500 bg-indigo-500 shadow-none data-[state=checked]:border-indigo-500 data-[state=checked]:bg-indigo-500\"\n        />\n        <RadioGroupItem\n          value=\"pink\"\n          aria-label=\"Pink\"\n          className=\"size-6 border-pink-500 bg-pink-500 shadow-none data-[state=checked]:border-pink-500 data-[state=checked]:bg-pink-500\"\n        />\n        <RadioGroupItem\n          value=\"red\"\n          aria-label=\"red\"\n          className=\"size-6 border-red-500 bg-red-500 shadow-none data-[state=checked]:border-red-500 data-[state=checked]:bg-red-500\"\n        />\n        <RadioGroupItem\n          value=\"orange\"\n          aria-label=\"orange\"\n          className=\"size-6 border-orange-500 bg-orange-500 shadow-none data-[state=checked]:border-orange-500 data-[state=checked]:bg-orange-500\"\n        />\n        <RadioGroupItem\n          value=\"amber\"\n          aria-label=\"amber\"\n          className=\"size-6 border-amber-500 bg-amber-500 shadow-none data-[state=checked]:border-amber-500 data-[state=checked]:bg-amber-500\"\n        />\n        <RadioGroupItem\n          value=\"emerald\"\n          aria-label=\"emerald\"\n          className=\"size-6 border-emerald-500 bg-emerald-500 shadow-none data-[state=checked]:border-emerald-500 data-[state=checked]:bg-emerald-500\"\n        />\n      </RadioGroup>\n    </fieldset>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/radio/radio-07.vue",
          "target": "components/ui/radio-07.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { RadioGroup } from '@timui/vue';\nimport { RadioGroupItem } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <fieldset class=\"space-y-4\"><legend class=\"text-foreground text-sm leading-none font-medium\">Choose a color</legend><RadioGroup class=\"flex gap-1.5\" default-value=\"blue\"><RadioGroupItem value=\"blue\" aria-label=\"Blue\" class=\"size-6 border-blue-500 bg-blue-500 shadow-none data-[state=checked]:border-blue-500 data-[state=checked]:bg-blue-500\" /><RadioGroupItem value=\"indigo\" aria-label=\"Indigo\" class=\"size-6 border-indigo-500 bg-indigo-500 shadow-none data-[state=checked]:border-indigo-500 data-[state=checked]:bg-indigo-500\" /><RadioGroupItem value=\"pink\" aria-label=\"Pink\" class=\"size-6 border-pink-500 bg-pink-500 shadow-none data-[state=checked]:border-pink-500 data-[state=checked]:bg-pink-500\" /><RadioGroupItem value=\"red\" aria-label=\"red\" class=\"size-6 border-red-500 bg-red-500 shadow-none data-[state=checked]:border-red-500 data-[state=checked]:bg-red-500\" /><RadioGroupItem value=\"orange\" aria-label=\"orange\" class=\"size-6 border-orange-500 bg-orange-500 shadow-none data-[state=checked]:border-orange-500 data-[state=checked]:bg-orange-500\" /><RadioGroupItem value=\"amber\" aria-label=\"amber\" class=\"size-6 border-amber-500 bg-amber-500 shadow-none data-[state=checked]:border-amber-500 data-[state=checked]:bg-amber-500\" /><RadioGroupItem value=\"emerald\" aria-label=\"emerald\" class=\"size-6 border-emerald-500 bg-emerald-500 shadow-none data-[state=checked]:border-emerald-500 data-[state=checked]:bg-emerald-500\" /></RadioGroup></fieldset>\n</template>\n"
        },
        {
          "path": "registry/default/components/radio/radio-07.html",
          "target": "components/ui/radio-07.html",
          "type": "registry:component",
          "content": "<template>\n  <fieldset class=\"space-y-4\"><legend class=\"text-foreground text-sm leading-none font-medium\">Choose a color</legend><RadioGroup class=\"flex gap-1.5\" default-value=\"blue\"><RadioGroupItem value=\"blue\" aria-label=\"Blue\" class=\"size-6 border-blue-500 bg-blue-500 shadow-none data-[state=checked]:border-blue-500 data-[state=checked]:bg-blue-500\" /><RadioGroupItem value=\"indigo\" aria-label=\"Indigo\" class=\"size-6 border-indigo-500 bg-indigo-500 shadow-none data-[state=checked]:border-indigo-500 data-[state=checked]:bg-indigo-500\" /><RadioGroupItem value=\"pink\" aria-label=\"Pink\" class=\"size-6 border-pink-500 bg-pink-500 shadow-none data-[state=checked]:border-pink-500 data-[state=checked]:bg-pink-500\" /><RadioGroupItem value=\"red\" aria-label=\"red\" class=\"size-6 border-red-500 bg-red-500 shadow-none data-[state=checked]:border-red-500 data-[state=checked]:bg-red-500\" /><RadioGroupItem value=\"orange\" aria-label=\"orange\" class=\"size-6 border-orange-500 bg-orange-500 shadow-none data-[state=checked]:border-orange-500 data-[state=checked]:bg-orange-500\" /><RadioGroupItem value=\"amber\" aria-label=\"amber\" class=\"size-6 border-amber-500 bg-amber-500 shadow-none data-[state=checked]:border-amber-500 data-[state=checked]:bg-amber-500\" /><RadioGroupItem value=\"emerald\" aria-label=\"emerald\" class=\"size-6 border-emerald-500 bg-emerald-500 shadow-none data-[state=checked]:border-emerald-500 data-[state=checked]:bg-emerald-500\" /></RadioGroup></fieldset>\n</template>"
        },
        {
          "path": "registry/default/components/radio/radio-07.wxml",
          "target": "components/ui/radio-07/radio-07.wxml",
          "type": "registry:component",
          "content": "<view>\n  <fieldset class=\"space-y-4\"><legend class=\"text-foreground text-sm leading-none font-medium\">Choose a color</legend><radiogroup class=\"flex gap-1.5\" default-value=\"blue\"><radiogroupitem value=\"blue\" aria-label=\"Blue\" class=\"size-6 border-blue-500 bg-blue-500 shadow-none data-[state=checked]:border-blue-500 data-[state=checked]:bg-blue-500\" /><radiogroupitem value=\"indigo\" aria-label=\"Indigo\" class=\"size-6 border-indigo-500 bg-indigo-500 shadow-none data-[state=checked]:border-indigo-500 data-[state=checked]:bg-indigo-500\" /><radiogroupitem value=\"pink\" aria-label=\"Pink\" class=\"size-6 border-pink-500 bg-pink-500 shadow-none data-[state=checked]:border-pink-500 data-[state=checked]:bg-pink-500\" /><radiogroupitem value=\"red\" aria-label=\"red\" class=\"size-6 border-red-500 bg-red-500 shadow-none data-[state=checked]:border-red-500 data-[state=checked]:bg-red-500\" /><radiogroupitem value=\"orange\" aria-label=\"orange\" class=\"size-6 border-orange-500 bg-orange-500 shadow-none data-[state=checked]:border-orange-500 data-[state=checked]:bg-orange-500\" /><radiogroupitem value=\"amber\" aria-label=\"amber\" class=\"size-6 border-amber-500 bg-amber-500 shadow-none data-[state=checked]:border-amber-500 data-[state=checked]:bg-amber-500\" /><radiogroupitem value=\"emerald\" aria-label=\"emerald\" class=\"size-6 border-emerald-500 bg-emerald-500 shadow-none data-[state=checked]:border-emerald-500 data-[state=checked]:bg-emerald-500\" /></radiogroup></fieldset>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "radio",
          "label",
          "color",
          "picker",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "radio-07",
          "group": "radio",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "radio-07",
              "path": "registry/default/components/radio/radio-07.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "radio-07",
              "path": "registry/default/components/radio/radio-07.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "radio-07",
              "path": "registry/default/components/radio/radio-07.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "radio-07",
              "path": "registry/default/components/radio/radio-07.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "radio",
        "title": "Radio · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "radio"
      ]
    },
    {
      "name": "radio-08",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/radio-group.json"
      ],
      "files": [
        {
          "path": "registry/default/components/radio/radio-08.tsx",
          "type": "registry:component",
          "target": "components/ui/radio-08.tsx",
          "content": "import { useId } from 'react'\nimport { Label, RadioGroup, RadioGroupItem } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <RadioGroup className=\"gap-2\" defaultValue=\"1\">\n      {/* Radio card #1 */}\n      <div className=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\">\n        <RadioGroupItem\n          value=\"1\"\n          id={`${id}-1`}\n          aria-describedby={`${id}-1-description`}\n          className=\"order-1 after:absolute after:inset-0\"\n        />\n        <div className=\"grid grow gap-2\">\n          <Label htmlFor={`${id}-1`}>\n            Label{' '}\n            <span className=\"text-muted-foreground text-xs leading-[inherit] font-normal\">\n              (Sublabel)\n            </span>\n          </Label>\n          <p id={`${id}-1-description`} className=\"text-muted-foreground text-xs\">\n            You can use this card with a label and a description.\n          </p>\n        </div>\n      </div>\n      {/* Radio card #2 */}\n      <div className=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\">\n        <RadioGroupItem\n          value=\"2\"\n          id={`${id}-2`}\n          aria-describedby={`${id}-2-description`}\n          className=\"order-1 after:absolute after:inset-0\"\n        />\n        <div className=\"grid grow gap-2\">\n          <Label htmlFor={`${id}-2`}>\n            Label{' '}\n            <span className=\"text-muted-foreground text-xs leading-[inherit] font-normal\">\n              (Sublabel)\n            </span>\n          </Label>\n          <p id={`${id}-2-description`} className=\"text-muted-foreground text-xs\">\n            You can use this card with a label and a description.\n          </p>\n        </div>\n      </div>\n    </RadioGroup>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/radio/radio-08.vue",
          "target": "components/ui/radio-08.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { RadioGroup } from '@timui/vue';\nimport { RadioGroupItem } from '@timui/vue';\n\n\n\n\n\nconst id = 'radio-08';\n\n</script>\n\n<template>\n  <RadioGroup class=\"gap-2\" default-value=\"1\"><div class=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\"><RadioGroupItem value=\"1\" :id=\"`${id}-1`\" :aria-describedby=\"`${id}-1-description`\" class=\"order-1 after:absolute after:inset-0\" /><div class=\"grid grow gap-2\"><Label :htmlFor=\"`${id}-1`\">Label{{ ' ' }}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n            </span></Label><p :id=\"`${id}-1-description`\" class=\"text-muted-foreground text-xs\">You can use this card with a label and a description.\n          </p></div></div><div class=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\"><RadioGroupItem value=\"2\" :id=\"`${id}-2`\" :aria-describedby=\"`${id}-2-description`\" class=\"order-1 after:absolute after:inset-0\" /><div class=\"grid grow gap-2\"><Label :htmlFor=\"`${id}-2`\">Label{{ ' ' }}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n            </span></Label><p :id=\"`${id}-2-description`\" class=\"text-muted-foreground text-xs\">You can use this card with a label and a description.\n          </p></div></div></RadioGroup>\n</template>\n"
        },
        {
          "path": "registry/default/components/radio/radio-08.html",
          "target": "components/ui/radio-08.html",
          "type": "registry:component",
          "content": "<template>\n  <RadioGroup class=\"gap-2\" default-value=\"1\"><div class=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\"><RadioGroupItem value=\"1\" id=\"${`${id}-1`}\" aria-describedby=\"${`${id}-1-description`}\" class=\"order-1 after:absolute after:inset-0\" /><div class=\"grid grow gap-2\"><Label htmlfor=\"${`${id}-1`}\">Label${' '}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n            </span></Label><p id=\"${`${id}-1-description`}\" class=\"text-muted-foreground text-xs\">You can use this card with a label and a description.\n          </p></div></div><div class=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\"><RadioGroupItem value=\"2\" id=\"${`${id}-2`}\" aria-describedby=\"${`${id}-2-description`}\" class=\"order-1 after:absolute after:inset-0\" /><div class=\"grid grow gap-2\"><Label htmlfor=\"${`${id}-2`}\">Label${' '}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n            </span></Label><p id=\"${`${id}-2-description`}\" class=\"text-muted-foreground text-xs\">You can use this card with a label and a description.\n          </p></div></div></RadioGroup>\n</template>"
        },
        {
          "path": "registry/default/components/radio/radio-08.wxml",
          "target": "components/ui/radio-08/radio-08.wxml",
          "type": "registry:component",
          "content": "<view>\n  <radiogroup class=\"gap-2\" default-value=\"1\"><view class=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\"><radiogroupitem value=\"1\" id=\"{{`${id}-1`}}\" aria-describedby=\"{{`${id}-1-description`}}\" class=\"order-1 after:absolute after:inset-0\" /><view class=\"grid grow gap-2\"><label htmlfor=\"{{`${id}-1`}}\">Label{{ ' ' }}<text class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n            </text></label><text id=\"{{`${id}-1-description`}}\" class=\"text-muted-foreground text-xs\">You can use this card with a label and a description.\n          </text></view></view><view class=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\"><radiogroupitem value=\"2\" id=\"{{`${id}-2`}}\" aria-describedby=\"{{`${id}-2-description`}}\" class=\"order-1 after:absolute after:inset-0\" /><view class=\"grid grow gap-2\"><label htmlfor=\"{{`${id}-2`}}\">Label{{ ' ' }}<text class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n            </text></label><text id=\"{{`${id}-2-description`}}\" class=\"text-muted-foreground text-xs\">You can use this card with a label and a description.\n          </text></view></view></radiogroup>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "radio",
          "label",
          "card",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "radio-08",
          "group": "radio",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "radio-08",
              "path": "registry/default/components/radio/radio-08.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "radio-08",
              "path": "registry/default/components/radio/radio-08.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "radio-08",
              "path": "registry/default/components/radio/radio-08.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "radio-08",
              "path": "registry/default/components/radio/radio-08.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "radio",
        "title": "Radio · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "radio"
      ]
    },
    {
      "name": "radio-09",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/radio-group.json"
      ],
      "files": [
        {
          "path": "registry/default/components/radio/radio-09.tsx",
          "type": "registry:component",
          "target": "components/ui/radio-09.tsx",
          "content": "import { useId } from 'react'\nimport { Label, RadioGroup, RadioGroupItem } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <RadioGroup className=\"gap-2\" defaultValue=\"1\">\n      {/* Radio card #1 */}\n      <div className=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\">\n        <RadioGroupItem\n          value=\"1\"\n          id={`${id}-1`}\n          aria-describedby={`${id}-1-description`}\n          className=\"order-1 after:absolute after:inset-0\"\n        />\n        <div className=\"flex grow items-start gap-3\">\n          <svg\n            className=\"shrink-0\"\n            width={32}\n            height={24}\n            viewBox=\"0 0 32 24\"\n            xmlns=\"http://www.w3.org/2000/svg\"\n            aria-hidden=\"true\"\n          >\n            <rect width=\"32\" height=\"24\" rx=\"4\" fill=\"#252525\" />\n            <path d=\"M19.0537 6.49742H12.9282V17.5026H19.0537V6.49742Z\" fill=\"#FF5A00\" />\n            <path\n              d=\"M13.3359 12C13.3359 9.76408 14.3871 7.77961 16 6.49741C14.8129 5.56408 13.3155 5 11.6822 5C7.81295 5 4.68221 8.13074 4.68221 12C4.68221 15.8693 7.81295 19 11.6822 19C13.3155 19 14.8129 18.4359 16 17.5026C14.3848 16.2385 13.3359 14.2359 13.3359 12Z\"\n              fill=\"#EB001B\"\n            />\n            <path\n              d=\"M27.3178 12C27.3178 15.8693 24.1871 19 20.3178 19C18.6845 19 17.1871 18.4359 16 17.5026C17.6333 16.2181 18.6641 14.2359 18.6641 12C18.6641 9.76408 17.6129 7.77961 16 6.49741C17.1848 5.56408 18.6822 5 20.3155 5C24.1871 5 27.3178 8.15113 27.3178 12Z\"\n              fill=\"#F79E1B\"\n            />\n          </svg>\n          <div className=\"grid grow gap-2\">\n            <Label htmlFor={`${id}-1`}>\n              Label{' '}\n              <span className=\"text-muted-foreground text-xs leading-[inherit] font-normal\">\n                (Sublabel)\n              </span>\n            </Label>\n            <p id={`${id}-1-description`} className=\"text-muted-foreground text-xs\">\n              You can use this card with a label and a description.\n            </p>\n          </div>\n        </div>\n      </div>\n      {/* Radio card #2 */}\n      <div className=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\">\n        <RadioGroupItem\n          value=\"2\"\n          id={`${id}-2`}\n          aria-describedby={`${id}-2-description`}\n          className=\"order-1 after:absolute after:inset-0\"\n        />\n        <div className=\"flex grow items-start gap-3\">\n          <svg\n            className=\"shrink-0\"\n            width={32}\n            height={24}\n            viewBox=\"0 0 32 24\"\n            xmlns=\"http://www.w3.org/2000/svg\"\n            aria-hidden=\"true\"\n          >\n            <g clipPath=\"url(#vc-a)\">\n              <path\n                fill=\"#252525\"\n                d=\"M28 0H4a4 4 0 0 0-4 4v16a4 4 0 0 0 4 4h24a4 4 0 0 0 4-4V4a4 4 0 0 0-4-4Z\"\n              />\n              <path fill=\"#fff\" d=\"m15.884 8.262-1.604 7.496h-1.94l1.604-7.496h1.94Z\" />\n              <path\n                fill=\"#fff\"\n                fillRule=\"evenodd\"\n                d=\"M26.207 15.758H28l-1.567-7.496H24.78a.882.882 0 0 0-.826.55l-2.91 6.946h2.037l.404-1.12h2.488l.235 1.12Zm-2.165-2.656 1.021-2.815.587 2.815h-1.608Z\"\n                clipRule=\"evenodd\"\n              />\n              <path\n                fill=\"#fff\"\n                d=\"M21.144 13.31c.005-1.183-.975-1.698-1.76-2.11-.526-.276-.964-.506-.957-.861.007-.27.263-.555.823-.628.277-.036 1.044-.065 1.913.335l.34-1.59a5.23 5.23 0 0 0-1.815-.331c-1.917 0-3.265 1.018-3.276 2.477-.013 1.08.963 1.681 1.697 2.04.756.368 1.01.604 1.006.932-.005.503-.604.726-1.16.734-.945.015-1.506-.247-1.95-.454l-.042-.02-.352 1.643c.454.208 1.29.39 2.156.398 2.038 0 3.371-1.006 3.377-2.565ZM13.112 8.262 9.97 15.758H7.92L6.374 9.775c-.094-.368-.175-.503-.46-.658-.467-.253-1.237-.49-1.914-.638l.046-.217h3.3c.42 0 .798.28.894.763l.817 4.338 2.018-5.101h2.037Z\"\n              />\n            </g>\n            <defs>\n              <clipPath id=\"vc-a\">\n                <path fill=\"#fff\" d=\"M0 0h32v24H0z\" />\n              </clipPath>\n            </defs>\n          </svg>\n          <div className=\"grid grow gap-2\">\n            <Label htmlFor={`${id}-2`}>\n              Label{' '}\n              <span className=\"text-muted-foreground text-xs leading-[inherit] font-normal\">\n                (Sublabel)\n              </span>\n            </Label>\n            <p id={`${id}-2-description`} className=\"text-muted-foreground text-xs\">\n              You can use this card with a label and a description.\n            </p>\n          </div>\n        </div>\n      </div>\n    </RadioGroup>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/radio/radio-09.vue",
          "target": "components/ui/radio-09.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { RadioGroup } from '@timui/vue';\nimport { RadioGroupItem } from '@timui/vue';\n\n\n\n\n\nconst id = 'radio-09';\n\n</script>\n\n<template>\n  <RadioGroup class=\"gap-2\" default-value=\"1\"><div class=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\"><RadioGroupItem value=\"1\" :id=\"`${id}-1`\" :aria-describedby=\"`${id}-1-description`\" class=\"order-1 after:absolute after:inset-0\" /><div class=\"flex grow items-start gap-3\"><svg class=\"shrink-0\" :width=\"32\" :height=\"24\" viewBox=\"0 0 32 24\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\"><rect width=\"32\" height=\"24\" rx=\"4\" fill=\"#252525\" /><path d=\"M19.0537 6.49742H12.9282V17.5026H19.0537V6.49742Z\" fill=\"#FF5A00\" /><path d=\"M13.3359 12C13.3359 9.76408 14.3871 7.77961 16 6.49741C14.8129 5.56408 13.3155 5 11.6822 5C7.81295 5 4.68221 8.13074 4.68221 12C4.68221 15.8693 7.81295 19 11.6822 19C13.3155 19 14.8129 18.4359 16 17.5026C14.3848 16.2385 13.3359 14.2359 13.3359 12Z\" fill=\"#EB001B\" /><path d=\"M27.3178 12C27.3178 15.8693 24.1871 19 20.3178 19C18.6845 19 17.1871 18.4359 16 17.5026C17.6333 16.2181 18.6641 14.2359 18.6641 12C18.6641 9.76408 17.6129 7.77961 16 6.49741C17.1848 5.56408 18.6822 5 20.3155 5C24.1871 5 27.3178 8.15113 27.3178 12Z\" fill=\"#F79E1B\" /></svg><div class=\"grid grow gap-2\"><Label :htmlFor=\"`${id}-1`\">Label{{ ' ' }}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n              </span></Label><p :id=\"`${id}-1-description`\" class=\"text-muted-foreground text-xs\">You can use this card with a label and a description.\n            </p></div></div></div><div class=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\"><RadioGroupItem value=\"2\" :id=\"`${id}-2`\" :aria-describedby=\"`${id}-2-description`\" class=\"order-1 after:absolute after:inset-0\" /><div class=\"flex grow items-start gap-3\"><svg class=\"shrink-0\" :width=\"32\" :height=\"24\" viewBox=\"0 0 32 24\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\"><g clipPath=\"url(#vc-a)\"><path fill=\"#252525\" d=\"M28 0H4a4 4 0 0 0-4 4v16a4 4 0 0 0 4 4h24a4 4 0 0 0 4-4V4a4 4 0 0 0-4-4Z\" /><path fill=\"#fff\" d=\"m15.884 8.262-1.604 7.496h-1.94l1.604-7.496h1.94Z\" /><path fill=\"#fff\" fillRule=\"evenodd\" d=\"M26.207 15.758H28l-1.567-7.496H24.78a.882.882 0 0 0-.826.55l-2.91 6.946h2.037l.404-1.12h2.488l.235 1.12Zm-2.165-2.656 1.021-2.815.587 2.815h-1.608Z\" clipRule=\"evenodd\" /><path fill=\"#fff\" d=\"M21.144 13.31c.005-1.183-.975-1.698-1.76-2.11-.526-.276-.964-.506-.957-.861.007-.27.263-.555.823-.628.277-.036 1.044-.065 1.913.335l.34-1.59a5.23 5.23 0 0 0-1.815-.331c-1.917 0-3.265 1.018-3.276 2.477-.013 1.08.963 1.681 1.697 2.04.756.368 1.01.604 1.006.932-.005.503-.604.726-1.16.734-.945.015-1.506-.247-1.95-.454l-.042-.02-.352 1.643c.454.208 1.29.39 2.156.398 2.038 0 3.371-1.006 3.377-2.565ZM13.112 8.262 9.97 15.758H7.92L6.374 9.775c-.094-.368-.175-.503-.46-.658-.467-.253-1.237-.49-1.914-.638l.046-.217h3.3c.42 0 .798.28.894.763l.817 4.338 2.018-5.101h2.037Z\" /></g><defs><clipPath id=\"vc-a\"><path fill=\"#fff\" d=\"M0 0h32v24H0z\" /></clipPath></defs></svg><div class=\"grid grow gap-2\"><Label :htmlFor=\"`${id}-2`\">Label{{ ' ' }}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n              </span></Label><p :id=\"`${id}-2-description`\" class=\"text-muted-foreground text-xs\">You can use this card with a label and a description.\n            </p></div></div></div></RadioGroup>\n</template>\n"
        },
        {
          "path": "registry/default/components/radio/radio-09.html",
          "target": "components/ui/radio-09.html",
          "type": "registry:component",
          "content": "<template>\n  <RadioGroup class=\"gap-2\" default-value=\"1\"><div class=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\"><RadioGroupItem value=\"1\" id=\"${`${id}-1`}\" aria-describedby=\"${`${id}-1-description`}\" class=\"order-1 after:absolute after:inset-0\" /><div class=\"flex grow items-start gap-3\"><svg class=\"shrink-0\" width=\"${32}\" height=\"${24}\" viewbox=\"0 0 32 24\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\"><rect width=\"32\" height=\"24\" rx=\"4\" fill=\"#252525\" /><path d=\"M19.0537 6.49742H12.9282V17.5026H19.0537V6.49742Z\" fill=\"#FF5A00\" /><path d=\"M13.3359 12C13.3359 9.76408 14.3871 7.77961 16 6.49741C14.8129 5.56408 13.3155 5 11.6822 5C7.81295 5 4.68221 8.13074 4.68221 12C4.68221 15.8693 7.81295 19 11.6822 19C13.3155 19 14.8129 18.4359 16 17.5026C14.3848 16.2385 13.3359 14.2359 13.3359 12Z\" fill=\"#EB001B\" /><path d=\"M27.3178 12C27.3178 15.8693 24.1871 19 20.3178 19C18.6845 19 17.1871 18.4359 16 17.5026C17.6333 16.2181 18.6641 14.2359 18.6641 12C18.6641 9.76408 17.6129 7.77961 16 6.49741C17.1848 5.56408 18.6822 5 20.3155 5C24.1871 5 27.3178 8.15113 27.3178 12Z\" fill=\"#F79E1B\" /></svg><div class=\"grid grow gap-2\"><Label htmlfor=\"${`${id}-1`}\">Label${' '}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n              </span></Label><p id=\"${`${id}-1-description`}\" class=\"text-muted-foreground text-xs\">You can use this card with a label and a description.\n            </p></div></div></div><div class=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\"><RadioGroupItem value=\"2\" id=\"${`${id}-2`}\" aria-describedby=\"${`${id}-2-description`}\" class=\"order-1 after:absolute after:inset-0\" /><div class=\"flex grow items-start gap-3\"><svg class=\"shrink-0\" width=\"${32}\" height=\"${24}\" viewbox=\"0 0 32 24\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\"><g clippath=\"url(#vc-a)\"><path fill=\"#252525\" d=\"M28 0H4a4 4 0 0 0-4 4v16a4 4 0 0 0 4 4h24a4 4 0 0 0 4-4V4a4 4 0 0 0-4-4Z\" /><path fill=\"#fff\" d=\"m15.884 8.262-1.604 7.496h-1.94l1.604-7.496h1.94Z\" /><path fill=\"#fff\" fillrule=\"evenodd\" d=\"M26.207 15.758H28l-1.567-7.496H24.78a.882.882 0 0 0-.826.55l-2.91 6.946h2.037l.404-1.12h2.488l.235 1.12Zm-2.165-2.656 1.021-2.815.587 2.815h-1.608Z\" cliprule=\"evenodd\" /><path fill=\"#fff\" d=\"M21.144 13.31c.005-1.183-.975-1.698-1.76-2.11-.526-.276-.964-.506-.957-.861.007-.27.263-.555.823-.628.277-.036 1.044-.065 1.913.335l.34-1.59a5.23 5.23 0 0 0-1.815-.331c-1.917 0-3.265 1.018-3.276 2.477-.013 1.08.963 1.681 1.697 2.04.756.368 1.01.604 1.006.932-.005.503-.604.726-1.16.734-.945.015-1.506-.247-1.95-.454l-.042-.02-.352 1.643c.454.208 1.29.39 2.156.398 2.038 0 3.371-1.006 3.377-2.565ZM13.112 8.262 9.97 15.758H7.92L6.374 9.775c-.094-.368-.175-.503-.46-.658-.467-.253-1.237-.49-1.914-.638l.046-.217h3.3c.42 0 .798.28.894.763l.817 4.338 2.018-5.101h2.037Z\" /></g><defs><clipPath id=\"vc-a\"><path fill=\"#fff\" d=\"M0 0h32v24H0z\" /></clipPath></defs></svg><div class=\"grid grow gap-2\"><Label htmlfor=\"${`${id}-2`}\">Label${' '}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n              </span></Label><p id=\"${`${id}-2-description`}\" class=\"text-muted-foreground text-xs\">You can use this card with a label and a description.\n            </p></div></div></div></RadioGroup>\n</template>"
        },
        {
          "path": "registry/default/components/radio/radio-09.wxml",
          "target": "components/ui/radio-09/radio-09.wxml",
          "type": "registry:component",
          "content": "<view>\n  <radiogroup class=\"gap-2\" default-value=\"1\"><view class=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\"><radiogroupitem value=\"1\" id=\"{{`${id}-1`}}\" aria-describedby=\"{{`${id}-1-description`}}\" class=\"order-1 after:absolute after:inset-0\" /><view class=\"flex grow items-start gap-3\"><svg class=\"shrink-0\" width=\"{{32}}\" height=\"{{24}}\" viewbox=\"0 0 32 24\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\"><rect width=\"32\" height=\"24\" rx=\"4\" fill=\"#252525\" /><path d=\"M19.0537 6.49742H12.9282V17.5026H19.0537V6.49742Z\" fill=\"#FF5A00\" /><path d=\"M13.3359 12C13.3359 9.76408 14.3871 7.77961 16 6.49741C14.8129 5.56408 13.3155 5 11.6822 5C7.81295 5 4.68221 8.13074 4.68221 12C4.68221 15.8693 7.81295 19 11.6822 19C13.3155 19 14.8129 18.4359 16 17.5026C14.3848 16.2385 13.3359 14.2359 13.3359 12Z\" fill=\"#EB001B\" /><path d=\"M27.3178 12C27.3178 15.8693 24.1871 19 20.3178 19C18.6845 19 17.1871 18.4359 16 17.5026C17.6333 16.2181 18.6641 14.2359 18.6641 12C18.6641 9.76408 17.6129 7.77961 16 6.49741C17.1848 5.56408 18.6822 5 20.3155 5C24.1871 5 27.3178 8.15113 27.3178 12Z\" fill=\"#F79E1B\" /></svg><view class=\"grid grow gap-2\"><label htmlfor=\"{{`${id}-1`}}\">Label{{ ' ' }}<text class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n              </text></label><text id=\"{{`${id}-1-description`}}\" class=\"text-muted-foreground text-xs\">You can use this card with a label and a description.\n            </text></view></view></view><view class=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\"><radiogroupitem value=\"2\" id=\"{{`${id}-2`}}\" aria-describedby=\"{{`${id}-2-description`}}\" class=\"order-1 after:absolute after:inset-0\" /><view class=\"flex grow items-start gap-3\"><svg class=\"shrink-0\" width=\"{{32}}\" height=\"{{24}}\" viewbox=\"0 0 32 24\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\"><g clippath=\"url(#vc-a)\"><path fill=\"#252525\" d=\"M28 0H4a4 4 0 0 0-4 4v16a4 4 0 0 0 4 4h24a4 4 0 0 0 4-4V4a4 4 0 0 0-4-4Z\" /><path fill=\"#fff\" d=\"m15.884 8.262-1.604 7.496h-1.94l1.604-7.496h1.94Z\" /><path fill=\"#fff\" fillrule=\"evenodd\" d=\"M26.207 15.758H28l-1.567-7.496H24.78a.882.882 0 0 0-.826.55l-2.91 6.946h2.037l.404-1.12h2.488l.235 1.12Zm-2.165-2.656 1.021-2.815.587 2.815h-1.608Z\" cliprule=\"evenodd\" /><path fill=\"#fff\" d=\"M21.144 13.31c.005-1.183-.975-1.698-1.76-2.11-.526-.276-.964-.506-.957-.861.007-.27.263-.555.823-.628.277-.036 1.044-.065 1.913.335l.34-1.59a5.23 5.23 0 0 0-1.815-.331c-1.917 0-3.265 1.018-3.276 2.477-.013 1.08.963 1.681 1.697 2.04.756.368 1.01.604 1.006.932-.005.503-.604.726-1.16.734-.945.015-1.506-.247-1.95-.454l-.042-.02-.352 1.643c.454.208 1.29.39 2.156.398 2.038 0 3.371-1.006 3.377-2.565ZM13.112 8.262 9.97 15.758H7.92L6.374 9.775c-.094-.368-.175-.503-.46-.658-.467-.253-1.237-.49-1.914-.638l.046-.217h3.3c.42 0 .798.28.894.763l.817 4.338 2.018-5.101h2.037Z\" /></g><defs><clippath id=\"vc-a\"><path fill=\"#fff\" d=\"M0 0h32v24H0z\" /></clippath></defs></svg><view class=\"grid grow gap-2\"><label htmlfor=\"{{`${id}-2`}}\">Label{{ ' ' }}<text class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n              </text></label><text id=\"{{`${id}-2-description`}}\" class=\"text-muted-foreground text-xs\">You can use this card with a label and a description.\n            </text></view></view></view></radiogroup>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "radio",
          "label",
          "card",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "radio-09",
          "group": "radio",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "radio-09",
              "path": "registry/default/components/radio/radio-09.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "radio-09",
              "path": "registry/default/components/radio/radio-09.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "radio-09",
              "path": "registry/default/components/radio/radio-09.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "radio-09",
              "path": "registry/default/components/radio/radio-09.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "radio",
        "title": "Radio · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "radio"
      ]
    },
    {
      "name": "radio-10",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/radio-group.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/radio/radio-10.tsx",
          "type": "registry:component",
          "target": "components/ui/radio-10.tsx",
          "content": "import { useId } from 'react'\nimport { Label, RadioGroup, RadioGroupItem } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <RadioGroup className=\"gap-2\" defaultValue=\"1\">\n      {/* Radio card #1 */}\n      <div className=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\">\n        <RadioGroupItem\n          value=\"1\"\n          id={`${id}-1`}\n          aria-describedby={`${id}-1-description`}\n          className=\"order-1 after:absolute after:inset-0\"\n        />\n        <div className=\"flex grow items-center gap-3\">\n          <svg\n            className=\"shrink-0\"\n            xmlns=\"http://www.w3.org/2000/svg\"\n            width={32}\n            height={32}\n            aria-hidden=\"true\"\n          >\n            <circle cx=\"16\" cy=\"16\" r=\"16\" fill=\"#121212\" />\n            <g clipPath=\"url(#sb-a)\">\n              <path\n                fill=\"url(#sb-b)\"\n                d=\"M17.63 25.52c-.506.637-1.533.287-1.545-.526l-.178-11.903h8.003c1.45 0 2.259 1.674 1.357 2.81l-7.637 9.618Z\"\n              />\n              <path\n                fill=\"url(#sb-c)\"\n                fillOpacity=\".2\"\n                d=\"M17.63 25.52c-.506.637-1.533.287-1.545-.526l-.178-11.903h8.003c1.45 0 2.259 1.674 1.357 2.81l-7.637 9.618Z\"\n              />\n              <path\n                fill=\"#3ECF8E\"\n                d=\"M14.375 6.367c.506-.638 1.532-.289 1.544.525l.078 11.903H8.094c-1.45 0-2.258-1.674-1.357-2.81l7.638-9.618Z\"\n              />\n            </g>\n            <defs>\n              <linearGradient\n                id=\"sb-b\"\n                x1=\"15.907\"\n                x2=\"23.02\"\n                y1=\"15.73\"\n                y2=\"18.713\"\n                gradientUnits=\"userSpaceOnUse\"\n              >\n                <stop stopColor=\"#249361\" />\n                <stop offset=\"1\" stopColor=\"#3ECF8E\" />\n              </linearGradient>\n              <linearGradient\n                id=\"sb-c\"\n                x1=\"12.753\"\n                x2=\"15.997\"\n                y1=\"11.412\"\n                y2=\"17.519\"\n                gradientUnits=\"userSpaceOnUse\"\n              >\n                <stop />\n                <stop offset=\"1\" stopOpacity=\"0\" />\n              </linearGradient>\n              <clipPath id=\"sb-a\">\n                <path fill=\"#fff\" d=\"M6.354 6h19.292v20H6.354z\" />\n              </clipPath>\n            </defs>\n          </svg>\n          <div className=\"grid grow gap-2\">\n            <Label htmlFor={`${id}-1`}>\n              Label{' '}\n              <span className=\"text-muted-foreground text-xs leading-[inherit] font-normal\">\n                (Sublabel)\n              </span>\n            </Label>\n            <p id={`${id}-1-description`} className=\"text-muted-foreground text-xs\">\n              You can use this card with a label and a description.\n            </p>\n          </div>\n        </div>\n      </div>\n      {/* Radio card #2 */}\n      <div className=\"border-input has-data-[state=checked]:border-primary/50 relative flex items-center gap-2 rounded-md border p-4 shadow-xs outline-none\">\n        <RadioGroupItem\n          value=\"2\"\n          id={`${id}-2`}\n          aria-describedby={`${id}-2-description`}\n          className=\"order-1 after:absolute after:inset-0\"\n        />\n        <div className=\"flex grow items-start gap-3\">\n          <svg\n            className=\"shrink-0\"\n            xmlns=\"http://www.w3.org/2000/svg\"\n            width={32}\n            height={32}\n            aria-hidden=\"true\"\n          >\n            <circle cx=\"16\" cy=\"16\" r=\"16\" fill=\"#090A15\" />\n            <path\n              fill=\"#fff\"\n              fillRule=\"evenodd\"\n              d=\"M8.004 19.728a.996.996 0 0 1-.008-1.054l7.478-12.199a.996.996 0 0 1 1.753.104l6.832 14.82a.996.996 0 0 1-.618 1.37l-10.627 3.189a.996.996 0 0 1-1.128-.42l-3.682-5.81Zm8.333-9.686a.373.373 0 0 1 .709-.074l4.712 10.904a.374.374 0 0 1-.236.506L14.18 23.57a.373.373 0 0 1-.473-.431l2.63-13.097Z\"\n              clipRule=\"evenodd\"\n            />\n          </svg>\n          <div className=\"grid grow gap-2\">\n            <Label htmlFor={`${id}-2`}>\n              Label{' '}\n              <span className=\"text-muted-foreground text-xs leading-[inherit] font-normal\">\n                (Sublabel)\n              </span>\n            </Label>\n            <p id={`${id}-2-description`} className=\"text-muted-foreground text-xs\">\n              You can use this card with a label and a description.\n            </p>\n          </div>\n        </div>\n      </div>\n    </RadioGroup>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/radio/radio-10.vue",
          "target": "components/ui/radio-10.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { RadioGroup } from '@timui/vue';\nimport { RadioGroupItem } from '@timui/vue';\n\n\n\n\n\nconst id = 'radio-10';\n\n</script>\n\n<template>\n  <RadioGroup class=\"gap-2\" default-value=\"1\"><div class=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\"><RadioGroupItem value=\"1\" :id=\"`${id}-1`\" :aria-describedby=\"`${id}-1-description`\" class=\"order-1 after:absolute after:inset-0\" /><div class=\"flex grow items-center gap-3\"><svg class=\"shrink-0\" xmlns=\"http://www.w3.org/2000/svg\" :width=\"32\" :height=\"32\" aria-hidden=\"true\"><circle cx=\"16\" cy=\"16\" r=\"16\" fill=\"#121212\" /><g clipPath=\"url(#sb-a)\"><path fill=\"url(#sb-b)\" d=\"M17.63 25.52c-.506.637-1.533.287-1.545-.526l-.178-11.903h8.003c1.45 0 2.259 1.674 1.357 2.81l-7.637 9.618Z\" /><path fill=\"url(#sb-c)\" fillOpacity=\".2\" d=\"M17.63 25.52c-.506.637-1.533.287-1.545-.526l-.178-11.903h8.003c1.45 0 2.259 1.674 1.357 2.81l-7.637 9.618Z\" /><path fill=\"#3ECF8E\" d=\"M14.375 6.367c.506-.638 1.532-.289 1.544.525l.078 11.903H8.094c-1.45 0-2.258-1.674-1.357-2.81l7.638-9.618Z\" /></g><defs><linearGradient id=\"sb-b\" x1=\"15.907\" x2=\"23.02\" y1=\"15.73\" y2=\"18.713\" gradientUnits=\"userSpaceOnUse\"><stop stopColor=\"#249361\" /><stop offset=\"1\" stopColor=\"#3ECF8E\" /></linearGradient><linearGradient id=\"sb-c\" x1=\"12.753\" x2=\"15.997\" y1=\"11.412\" y2=\"17.519\" gradientUnits=\"userSpaceOnUse\"><stop /><stop offset=\"1\" stopOpacity=\"0\" /></linearGradient><clipPath id=\"sb-a\"><path fill=\"#fff\" d=\"M6.354 6h19.292v20H6.354z\" /></clipPath></defs></svg><div class=\"grid grow gap-2\"><Label :htmlFor=\"`${id}-1`\">Label{{ ' ' }}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n              </span></Label><p :id=\"`${id}-1-description`\" class=\"text-muted-foreground text-xs\">You can use this card with a label and a description.\n            </p></div></div></div><div class=\"border-input has-data-[state=checked]:border-primary/50 relative flex items-center gap-2 rounded-md border p-4 shadow-xs outline-none\"><RadioGroupItem value=\"2\" :id=\"`${id}-2`\" :aria-describedby=\"`${id}-2-description`\" class=\"order-1 after:absolute after:inset-0\" /><div class=\"flex grow items-start gap-3\"><svg class=\"shrink-0\" xmlns=\"http://www.w3.org/2000/svg\" :width=\"32\" :height=\"32\" aria-hidden=\"true\"><circle cx=\"16\" cy=\"16\" r=\"16\" fill=\"#090A15\" /><path fill=\"#fff\" fillRule=\"evenodd\" d=\"M8.004 19.728a.996.996 0 0 1-.008-1.054l7.478-12.199a.996.996 0 0 1 1.753.104l6.832 14.82a.996.996 0 0 1-.618 1.37l-10.627 3.189a.996.996 0 0 1-1.128-.42l-3.682-5.81Zm8.333-9.686a.373.373 0 0 1 .709-.074l4.712 10.904a.374.374 0 0 1-.236.506L14.18 23.57a.373.373 0 0 1-.473-.431l2.63-13.097Z\" clipRule=\"evenodd\" /></svg><div class=\"grid grow gap-2\"><Label :htmlFor=\"`${id}-2`\">Label{{ ' ' }}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n              </span></Label><p :id=\"`${id}-2-description`\" class=\"text-muted-foreground text-xs\">You can use this card with a label and a description.\n            </p></div></div></div></RadioGroup>\n</template>\n"
        },
        {
          "path": "registry/default/components/radio/radio-10.html",
          "target": "components/ui/radio-10.html",
          "type": "registry:component",
          "content": "<template>\n  <RadioGroup class=\"gap-2\" default-value=\"1\"><div class=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\"><RadioGroupItem value=\"1\" id=\"${`${id}-1`}\" aria-describedby=\"${`${id}-1-description`}\" class=\"order-1 after:absolute after:inset-0\" /><div class=\"flex grow items-center gap-3\"><svg class=\"shrink-0\" xmlns=\"http://www.w3.org/2000/svg\" width=\"${32}\" height=\"${32}\" aria-hidden=\"true\"><circle cx=\"16\" cy=\"16\" r=\"16\" fill=\"#121212\" /><g clippath=\"url(#sb-a)\"><path fill=\"url(#sb-b)\" d=\"M17.63 25.52c-.506.637-1.533.287-1.545-.526l-.178-11.903h8.003c1.45 0 2.259 1.674 1.357 2.81l-7.637 9.618Z\" /><path fill=\"url(#sb-c)\" fillopacity=\".2\" d=\"M17.63 25.52c-.506.637-1.533.287-1.545-.526l-.178-11.903h8.003c1.45 0 2.259 1.674 1.357 2.81l-7.637 9.618Z\" /><path fill=\"#3ECF8E\" d=\"M14.375 6.367c.506-.638 1.532-.289 1.544.525l.078 11.903H8.094c-1.45 0-2.258-1.674-1.357-2.81l7.638-9.618Z\" /></g><defs><linearGradient id=\"sb-b\" x1=\"15.907\" x2=\"23.02\" y1=\"15.73\" y2=\"18.713\" gradientunits=\"userSpaceOnUse\"><stop stopcolor=\"#249361\" /><stop offset=\"1\" stopcolor=\"#3ECF8E\" /></linearGradient><linearGradient id=\"sb-c\" x1=\"12.753\" x2=\"15.997\" y1=\"11.412\" y2=\"17.519\" gradientunits=\"userSpaceOnUse\"><stop /><stop offset=\"1\" stopopacity=\"0\" /></linearGradient><clipPath id=\"sb-a\"><path fill=\"#fff\" d=\"M6.354 6h19.292v20H6.354z\" /></clipPath></defs></svg><div class=\"grid grow gap-2\"><Label htmlfor=\"${`${id}-1`}\">Label${' '}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n              </span></Label><p id=\"${`${id}-1-description`}\" class=\"text-muted-foreground text-xs\">You can use this card with a label and a description.\n            </p></div></div></div><div class=\"border-input has-data-[state=checked]:border-primary/50 relative flex items-center gap-2 rounded-md border p-4 shadow-xs outline-none\"><RadioGroupItem value=\"2\" id=\"${`${id}-2`}\" aria-describedby=\"${`${id}-2-description`}\" class=\"order-1 after:absolute after:inset-0\" /><div class=\"flex grow items-start gap-3\"><svg class=\"shrink-0\" xmlns=\"http://www.w3.org/2000/svg\" width=\"${32}\" height=\"${32}\" aria-hidden=\"true\"><circle cx=\"16\" cy=\"16\" r=\"16\" fill=\"#090A15\" /><path fill=\"#fff\" fillrule=\"evenodd\" d=\"M8.004 19.728a.996.996 0 0 1-.008-1.054l7.478-12.199a.996.996 0 0 1 1.753.104l6.832 14.82a.996.996 0 0 1-.618 1.37l-10.627 3.189a.996.996 0 0 1-1.128-.42l-3.682-5.81Zm8.333-9.686a.373.373 0 0 1 .709-.074l4.712 10.904a.374.374 0 0 1-.236.506L14.18 23.57a.373.373 0 0 1-.473-.431l2.63-13.097Z\" cliprule=\"evenodd\" /></svg><div class=\"grid grow gap-2\"><Label htmlfor=\"${`${id}-2`}\">Label${' '}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n              </span></Label><p id=\"${`${id}-2-description`}\" class=\"text-muted-foreground text-xs\">You can use this card with a label and a description.\n            </p></div></div></div></RadioGroup>\n</template>"
        },
        {
          "path": "registry/default/components/radio/radio-10.wxml",
          "target": "components/ui/radio-10/radio-10.wxml",
          "type": "registry:component",
          "content": "<view>\n  <radiogroup class=\"gap-2\" default-value=\"1\"><view class=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\"><radiogroupitem value=\"1\" id=\"{{`${id}-1`}}\" aria-describedby=\"{{`${id}-1-description`}}\" class=\"order-1 after:absolute after:inset-0\" /><view class=\"flex grow items-center gap-3\"><svg class=\"shrink-0\" xmlns=\"http://www.w3.org/2000/svg\" width=\"{{32}}\" height=\"{{32}}\" aria-hidden=\"true\"><circle cx=\"16\" cy=\"16\" r=\"16\" fill=\"#121212\" /><g clippath=\"url(#sb-a)\"><path fill=\"url(#sb-b)\" d=\"M17.63 25.52c-.506.637-1.533.287-1.545-.526l-.178-11.903h8.003c1.45 0 2.259 1.674 1.357 2.81l-7.637 9.618Z\" /><path fill=\"url(#sb-c)\" fillopacity=\".2\" d=\"M17.63 25.52c-.506.637-1.533.287-1.545-.526l-.178-11.903h8.003c1.45 0 2.259 1.674 1.357 2.81l-7.637 9.618Z\" /><path fill=\"#3ECF8E\" d=\"M14.375 6.367c.506-.638 1.532-.289 1.544.525l.078 11.903H8.094c-1.45 0-2.258-1.674-1.357-2.81l7.638-9.618Z\" /></g><defs><lineargradient id=\"sb-b\" x1=\"15.907\" x2=\"23.02\" y1=\"15.73\" y2=\"18.713\" gradientunits=\"userSpaceOnUse\"><stop stopcolor=\"#249361\" /><stop offset=\"1\" stopcolor=\"#3ECF8E\" /></lineargradient><lineargradient id=\"sb-c\" x1=\"12.753\" x2=\"15.997\" y1=\"11.412\" y2=\"17.519\" gradientunits=\"userSpaceOnUse\"><stop /><stop offset=\"1\" stopopacity=\"0\" /></lineargradient><clippath id=\"sb-a\"><path fill=\"#fff\" d=\"M6.354 6h19.292v20H6.354z\" /></clippath></defs></svg><view class=\"grid grow gap-2\"><label htmlfor=\"{{`${id}-1`}}\">Label{{ ' ' }}<text class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n              </text></label><text id=\"{{`${id}-1-description`}}\" class=\"text-muted-foreground text-xs\">You can use this card with a label and a description.\n            </text></view></view></view><view class=\"border-input has-data-[state=checked]:border-primary/50 relative flex items-center gap-2 rounded-md border p-4 shadow-xs outline-none\"><radiogroupitem value=\"2\" id=\"{{`${id}-2`}}\" aria-describedby=\"{{`${id}-2-description`}}\" class=\"order-1 after:absolute after:inset-0\" /><view class=\"flex grow items-start gap-3\"><svg class=\"shrink-0\" xmlns=\"http://www.w3.org/2000/svg\" width=\"{{32}}\" height=\"{{32}}\" aria-hidden=\"true\"><circle cx=\"16\" cy=\"16\" r=\"16\" fill=\"#090A15\" /><path fill=\"#fff\" fillrule=\"evenodd\" d=\"M8.004 19.728a.996.996 0 0 1-.008-1.054l7.478-12.199a.996.996 0 0 1 1.753.104l6.832 14.82a.996.996 0 0 1-.618 1.37l-10.627 3.189a.996.996 0 0 1-1.128-.42l-3.682-5.81Zm8.333-9.686a.373.373 0 0 1 .709-.074l4.712 10.904a.374.374 0 0 1-.236.506L14.18 23.57a.373.373 0 0 1-.473-.431l2.63-13.097Z\" cliprule=\"evenodd\" /></svg><view class=\"grid grow gap-2\"><label htmlfor=\"{{`${id}-2`}}\">Label{{ ' ' }}<text class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n              </text></label><text id=\"{{`${id}-2-description`}}\" class=\"text-muted-foreground text-xs\">You can use this card with a label and a description.\n            </text></view></view></view></radiogroup>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "radio",
          "label",
          "card",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "radio-10",
          "group": "radio",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "radio-10",
              "path": "registry/default/components/radio/radio-10.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "radio-10",
              "path": "registry/default/components/radio/radio-10.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "radio-10",
              "path": "registry/default/components/radio/radio-10.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "radio-10",
              "path": "registry/default/components/radio/radio-10.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "radio",
        "title": "Radio · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "radio"
      ]
    },
    {
      "name": "radio-11",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/radio-group.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/radio/radio-11.tsx",
          "type": "registry:component",
          "target": "components/ui/radio-11.tsx",
          "content": "import { useId } from 'react'\nimport { Label, RadioGroup, RadioGroupItem } from '@timui/react'\nimport { Brush, Eraser, Scissors, SwatchBook } from 'lucide-react'\n\nexport default function Component() {\n  const id = useId()\n\n  const items = [\n    { value: '1', label: 'Palette', Icon: SwatchBook },\n    { value: '2', label: 'Brush', Icon: Brush },\n    { value: '3', label: 'Eraser', Icon: Eraser },\n    { value: '4', label: 'Cut', Icon: Scissors },\n  ]\n\n  return (\n    <RadioGroup className=\"grid-cols-2\" defaultValue=\"1\">\n      {items.map((item) => (\n        <div\n          key={`${id}-${item.value}`}\n          className=\"border-input has-data-[state=checked]:border-primary/50 relative flex flex-col gap-4 rounded-md border p-4 shadow-xs outline-none\"\n        >\n          <div className=\"flex justify-between gap-2\">\n            <RadioGroupItem\n              id={`${id}-${item.value}`}\n              value={item.value}\n              className=\"order-1 after:absolute after:inset-0\"\n            />\n            <item.Icon className=\"opacity-60\" size={16} aria-hidden=\"true\" />\n          </div>\n          <Label htmlFor={`${id}-${item.value}`}>{item.label}</Label>\n        </div>\n      ))}\n    </RadioGroup>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/radio/radio-11.vue",
          "target": "components/ui/radio-11.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Brush, Eraser, Scissors, SwatchBook } from 'lucide-vue-next';\nimport { Label } from '@timui/vue';\nimport { RadioGroup } from '@timui/vue';\nimport { RadioGroupItem } from '@timui/vue';\n\n\n\n\n\nconst id = 'radio-11';\n\n\nconst items = [\n    { value: '1', label: 'Palette', Icon: SwatchBook },\n    { value: '2', label: 'Brush', Icon: Brush },\n    { value: '3', label: 'Eraser', Icon: Eraser },\n    { value: '4', label: 'Cut', Icon: Scissors },\n  ]\n\n</script>\n\n<template>\n  <RadioGroup class=\"grid-cols-2\" default-value=\"1\"><div v-for=\"(item, index) in items\" :key=\"`${id}-${item.value}`\" class=\"border-input has-data-[state=checked]:border-primary/50 relative flex flex-col gap-4 rounded-md border p-4 shadow-xs outline-none\"><div class=\"flex justify-between gap-2\"><RadioGroupItem :id=\"`${id}-${item.value}`\" :value=\"item.value\" class=\"order-1 after:absolute after:inset-0\" /><item.Icon class=\"opacity-60\" :size=\"16\" aria-hidden=\"true\" /></div><Label :htmlFor=\"`${id}-${item.value}`\">{{ item.label }}</Label></div></RadioGroup>\n</template>\n"
        },
        {
          "path": "registry/default/components/radio/radio-11.html",
          "target": "components/ui/radio-11.html",
          "type": "registry:component",
          "content": "<template>\n  <RadioGroup class=\"grid-cols-2\" default-value=\"1\"><!-- Loop items -->\n<div key=\"${`${id}-${item.value}`}\" class=\"border-input has-data-[state=checked]:border-primary/50 relative flex flex-col gap-4 rounded-md border p-4 shadow-xs outline-none\"><div class=\"flex justify-between gap-2\"><RadioGroupItem id=\"${`${id}-${item.value}`}\" value=\"${item.value}\" class=\"order-1 after:absolute after:inset-0\" /><item.Icon class=\"opacity-60\" size=\"${16}\" aria-hidden=\"true\" /></div><Label htmlfor=\"${`${id}-${item.value}`}\">${item.label}</Label></div>\n<!-- End Loop --></RadioGroup>\n</template>"
        },
        {
          "path": "registry/default/components/radio/radio-11.wxml",
          "target": "components/ui/radio-11/radio-11.wxml",
          "type": "registry:component",
          "content": "<view>\n  <radiogroup class=\"grid-cols-2\" default-value=\"1\"><view wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{`${id}-${item.value}`}}\" class=\"border-input has-data-[state=checked]:border-primary/50 relative flex flex-col gap-4 rounded-md border p-4 shadow-xs outline-none\"><view class=\"flex justify-between gap-2\"><radiogroupitem id=\"{{`${id}-${item.value}`}}\" value=\"{{item.value}}\" class=\"order-1 after:absolute after:inset-0\" /><item.icon class=\"opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" /></view><label htmlfor=\"{{`${id}-${item.value}`}}\">{{ item.label }}</label></view></radiogroup>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "radio",
          "label",
          "card",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "radio-11",
          "group": "radio",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "radio-11",
              "path": "registry/default/components/radio/radio-11.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "radio-11",
              "path": "registry/default/components/radio/radio-11.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "radio-11",
              "path": "registry/default/components/radio/radio-11.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "radio-11",
              "path": "registry/default/components/radio/radio-11.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "radio",
        "title": "Radio · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "radio"
      ]
    },
    {
      "name": "radio-12",
      "type": "registry:component",
      "dependencies": [
        "@remixicon/react",
        "@timui/react"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/radio-group.json"
      ],
      "files": [
        {
          "path": "registry/default/components/radio/radio-12.tsx",
          "type": "registry:component",
          "target": "components/ui/radio-12.tsx",
          "content": "import { useId } from 'react'\nimport { RiAppleLine, RiBankCardLine, RiPaypalLine } from '@remixicon/react'\nimport { RadioGroup, RadioGroupItem } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <RadioGroup className=\"grid-cols-3\" defaultValue=\"1\">\n      {/* Credit card */}\n      <div className=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex cursor-pointer flex-col items-center gap-3 rounded-md border px-2 py-3 text-center shadow-xs transition-[color,box-shadow] outline-none has-focus-visible:ring-[3px]\">\n        <RadioGroupItem id={`${id}-1`} value=\"1\" className=\"sr-only\" />\n        <RiBankCardLine className=\"opacity-60\" size={20} aria-hidden=\"true\" />\n        <label\n          htmlFor={`${id}-1`}\n          className=\"text-foreground cursor-pointer text-xs leading-none font-medium after:absolute after:inset-0\"\n        >\n          Card\n        </label>\n      </div>\n      {/* PayPal */}\n      <div className=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex cursor-pointer flex-col items-center gap-3 rounded-md border px-2 py-3 text-center shadow-xs transition-[color,box-shadow] outline-none has-focus-visible:ring-[3px]\">\n        <RadioGroupItem id={`${id}-2`} value=\"2\" className=\"sr-only\" />\n        <RiPaypalLine className=\"opacity-60\" size={20} aria-hidden=\"true\" />\n        <label\n          htmlFor={`${id}-2`}\n          className=\"text-foreground cursor-pointer text-xs leading-none font-medium after:absolute after:inset-0\"\n        >\n          PayPal\n        </label>\n      </div>\n      {/* Apple Pay */}\n      <div className=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex cursor-pointer flex-col items-center gap-3 rounded-md border px-2 py-3 text-center shadow-xs transition-[color,box-shadow] outline-none has-focus-visible:ring-[3px]\">\n        <RadioGroupItem id={`${id}-3`} value=\"3\" className=\"sr-only\" />\n        <RiAppleLine className=\"opacity-60\" size={20} aria-hidden=\"true\" />\n        <label\n          htmlFor={`${id}-3`}\n          className=\"text-foreground cursor-pointer text-xs leading-none font-medium after:absolute after:inset-0\"\n        >\n          Apple Pay\n        </label>\n      </div>\n    </RadioGroup>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/radio/radio-12.vue",
          "target": "components/ui/radio-12.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { AppleIcon, CreditCardIcon, WalletIcon } from 'lucide-vue-next'\nimport { RadioGroup } from '@timui/vue'\nimport { RadioGroupItem } from '@timui/vue'\n\nconst id = 'radio-12'\n</script>\n\n<template>\n  <RadioGroup class=\"grid-cols-3\" default-value=\"1\">\n    <div class=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex cursor-pointer flex-col items-center gap-3 rounded-md border px-2 py-3 text-center shadow-xs transition-[color,box-shadow] outline-none has-focus-visible:ring-[3px]\">\n      <RadioGroupItem :id=\"`${id}-1`\" value=\"1\" class=\"sr-only\" />\n      <CreditCardIcon class=\"opacity-60\" :size=\"20\" aria-hidden=\"true\" />\n      <label :for=\"`${id}-1`\" class=\"text-foreground cursor-pointer text-xs leading-none font-medium after:absolute after:inset-0\">Card</label>\n    </div>\n    <div class=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex cursor-pointer flex-col items-center gap-3 rounded-md border px-2 py-3 text-center shadow-xs transition-[color,box-shadow] outline-none has-focus-visible:ring-[3px]\">\n      <RadioGroupItem :id=\"`${id}-2`\" value=\"2\" class=\"sr-only\" />\n      <WalletIcon class=\"opacity-60\" :size=\"20\" aria-hidden=\"true\" />\n      <label :for=\"`${id}-2`\" class=\"text-foreground cursor-pointer text-xs leading-none font-medium after:absolute after:inset-0\">PayPal</label>\n    </div>\n    <div class=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex cursor-pointer flex-col items-center gap-3 rounded-md border px-2 py-3 text-center shadow-xs transition-[color,box-shadow] outline-none has-focus-visible:ring-[3px]\">\n      <RadioGroupItem :id=\"`${id}-3`\" value=\"3\" class=\"sr-only\" />\n      <AppleIcon class=\"opacity-60\" :size=\"20\" aria-hidden=\"true\" />\n      <label :for=\"`${id}-3`\" class=\"text-foreground cursor-pointer text-xs leading-none font-medium after:absolute after:inset-0\">Apple Pay</label>\n    </div>\n  </RadioGroup>\n</template>\n"
        },
        {
          "path": "registry/default/components/radio/radio-12.html",
          "target": "components/ui/radio-12.html",
          "type": "registry:component",
          "content": "<template>\n  <RadioGroup class=\"grid-cols-3\" default-value=\"1\"><div class=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex cursor-pointer flex-col items-center gap-3 rounded-md border px-2 py-3 text-center shadow-xs transition-[color,box-shadow] outline-none has-focus-visible:ring-[3px]\"><RadioGroupItem id=\"${`${id}-1`}\" value=\"1\" class=\"sr-only\" /><RiBankCardLine class=\"opacity-60\" size=\"${20}\" aria-hidden=\"true\" /><label htmlfor=\"${`${id}-1`}\" class=\"text-foreground cursor-pointer text-xs leading-none font-medium after:absolute after:inset-0\">Card\n        </label></div><div class=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex cursor-pointer flex-col items-center gap-3 rounded-md border px-2 py-3 text-center shadow-xs transition-[color,box-shadow] outline-none has-focus-visible:ring-[3px]\"><RadioGroupItem id=\"${`${id}-2`}\" value=\"2\" class=\"sr-only\" /><RiPaypalLine class=\"opacity-60\" size=\"${20}\" aria-hidden=\"true\" /><label htmlfor=\"${`${id}-2`}\" class=\"text-foreground cursor-pointer text-xs leading-none font-medium after:absolute after:inset-0\">PayPal\n        </label></div><div class=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex cursor-pointer flex-col items-center gap-3 rounded-md border px-2 py-3 text-center shadow-xs transition-[color,box-shadow] outline-none has-focus-visible:ring-[3px]\"><RadioGroupItem id=\"${`${id}-3`}\" value=\"3\" class=\"sr-only\" /><RiAppleLine class=\"opacity-60\" size=\"${20}\" aria-hidden=\"true\" /><label htmlfor=\"${`${id}-3`}\" class=\"text-foreground cursor-pointer text-xs leading-none font-medium after:absolute after:inset-0\">Apple Pay\n        </label></div></RadioGroup>\n</template>"
        },
        {
          "path": "registry/default/components/radio/radio-12.wxml",
          "target": "components/ui/radio-12/radio-12.wxml",
          "type": "registry:component",
          "content": "<view>\n  <radiogroup class=\"grid-cols-3\" default-value=\"1\"><view class=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex cursor-pointer flex-col items-center gap-3 rounded-md border px-2 py-3 text-center shadow-xs transition-[color,box-shadow] outline-none has-focus-visible:ring-[3px]\"><radiogroupitem id=\"{{`${id}-1`}}\" value=\"1\" class=\"sr-only\" /><ribankcardline class=\"opacity-60\" size=\"{{20}}\" aria-hidden=\"true\" /><label htmlfor=\"{{`${id}-1`}}\" class=\"text-foreground cursor-pointer text-xs leading-none font-medium after:absolute after:inset-0\">Card\n        </label></view><view class=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex cursor-pointer flex-col items-center gap-3 rounded-md border px-2 py-3 text-center shadow-xs transition-[color,box-shadow] outline-none has-focus-visible:ring-[3px]\"><radiogroupitem id=\"{{`${id}-2`}}\" value=\"2\" class=\"sr-only\" /><ripaypalline class=\"opacity-60\" size=\"{{20}}\" aria-hidden=\"true\" /><label htmlfor=\"{{`${id}-2`}}\" class=\"text-foreground cursor-pointer text-xs leading-none font-medium after:absolute after:inset-0\">PayPal\n        </label></view><view class=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex cursor-pointer flex-col items-center gap-3 rounded-md border px-2 py-3 text-center shadow-xs transition-[color,box-shadow] outline-none has-focus-visible:ring-[3px]\"><radiogroupitem id=\"{{`${id}-3`}}\" value=\"3\" class=\"sr-only\" /><riappleline class=\"opacity-60\" size=\"{{20}}\" aria-hidden=\"true\" /><label htmlfor=\"{{`${id}-3`}}\" class=\"text-foreground cursor-pointer text-xs leading-none font-medium after:absolute after:inset-0\">Apple Pay\n        </label></view></radiogroup>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "radio",
          "label",
          "card",
          "checkout",
          "payment",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "radio-12",
          "group": "radio",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "radio-12",
              "path": "registry/default/components/radio/radio-12.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "radio-12",
              "path": "registry/default/components/radio/radio-12.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "radio-12",
              "path": "registry/default/components/radio/radio-12.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "radio-12",
              "path": "registry/default/components/radio/radio-12.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@remixicon/react",
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "radio",
        "title": "Radio · With label"
      },
      "categories": [
        "radio"
      ]
    },
    {
      "name": "radio-13",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/radio-group.json"
      ],
      "files": [
        {
          "path": "registry/default/components/radio/radio-13.tsx",
          "type": "registry:component",
          "target": "components/ui/radio-13.tsx",
          "content": "import { useId } from 'react'\nimport { RadioGroup, RadioGroupItem } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n\n  const items = [\n    { value: '1', label: '2 CPU' },\n    { value: '2', label: '4 CPU' },\n    { value: '3', label: '6 CPU' },\n    { value: '4', label: '8 CPU' },\n    { value: '5', label: '12 CPU' },\n    { value: '6', label: '16 CPU', disabled: true },\n  ]\n\n  return (\n    <fieldset className=\"space-y-4\">\n      <legend className=\"text-foreground text-sm leading-none font-medium\">CPU Cores</legend>\n      <RadioGroup className=\"grid grid-cols-3 gap-2\" defaultValue=\"1\">\n        {items.map((item) => (\n          <label\n            key={`${id}-${item.value}`}\n            className=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex cursor-pointer flex-col items-center gap-3 rounded-md border px-2 py-3 text-center shadow-xs transition-[color,box-shadow] outline-none has-focus-visible:ring-[3px] has-data-disabled:cursor-not-allowed has-data-disabled:opacity-50\"\n          >\n            <RadioGroupItem\n              id={`${id}-${item.value}`}\n              value={item.value}\n              className=\"sr-only after:absolute after:inset-0\"\n              disabled={item.disabled}\n            />\n            <p className=\"text-foreground text-sm leading-none font-medium\">{item.label}</p>\n          </label>\n        ))}\n      </RadioGroup>\n    </fieldset>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/radio/radio-13.vue",
          "target": "components/ui/radio-13.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { RadioGroup } from '@timui/vue';\nimport { RadioGroupItem } from '@timui/vue';\n\n\n\n\n\nconst id = 'radio-13';\n\n\nconst items = [\n    { value: '1', label: '2 CPU' },\n    { value: '2', label: '4 CPU' },\n    { value: '3', label: '6 CPU' },\n    { value: '4', label: '8 CPU' },\n    { value: '5', label: '12 CPU' },\n    { value: '6', label: '16 CPU', disabled: true },\n  ]\n\n</script>\n\n<template>\n  <fieldset class=\"space-y-4\"><legend class=\"text-foreground text-sm leading-none font-medium\">CPU Cores</legend><RadioGroup class=\"grid grid-cols-3 gap-2\" default-value=\"1\"><label v-for=\"(item, index) in items\" :key=\"`${id}-${item.value}`\" class=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex cursor-pointer flex-col items-center gap-3 rounded-md border px-2 py-3 text-center shadow-xs transition-[color,box-shadow] outline-none has-focus-visible:ring-[3px] has-data-disabled:cursor-not-allowed has-data-disabled:opacity-50\"><RadioGroupItem :id=\"`${id}-${item.value}`\" :value=\"item.value\" class=\"sr-only after:absolute after:inset-0\" :disabled=\"item.disabled\" /><p class=\"text-foreground text-sm leading-none font-medium\">{{ item.label }}</p></label></RadioGroup></fieldset>\n</template>\n"
        },
        {
          "path": "registry/default/components/radio/radio-13.html",
          "target": "components/ui/radio-13.html",
          "type": "registry:component",
          "content": "<template>\n  <fieldset class=\"space-y-4\"><legend class=\"text-foreground text-sm leading-none font-medium\">CPU Cores</legend><RadioGroup class=\"grid grid-cols-3 gap-2\" default-value=\"1\"><!-- Loop items -->\n<label key=\"${`${id}-${item.value}`}\" class=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex cursor-pointer flex-col items-center gap-3 rounded-md border px-2 py-3 text-center shadow-xs transition-[color,box-shadow] outline-none has-focus-visible:ring-[3px] has-data-disabled:cursor-not-allowed has-data-disabled:opacity-50\"><RadioGroupItem id=\"${`${id}-${item.value}`}\" value=\"${item.value}\" class=\"sr-only after:absolute after:inset-0\" disabled=\"${item.disabled}\" /><p class=\"text-foreground text-sm leading-none font-medium\">${item.label}</p></label>\n<!-- End Loop --></RadioGroup></fieldset>\n</template>"
        },
        {
          "path": "registry/default/components/radio/radio-13.wxml",
          "target": "components/ui/radio-13/radio-13.wxml",
          "type": "registry:component",
          "content": "<view>\n  <fieldset class=\"space-y-4\"><legend class=\"text-foreground text-sm leading-none font-medium\">CPU Cores</legend><radiogroup class=\"grid grid-cols-3 gap-2\" default-value=\"1\"><label wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{`${id}-${item.value}`}}\" class=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex cursor-pointer flex-col items-center gap-3 rounded-md border px-2 py-3 text-center shadow-xs transition-[color,box-shadow] outline-none has-focus-visible:ring-[3px] has-data-disabled:cursor-not-allowed has-data-disabled:opacity-50\"><radiogroupitem id=\"{{`${id}-${item.value}`}}\" value=\"{{item.value}}\" class=\"sr-only after:absolute after:inset-0\" disabled=\"{{item.disabled}}\" /><text class=\"text-foreground text-sm leading-none font-medium\">{{ item.label }}</text></label></radiogroup></fieldset>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "radio",
          "label",
          "card",
          "pricing",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "radio-13",
          "group": "radio",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "radio-13",
              "path": "registry/default/components/radio/radio-13.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "radio-13",
              "path": "registry/default/components/radio/radio-13.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "radio-13",
              "path": "registry/default/components/radio/radio-13.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "radio-13",
              "path": "registry/default/components/radio/radio-13.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "radio",
        "title": "Radio · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "radio"
      ]
    },
    {
      "name": "radio-14",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/radio-group.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/radio/radio-14.tsx",
          "type": "registry:component",
          "target": "components/ui/radio-14.tsx",
          "content": "import { useId } from 'react'\nimport { Label, RadioGroup, RadioGroupItem } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n\n  const items = [\n    { value: '1', label: 'USA' },\n    { value: '2', label: 'UK' },\n    { value: '3', label: 'France' },\n  ]\n\n  return (\n    <fieldset className=\"space-y-4\">\n      <legend className=\"text-foreground text-sm leading-none font-medium\">Server location</legend>\n      <RadioGroup className=\"flex flex-wrap gap-2\" defaultValue=\"1\">\n        {items.map((item) => (\n          <div\n            key={`${id}-${item.value}`}\n            className=\"border-input has-data-[state=checked]:border-primary/50 relative flex flex-col items-start gap-4 rounded-md border p-3 shadow-xs outline-none\"\n          >\n            <div className=\"flex items-center gap-2\">\n              <RadioGroupItem\n                id={`${id}-${item.value}`}\n                value={item.value}\n                className=\"after:absolute after:inset-0\"\n              />\n              <Label htmlFor={`${id}-${item.value}`}>{item.label}</Label>\n            </div>\n          </div>\n        ))}\n      </RadioGroup>\n    </fieldset>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/radio/radio-14.vue",
          "target": "components/ui/radio-14.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { RadioGroup } from '@timui/vue';\nimport { RadioGroupItem } from '@timui/vue';\n\n\n\n\n\nconst id = 'radio-14';\n\n\nconst items = [\n    { value: '1', label: 'USA' },\n    { value: '2', label: 'UK' },\n    { value: '3', label: 'France' },\n  ]\n\n</script>\n\n<template>\n  <fieldset class=\"space-y-4\"><legend class=\"text-foreground text-sm leading-none font-medium\">Server location</legend><RadioGroup class=\"flex flex-wrap gap-2\" default-value=\"1\"><div v-for=\"(item, index) in items\" :key=\"`${id}-${item.value}`\" class=\"border-input has-data-[state=checked]:border-primary/50 relative flex flex-col items-start gap-4 rounded-md border p-3 shadow-xs outline-none\"><div class=\"flex items-center gap-2\"><RadioGroupItem :id=\"`${id}-${item.value}`\" :value=\"item.value\" class=\"after:absolute after:inset-0\" /><Label :htmlFor=\"`${id}-${item.value}`\">{{ item.label }}</Label></div></div></RadioGroup></fieldset>\n</template>\n"
        },
        {
          "path": "registry/default/components/radio/radio-14.html",
          "target": "components/ui/radio-14.html",
          "type": "registry:component",
          "content": "<template>\n  <fieldset class=\"space-y-4\"><legend class=\"text-foreground text-sm leading-none font-medium\">Server location</legend><RadioGroup class=\"flex flex-wrap gap-2\" default-value=\"1\"><!-- Loop items -->\n<div key=\"${`${id}-${item.value}`}\" class=\"border-input has-data-[state=checked]:border-primary/50 relative flex flex-col items-start gap-4 rounded-md border p-3 shadow-xs outline-none\"><div class=\"flex items-center gap-2\"><RadioGroupItem id=\"${`${id}-${item.value}`}\" value=\"${item.value}\" class=\"after:absolute after:inset-0\" /><Label htmlfor=\"${`${id}-${item.value}`}\">${item.label}</Label></div></div>\n<!-- End Loop --></RadioGroup></fieldset>\n</template>"
        },
        {
          "path": "registry/default/components/radio/radio-14.wxml",
          "target": "components/ui/radio-14/radio-14.wxml",
          "type": "registry:component",
          "content": "<view>\n  <fieldset class=\"space-y-4\"><legend class=\"text-foreground text-sm leading-none font-medium\">Server location</legend><radiogroup class=\"flex flex-wrap gap-2\" default-value=\"1\"><view wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{`${id}-${item.value}`}}\" class=\"border-input has-data-[state=checked]:border-primary/50 relative flex flex-col items-start gap-4 rounded-md border p-3 shadow-xs outline-none\"><view class=\"flex items-center gap-2\"><radiogroupitem id=\"{{`${id}-${item.value}`}}\" value=\"{{item.value}}\" class=\"after:absolute after:inset-0\" /><label htmlfor=\"{{`${id}-${item.value}`}}\">{{ item.label }}</label></view></view></radiogroup></fieldset>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "radio",
          "label",
          "card",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "radio-14",
          "group": "radio",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "radio-14",
              "path": "registry/default/components/radio/radio-14.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "radio-14",
              "path": "registry/default/components/radio/radio-14.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "radio-14",
              "path": "registry/default/components/radio/radio-14.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "radio-14",
              "path": "registry/default/components/radio/radio-14.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "radio",
        "title": "Radio · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "radio"
      ]
    },
    {
      "name": "radio-15",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/radio-group.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/badge.json"
      ],
      "files": [
        {
          "path": "registry/default/components/radio/radio-15.tsx",
          "type": "registry:component",
          "target": "components/ui/radio-15.tsx",
          "content": "import { useId } from 'react'\nimport { Badge, Label, RadioGroup, RadioGroupItem } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n\n  const items = [\n    { value: '1', label: 'Hobby', price: '$9/mo' },\n    { value: '2', label: 'Plus', price: '$29/mo' },\n    { value: '3', label: 'Team', price: '$49/mo' },\n    { value: '4', label: 'Enterprise', price: 'Custom' },\n  ]\n\n  return (\n    <fieldset className=\"space-y-4\">\n      <legend className=\"text-foreground text-sm leading-none font-medium\">Choose plan</legend>\n      <RadioGroup className=\"gap-0 -space-y-px rounded-md shadow-xs\" defaultValue=\"2\">\n        {items.map((item) => (\n          <div\n            key={`${id}-${item.value}`}\n            className=\"border-input has-data-[state=checked]:border-primary/50 has-data-[state=checked]:bg-accent relative flex flex-col gap-4 border p-4 outline-none first:rounded-t-md last:rounded-b-md has-data-[state=checked]:z-10\"\n          >\n            <div className=\"flex items-center justify-between\">\n              <div className=\"flex items-center gap-2\">\n                <RadioGroupItem\n                  id={`${id}-${item.value}`}\n                  value={item.value}\n                  className=\"after:absolute after:inset-0\"\n                  aria-describedby={`${`${id}-${item.value}`}-price`}\n                />\n                <Label className=\"inline-flex items-start\" htmlFor={`${id}-${item.value}`}>\n                  {item.label}\n                  {item.value === '2' && <Badge className=\"ms-2 -mt-1\">Popular</Badge>}\n                </Label>\n              </div>\n              <div\n                id={`${`${id}-${item.value}`}-price`}\n                className=\"text-muted-foreground text-xs leading-[inherit]\"\n              >\n                {item.price}\n              </div>\n            </div>\n          </div>\n        ))}\n      </RadioGroup>\n    </fieldset>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/radio/radio-15.vue",
          "target": "components/ui/radio-15.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Badge } from '@timui/vue';\nimport { Label } from '@timui/vue';\nimport { RadioGroup } from '@timui/vue';\nimport { RadioGroupItem } from '@timui/vue';\n\n\n\n\n\nconst id = 'radio-15';\n\n\nconst items = [\n    { value: '1', label: 'Hobby', price: '$9/mo' },\n    { value: '2', label: 'Plus', price: '$29/mo' },\n    { value: '3', label: 'Team', price: '$49/mo' },\n    { value: '4', label: 'Enterprise', price: 'Custom' },\n  ]\n\n</script>\n\n<template>\n  <fieldset class=\"space-y-4\"><legend class=\"text-foreground text-sm leading-none font-medium\">Choose plan</legend><RadioGroup class=\"gap-0 -space-y-px rounded-md shadow-xs\" default-value=\"2\"><div v-for=\"(item, index) in items\" :key=\"`${id}-${item.value}`\" class=\"border-input has-data-[state=checked]:border-primary/50 has-data-[state=checked]:bg-accent relative flex flex-col gap-4 border p-4 outline-none first:rounded-t-md last:rounded-b-md has-data-[state=checked]:z-10\"><div class=\"flex items-center justify-between\"><div class=\"flex items-center gap-2\"><RadioGroupItem :id=\"`${id}-${item.value}`\" :value=\"item.value\" class=\"after:absolute after:inset-0\" :aria-describedby=\"`${`${id}-${item.value}`}-price`\" /><Label class=\"inline-flex items-start\" :htmlFor=\"`${id}-${item.value}`\">{{ item.label }}<Badge v-if=\"item.value === '2'\" class=\"ms-2 -mt-1\">Popular</Badge></Label></div><div :id=\"`${`${id}-${item.value}`}-price`\" class=\"text-muted-foreground text-xs leading-[inherit]\">{{ item.price }}</div></div></div></RadioGroup></fieldset>\n</template>\n"
        },
        {
          "path": "registry/default/components/radio/radio-15.html",
          "target": "components/ui/radio-15.html",
          "type": "registry:component",
          "content": "<template>\n  <fieldset class=\"space-y-4\"><legend class=\"text-foreground text-sm leading-none font-medium\">Choose plan</legend><RadioGroup class=\"gap-0 -space-y-px rounded-md shadow-xs\" default-value=\"2\"><!-- Loop items -->\n<div key=\"${`${id}-${item.value}`}\" class=\"border-input has-data-[state=checked]:border-primary/50 has-data-[state=checked]:bg-accent relative flex flex-col gap-4 border p-4 outline-none first:rounded-t-md last:rounded-b-md has-data-[state=checked]:z-10\"><div class=\"flex items-center justify-between\"><div class=\"flex items-center gap-2\"><RadioGroupItem id=\"${`${id}-${item.value}`}\" value=\"${item.value}\" class=\"after:absolute after:inset-0\" aria-describedby=\"${`${`${id}-${item.value}`}-price`}\" /><Label class=\"inline-flex items-start\" htmlfor=\"${`${id}-${item.value}`}\">${item.label}<!-- if item.value === '2' -->\n<Badge class=\"ms-2 -mt-1\">Popular</Badge>\n<!-- endif --></Label></div><div id=\"${`${`${id}-${item.value}`}-price`}\" class=\"text-muted-foreground text-xs leading-[inherit]\">${item.price}</div></div></div>\n<!-- End Loop --></RadioGroup></fieldset>\n</template>"
        },
        {
          "path": "registry/default/components/radio/radio-15.wxml",
          "target": "components/ui/radio-15/radio-15.wxml",
          "type": "registry:component",
          "content": "<view>\n  <fieldset class=\"space-y-4\"><legend class=\"text-foreground text-sm leading-none font-medium\">Choose plan</legend><radiogroup class=\"gap-0 -space-y-px rounded-md shadow-xs\" default-value=\"2\"><view wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{`${id}-${item.value}`}}\" class=\"border-input has-data-[state=checked]:border-primary/50 has-data-[state=checked]:bg-accent relative flex flex-col gap-4 border p-4 outline-none first:rounded-t-md last:rounded-b-md has-data-[state=checked]:z-10\"><view class=\"flex items-center justify-between\"><view class=\"flex items-center gap-2\"><radiogroupitem id=\"{{`${id}-${item.value}`}}\" value=\"{{item.value}}\" class=\"after:absolute after:inset-0\" aria-describedby=\"{{`${`${id}-${item.value}`}-price`}}\" /><label class=\"inline-flex items-start\" htmlfor=\"{{`${id}-${item.value}`}}\">{{ item.label }}<badge wx:if=\"{{item.value === '2'}}\" class=\"ms-2 -mt-1\">Popular</badge></label></view><view id=\"{{`${`${id}-${item.value}`}-price`}}\" class=\"text-muted-foreground text-xs leading-[inherit]\">{{ item.price }}</view></view></view></radiogroup></fieldset>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "radio",
          "label",
          "pricing",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "radio-15",
          "group": "radio",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "radio-15",
              "path": "registry/default/components/radio/radio-15.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "radio-15",
              "path": "registry/default/components/radio/radio-15.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "radio-15",
              "path": "registry/default/components/radio/radio-15.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "radio-15",
              "path": "registry/default/components/radio/radio-15.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "radio",
        "title": "Radio · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "radio"
      ]
    },
    {
      "name": "radio-17",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/radio-group.json"
      ],
      "files": [
        {
          "path": "registry/default/components/radio/radio-17.tsx",
          "type": "registry:component",
          "target": "components/ui/radio-17.tsx",
          "content": "import { useId } from 'react'\nimport { RadioGroup, RadioGroupItem } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n\n  const items = [\n    { value: '1', label: 'Angry', icon: '😠' },\n    { value: '2', label: 'Sad', icon: '🙁' },\n    { value: '3', label: 'Neutral', icon: '😐' },\n    { value: '4', label: 'Happy', icon: '🙂' },\n    { value: '5', label: 'Laughing', icon: '😀' },\n  ]\n\n  return (\n    <fieldset className=\"space-y-4\">\n      <legend className=\"text-foreground text-sm leading-none font-medium\">How did it go?</legend>\n      <RadioGroup className=\"flex gap-1.5\" defaultValue=\"3\">\n        {items.map((item) => (\n          <label\n            key={`${id}-${item.value}`}\n            className=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex size-9 cursor-pointer flex-col items-center justify-center rounded-full border text-center text-xl shadow-xs transition-[color,box-shadow] outline-none has-focus-visible:ring-[3px] has-data-disabled:cursor-not-allowed has-data-disabled:opacity-50\"\n          >\n            <RadioGroupItem\n              id={`${id}-${item.value}`}\n              value={item.value}\n              className=\"sr-only after:absolute after:inset-0\"\n            />\n            {item.icon}\n          </label>\n        ))}\n      </RadioGroup>\n    </fieldset>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/radio/radio-17.vue",
          "target": "components/ui/radio-17.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { RadioGroup } from '@timui/vue';\nimport { RadioGroupItem } from '@timui/vue';\n\n\n\n\n\nconst id = 'radio-17';\n\n\nconst items = [\n    { value: '1', label: 'Angry', icon: '😠' },\n    { value: '2', label: 'Sad', icon: '🙁' },\n    { value: '3', label: 'Neutral', icon: '😐' },\n    { value: '4', label: 'Happy', icon: '🙂' },\n    { value: '5', label: 'Laughing', icon: '😀' },\n  ]\n\n</script>\n\n<template>\n  <fieldset class=\"space-y-4\"><legend class=\"text-foreground text-sm leading-none font-medium\">How did it go?</legend><RadioGroup class=\"flex gap-1.5\" default-value=\"3\"><label v-for=\"(item, index) in items\" :key=\"`${id}-${item.value}`\" class=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex size-9 cursor-pointer flex-col items-center justify-center rounded-full border text-center text-xl shadow-xs transition-[color,box-shadow] outline-none has-focus-visible:ring-[3px] has-data-disabled:cursor-not-allowed has-data-disabled:opacity-50\"><RadioGroupItem :id=\"`${id}-${item.value}`\" :value=\"item.value\" class=\"sr-only after:absolute after:inset-0\" />{{ item.icon }}</label></RadioGroup></fieldset>\n</template>\n"
        },
        {
          "path": "registry/default/components/radio/radio-17.html",
          "target": "components/ui/radio-17.html",
          "type": "registry:component",
          "content": "<template>\n  <fieldset class=\"space-y-4\"><legend class=\"text-foreground text-sm leading-none font-medium\">How did it go?</legend><RadioGroup class=\"flex gap-1.5\" default-value=\"3\"><!-- Loop items -->\n<label key=\"${`${id}-${item.value}`}\" class=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex size-9 cursor-pointer flex-col items-center justify-center rounded-full border text-center text-xl shadow-xs transition-[color,box-shadow] outline-none has-focus-visible:ring-[3px] has-data-disabled:cursor-not-allowed has-data-disabled:opacity-50\"><RadioGroupItem id=\"${`${id}-${item.value}`}\" value=\"${item.value}\" class=\"sr-only after:absolute after:inset-0\" />${item.icon}</label>\n<!-- End Loop --></RadioGroup></fieldset>\n</template>"
        },
        {
          "path": "registry/default/components/radio/radio-17.wxml",
          "target": "components/ui/radio-17/radio-17.wxml",
          "type": "registry:component",
          "content": "<view>\n  <fieldset class=\"space-y-4\"><legend class=\"text-foreground text-sm leading-none font-medium\">How did it go?</legend><radiogroup class=\"flex gap-1.5\" default-value=\"3\"><label wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{`${id}-${item.value}`}}\" class=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex size-9 cursor-pointer flex-col items-center justify-center rounded-full border text-center text-xl shadow-xs transition-[color,box-shadow] outline-none has-focus-visible:ring-[3px] has-data-disabled:cursor-not-allowed has-data-disabled:opacity-50\"><radiogroupitem id=\"{{`${id}-${item.value}`}}\" value=\"{{item.value}}\" class=\"sr-only after:absolute after:inset-0\" />{{ item.icon }}</label></radiogroup></fieldset>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "radio",
          "label",
          "rating",
          "vote",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "radio-17",
          "group": "radio",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "radio-17",
              "path": "registry/default/components/radio/radio-17.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "radio-17",
              "path": "registry/default/components/radio/radio-17.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "radio-17",
              "path": "registry/default/components/radio/radio-17.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "radio-17",
              "path": "registry/default/components/radio/radio-17.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "radio",
        "title": "Radio · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "radio"
      ]
    },
    {
      "name": "radio-18",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/radio-group.json"
      ],
      "files": [
        {
          "path": "registry/default/components/radio/radio-18.tsx",
          "type": "registry:component",
          "target": "components/ui/radio-18.tsx",
          "content": "import { useId } from 'react'\nimport { RadioGroup, RadioGroupItem } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <>\n      <fieldset className=\"space-y-4\">\n        <legend className=\"text-foreground text-sm leading-none font-medium\">\n          How likely are you to recommend us?\n        </legend>\n        <RadioGroup className=\"flex gap-0 -space-x-px rounded-md shadow-xs\">\n          {['0', '1', '2', '3', '4', '5'].map((value) => (\n            <label\n              key={value}\n              className=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex size-9 flex-1 cursor-pointer flex-col items-center justify-center gap-3 border text-center text-sm font-medium transition-[color,box-shadow] outline-none first:rounded-s-md last:rounded-e-md has-focus-visible:ring-[3px] has-data-disabled:cursor-not-allowed has-data-disabled:opacity-50 has-data-[state=checked]:z-10\"\n            >\n              <RadioGroupItem\n                id={`${id}-${value}`}\n                value={value}\n                className=\"sr-only after:absolute after:inset-0\"\n              />\n              {value}\n            </label>\n          ))}\n        </RadioGroup>\n      </fieldset>\n      <div className=\"mt-1 flex justify-between text-xs font-medium\">\n        <p>\n          <span className=\"text-base\">😡</span> Not likely\n        </p>\n        <p>\n          Very Likely <span className=\"text-base\">😍</span>\n        </p>\n      </div>\n    </>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/radio/radio-18.vue",
          "target": "components/ui/radio-18.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { RadioGroup } from '@timui/vue';\nimport { RadioGroupItem } from '@timui/vue';\n\n\n\n\n\nconst id = 'radio-18';\n\n</script>\n\n<template>\n  <fieldset class=\"space-y-4\"><legend class=\"text-foreground text-sm leading-none font-medium\">How likely are you to recommend us?\n        </legend><RadioGroup class=\"flex gap-0 -space-x-px rounded-md shadow-xs\"><label v-for=\"(value, index) in ['0', '1', '2', '3', '4', '5']\" :key=\"value\" class=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex size-9 flex-1 cursor-pointer flex-col items-center justify-center gap-3 border text-center text-sm font-medium transition-[color,box-shadow] outline-none first:rounded-s-md last:rounded-e-md has-focus-visible:ring-[3px] has-data-disabled:cursor-not-allowed has-data-disabled:opacity-50 has-data-[state=checked]:z-10\"><RadioGroupItem :id=\"`${id}-${value}`\" :value=\"value\" class=\"sr-only after:absolute after:inset-0\" />{{ value }}</label></RadioGroup></fieldset><div class=\"mt-1 flex justify-between text-xs font-medium\"><p><span class=\"text-base\">😡</span>Not likely\n        </p><p>Very Likely <span class=\"text-base\">😍</span></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/radio/radio-18.html",
          "target": "components/ui/radio-18.html",
          "type": "registry:component",
          "content": "<template>\n  <fieldset class=\"space-y-4\"><legend class=\"text-foreground text-sm leading-none font-medium\">How likely are you to recommend us?\n        </legend><RadioGroup class=\"flex gap-0 -space-x-px rounded-md shadow-xs\"><!-- Loop ['0', '1', '2', '3', '4', '5'] -->\n<label key=\"${value}\" class=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex size-9 flex-1 cursor-pointer flex-col items-center justify-center gap-3 border text-center text-sm font-medium transition-[color,box-shadow] outline-none first:rounded-s-md last:rounded-e-md has-focus-visible:ring-[3px] has-data-disabled:cursor-not-allowed has-data-disabled:opacity-50 has-data-[state=checked]:z-10\"><RadioGroupItem id=\"${`${id}-${value}`}\" value=\"${value}\" class=\"sr-only after:absolute after:inset-0\" />${value}</label>\n<!-- End Loop --></RadioGroup></fieldset><div class=\"mt-1 flex justify-between text-xs font-medium\"><p><span class=\"text-base\">😡</span>Not likely\n        </p><p>Very Likely <span class=\"text-base\">😍</span></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/radio/radio-18.wxml",
          "target": "components/ui/radio-18/radio-18.wxml",
          "type": "registry:component",
          "content": "<view>\n  <fieldset class=\"space-y-4\"><legend class=\"text-foreground text-sm leading-none font-medium\">How likely are you to recommend us?\n        </legend><radiogroup class=\"flex gap-0 -space-x-px rounded-md shadow-xs\"><label wx:for=\"{{['0', '1', '2', '3', '4', '5']}}\" wx:for-item=\"value\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{value}}\" class=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex size-9 flex-1 cursor-pointer flex-col items-center justify-center gap-3 border text-center text-sm font-medium transition-[color,box-shadow] outline-none first:rounded-s-md last:rounded-e-md has-focus-visible:ring-[3px] has-data-disabled:cursor-not-allowed has-data-disabled:opacity-50 has-data-[state=checked]:z-10\"><radiogroupitem id=\"{{`${id}-${value}`}}\" value=\"{{value}}\" class=\"sr-only after:absolute after:inset-0\" />{{ value }}</label></radiogroup></fieldset><view class=\"mt-1 flex justify-between text-xs font-medium\"><text><text class=\"text-base\">😡</text>Not likely\n        </text><text>Very Likely <text class=\"text-base\">😍</text></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "radio",
          "label",
          "rating",
          "vote",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "radio-18",
          "group": "radio",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "radio-18",
              "path": "registry/default/components/radio/radio-18.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "radio-18",
              "path": "registry/default/components/radio/radio-18.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "radio-18",
              "path": "registry/default/components/radio/radio-18.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "radio-18",
              "path": "registry/default/components/radio/radio-18.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "radio",
        "title": "Radio · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "radio"
      ]
    },
    {
      "name": "radio-19",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/radio-group.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/radio/radio-19.tsx",
          "type": "registry:component",
          "target": "components/ui/radio-19.tsx",
          "content": "import { useId } from 'react'\nimport { RadioGroup, RadioGroupItem } from '@timui/react'\nimport { CheckIcon, MinusIcon } from 'lucide-react'\n\nconst items = [\n  { value: '1', label: 'Light', image: '/ui-light.png' },\n  { value: '2', label: 'Dark', image: '/ui-dark.png' },\n  { value: '3', label: 'System', image: '/ui-system.png' },\n]\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <fieldset className=\"space-y-4\">\n      <legend className=\"text-foreground text-sm leading-none font-medium\">Choose a theme</legend>\n      <RadioGroup className=\"flex gap-3\" defaultValue=\"1\">\n        {items.map((item) => (\n          <label key={`${id}-${item.value}`}>\n            <RadioGroupItem\n              id={`${id}-${item.value}`}\n              value={item.value}\n              className=\"peer sr-only after:absolute after:inset-0\"\n            />\n            <img\n              src={item.image}\n              alt={item.label}\n              width={88}\n              height={70}\n              className=\"border-input peer-focus-visible:ring-ring/50 peer-data-[state=checked]:border-ring peer-data-[state=checked]:bg-accent relative cursor-pointer overflow-hidden rounded-md border shadow-xs transition-[color,box-shadow] outline-none peer-focus-visible:ring-[3px] peer-data-disabled:cursor-not-allowed peer-data-disabled:opacity-50\"\n            />\n            <span className=\"group peer-data-[state=unchecked]:text-muted-foreground/70 mt-2 flex items-center gap-1\">\n              <CheckIcon\n                size={16}\n                className=\"group-peer-data-[state=unchecked]:hidden\"\n                aria-hidden=\"true\"\n              />\n              <MinusIcon\n                size={16}\n                className=\"group-peer-data-[state=checked]:hidden\"\n                aria-hidden=\"true\"\n              />\n              <span className=\"text-xs font-medium\">{item.label}</span>\n            </span>\n          </label>\n        ))}\n      </RadioGroup>\n    </fieldset>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/radio/radio-19.vue",
          "target": "components/ui/radio-19.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { CheckIcon, MinusIcon } from 'lucide-vue-next';\nimport { RadioGroup } from '@timui/vue';\nimport { RadioGroupItem } from '@timui/vue';\n\n\n\n\n\nconst id = 'radio-19';\n\n\nconst items = [\n  { value: '1', label: 'Light', image: '/ui-light.png' },\n  { value: '2', label: 'Dark', image: '/ui-dark.png' },\n  { value: '3', label: 'System', image: '/ui-system.png' },\n]\n\n</script>\n\n<template>\n  <fieldset class=\"space-y-4\"><legend class=\"text-foreground text-sm leading-none font-medium\">Choose a theme</legend><RadioGroup class=\"flex gap-3\" default-value=\"1\"><label v-for=\"(item, index) in items\" :key=\"`${id}-${item.value}`\"><RadioGroupItem :id=\"`${id}-${item.value}`\" :value=\"item.value\" class=\"peer sr-only after:absolute after:inset-0\" /><img :src=\"item.image\" :alt=\"item.label\" :width=\"88\" :height=\"70\" class=\"border-input peer-focus-visible:ring-ring/50 peer-data-[state=checked]:border-ring peer-data-[state=checked]:bg-accent relative cursor-pointer overflow-hidden rounded-md border shadow-xs transition-[color,box-shadow] outline-none peer-focus-visible:ring-[3px] peer-data-disabled:cursor-not-allowed peer-data-disabled:opacity-50\" /><span class=\"group peer-data-[state=unchecked]:text-muted-foreground/70 mt-2 flex items-center gap-1\"><CheckIcon :size=\"16\" class=\"group-peer-data-[state=unchecked]:hidden\" aria-hidden=\"true\" /><MinusIcon :size=\"16\" class=\"group-peer-data-[state=checked]:hidden\" aria-hidden=\"true\" /><span class=\"text-xs font-medium\">{{ item.label }}</span></span></label></RadioGroup></fieldset>\n</template>\n"
        },
        {
          "path": "registry/default/components/radio/radio-19.html",
          "target": "components/ui/radio-19.html",
          "type": "registry:component",
          "content": "<template>\n  <fieldset class=\"space-y-4\"><legend class=\"text-foreground text-sm leading-none font-medium\">Choose a theme</legend><RadioGroup class=\"flex gap-3\" default-value=\"1\"><!-- Loop items -->\n<label key=\"${`${id}-${item.value}`}\"><RadioGroupItem id=\"${`${id}-${item.value}`}\" value=\"${item.value}\" class=\"peer sr-only after:absolute after:inset-0\" /><img src=\"${item.image}\" alt=\"${item.label}\" width=\"${88}\" height=\"${70}\" class=\"border-input peer-focus-visible:ring-ring/50 peer-data-[state=checked]:border-ring peer-data-[state=checked]:bg-accent relative cursor-pointer overflow-hidden rounded-md border shadow-xs transition-[color,box-shadow] outline-none peer-focus-visible:ring-[3px] peer-data-disabled:cursor-not-allowed peer-data-disabled:opacity-50\" /><span class=\"group peer-data-[state=unchecked]:text-muted-foreground/70 mt-2 flex items-center gap-1\"><CheckIcon size=\"${16}\" class=\"group-peer-data-[state=unchecked]:hidden\" aria-hidden=\"true\" /><MinusIcon size=\"${16}\" class=\"group-peer-data-[state=checked]:hidden\" aria-hidden=\"true\" /><span class=\"text-xs font-medium\">${item.label}</span></span></label>\n<!-- End Loop --></RadioGroup></fieldset>\n</template>"
        },
        {
          "path": "registry/default/components/radio/radio-19.wxml",
          "target": "components/ui/radio-19/radio-19.wxml",
          "type": "registry:component",
          "content": "<view>\n  <fieldset class=\"space-y-4\"><legend class=\"text-foreground text-sm leading-none font-medium\">Choose a theme</legend><radiogroup class=\"flex gap-3\" default-value=\"1\"><label wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{`${id}-${item.value}`}}\"><radiogroupitem id=\"{{`${id}-${item.value}`}}\" value=\"{{item.value}}\" class=\"peer sr-only after:absolute after:inset-0\" /><image src=\"{{item.image}}\" alt=\"{{item.label}}\" width=\"{{88}}\" height=\"{{70}}\" class=\"border-input peer-focus-visible:ring-ring/50 peer-data-[state=checked]:border-ring peer-data-[state=checked]:bg-accent relative cursor-pointer overflow-hidden rounded-md border shadow-xs transition-[color,box-shadow] outline-none peer-focus-visible:ring-[3px] peer-data-disabled:cursor-not-allowed peer-data-disabled:opacity-50\" /><text class=\"group peer-data-[state=unchecked]:text-muted-foreground/70 mt-2 flex items-center gap-1\"><checkicon size=\"{{16}}\" class=\"group-peer-data-[state=unchecked]:hidden\" aria-hidden=\"true\" /><minusicon size=\"{{16}}\" class=\"group-peer-data-[state=checked]:hidden\" aria-hidden=\"true\" /><text class=\"text-xs font-medium\">{{ item.label }}</text></text></label></radiogroup></fieldset>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "radio",
          "label",
          "darkmode",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "radio-19",
          "group": "radio",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "radio-19",
              "path": "registry/default/components/radio/radio-19.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "radio-19",
              "path": "registry/default/components/radio/radio-19.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "radio-19",
              "path": "registry/default/components/radio/radio-19.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "radio-19",
              "path": "registry/default/components/radio/radio-19.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "radio",
        "title": "Radio · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "radio"
      ]
    },
    {
      "name": "radio-20",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/radio-group.json"
      ],
      "files": [
        {
          "path": "registry/default/components/radio/radio-20.tsx",
          "type": "registry:component",
          "target": "components/ui/radio-20.tsx",
          "content": "'use client'\n\nimport { useId, useState } from 'react'\nimport { RadioGroup, RadioGroupItem } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  const [selectedValue, setSelectedValue] = useState('on')\n\n  return (\n    <div className=\"bg-input/50 inline-flex h-9 rounded-md p-0.5\">\n      <RadioGroup\n        value={selectedValue}\n        onValueChange={setSelectedValue}\n        className=\"group after:bg-background has-focus-visible:after:border-ring has-focus-visible:after:ring-ring/50 relative inline-grid grid-cols-[1fr_1fr] items-center gap-0 text-sm font-medium after:absolute after:inset-y-0 after:w-1/2 after:rounded-sm after:shadow-xs after:transition-[translate,box-shadow] after:duration-300 after:ease-[cubic-bezier(0.16,1,0.3,1)] has-focus-visible:after:ring-[3px] data-[state=off]:after:translate-x-0 data-[state=on]:after:translate-x-full\"\n        data-state={selectedValue}\n      >\n        <label className=\"group-data-[state=on]:text-muted-foreground/70 relative z-10 inline-flex h-full min-w-8 cursor-pointer items-center justify-center px-4 whitespace-nowrap transition-colors select-none\">\n          Bill Monthly\n          <RadioGroupItem id={`${id}-1`} value=\"off\" className=\"sr-only\" />\n        </label>\n        <label className=\"group-data-[state=off]:text-muted-foreground/70 relative z-10 inline-flex h-full min-w-8 cursor-pointer items-center justify-center px-4 whitespace-nowrap transition-colors select-none\">\n          <span>\n            Bill Yearly{' '}\n            <span className=\"group-data-[state=off]:text-muted-foreground/70 transition-colors group-data-[state=on]:text-emerald-500\">\n              -20%\n            </span>\n          </span>\n          <RadioGroupItem id={`${id}-2`} value=\"on\" className=\"sr-only\" />\n        </label>\n      </RadioGroup>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/radio/radio-20.vue",
          "target": "components/ui/radio-20.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { RadioGroup } from '@timui/vue';\nimport { RadioGroupItem } from '@timui/vue';\n\n\n\nconst selectedValue = ref('on');\n\n\nconst id = 'radio-20';\n\n\nfunction setSelectedValue(next: typeof selectedValue.value | ((prev: typeof selectedValue.value) => typeof selectedValue.value)) {\n  selectedValue.value = typeof next === 'function'\n    ? (next as (prev: typeof selectedValue.value) => typeof selectedValue.value)(selectedValue.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <div class=\"bg-input/50 inline-flex h-9 rounded-md p-0.5\"><RadioGroup :value=\"selectedValue\" @update:modelValue=\"setSelectedValue\" class=\"group after:bg-background has-focus-visible:after:border-ring has-focus-visible:after:ring-ring/50 relative inline-grid grid-cols-[1fr_1fr] items-center gap-0 text-sm font-medium after:absolute after:inset-y-0 after:w-1/2 after:rounded-sm after:shadow-xs after:transition-[translate,box-shadow] after:duration-300 after:ease-[cubic-bezier(0.16,1,0.3,1)] has-focus-visible:after:ring-[3px] data-[state=off]:after:translate-x-0 data-[state=on]:after:translate-x-full\" :data-state=\"selectedValue\"><label class=\"group-data-[state=on]:text-muted-foreground/70 relative z-10 inline-flex h-full min-w-8 cursor-pointer items-center justify-center px-4 whitespace-nowrap transition-colors select-none\">Bill Monthly\n          <RadioGroupItem :id=\"`${id}-1`\" value=\"off\" class=\"sr-only\" /></label><label class=\"group-data-[state=off]:text-muted-foreground/70 relative z-10 inline-flex h-full min-w-8 cursor-pointer items-center justify-center px-4 whitespace-nowrap transition-colors select-none\"><span>Bill Yearly{{ ' ' }}<span class=\"group-data-[state=off]:text-muted-foreground/70 transition-colors group-data-[state=on]:text-emerald-500\">-20%\n            </span></span><RadioGroupItem :id=\"`${id}-2`\" value=\"on\" class=\"sr-only\" /></label></RadioGroup></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/radio/radio-20.html",
          "target": "components/ui/radio-20.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"bg-input/50 inline-flex h-9 rounded-md p-0.5\"><RadioGroup value=\"${selectedValue}\" on-value-change=\"${setSelectedValue}\" class=\"group after:bg-background has-focus-visible:after:border-ring has-focus-visible:after:ring-ring/50 relative inline-grid grid-cols-[1fr_1fr] items-center gap-0 text-sm font-medium after:absolute after:inset-y-0 after:w-1/2 after:rounded-sm after:shadow-xs after:transition-[translate,box-shadow] after:duration-300 after:ease-[cubic-bezier(0.16,1,0.3,1)] has-focus-visible:after:ring-[3px] data-[state=off]:after:translate-x-0 data-[state=on]:after:translate-x-full\" data-state=\"${selectedValue}\"><label class=\"group-data-[state=on]:text-muted-foreground/70 relative z-10 inline-flex h-full min-w-8 cursor-pointer items-center justify-center px-4 whitespace-nowrap transition-colors select-none\">Bill Monthly\n          <RadioGroupItem id=\"${`${id}-1`}\" value=\"off\" class=\"sr-only\" /></label><label class=\"group-data-[state=off]:text-muted-foreground/70 relative z-10 inline-flex h-full min-w-8 cursor-pointer items-center justify-center px-4 whitespace-nowrap transition-colors select-none\"><span>Bill Yearly${' '}<span class=\"group-data-[state=off]:text-muted-foreground/70 transition-colors group-data-[state=on]:text-emerald-500\">-20%\n            </span></span><RadioGroupItem id=\"${`${id}-2`}\" value=\"on\" class=\"sr-only\" /></label></RadioGroup></div>\n</template>"
        },
        {
          "path": "registry/default/components/radio/radio-20.wxml",
          "target": "components/ui/radio-20/radio-20.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"bg-input/50 inline-flex h-9 rounded-md p-0.5\"><radiogroup value=\"{{selectedValue}}\" bindchange=\"setSelectedValue\" class=\"group after:bg-background has-focus-visible:after:border-ring has-focus-visible:after:ring-ring/50 relative inline-grid grid-cols-[1fr_1fr] items-center gap-0 text-sm font-medium after:absolute after:inset-y-0 after:w-1/2 after:rounded-sm after:shadow-xs after:transition-[translate,box-shadow] after:duration-300 after:ease-[cubic-bezier(0.16,1,0.3,1)] has-focus-visible:after:ring-[3px] data-[state=off]:after:translate-x-0 data-[state=on]:after:translate-x-full\" data-state=\"{{selectedValue}}\"><label class=\"group-data-[state=on]:text-muted-foreground/70 relative z-10 inline-flex h-full min-w-8 cursor-pointer items-center justify-center px-4 whitespace-nowrap transition-colors select-none\">Bill Monthly\n          <radiogroupitem id=\"{{`${id}-1`}}\" value=\"off\" class=\"sr-only\" /></label><label class=\"group-data-[state=off]:text-muted-foreground/70 relative z-10 inline-flex h-full min-w-8 cursor-pointer items-center justify-center px-4 whitespace-nowrap transition-colors select-none\"><text>Bill Yearly{{ ' ' }}<text class=\"group-data-[state=off]:text-muted-foreground/70 transition-colors group-data-[state=on]:text-emerald-500\">-20%\n            </text></text><radiogroupitem id=\"{{`${id}-2`}}\" value=\"on\" class=\"sr-only\" /></label></radiogroup></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "radio",
          "label",
          "pricing",
          "switch",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "radio-20",
          "group": "radio",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "radio-20",
              "path": "registry/default/components/radio/radio-20.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "radio-20",
              "path": "registry/default/components/radio/radio-20.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "radio-20",
              "path": "registry/default/components/radio/radio-20.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "radio-20",
              "path": "registry/default/components/radio/radio-20.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "radio",
        "title": "Radio · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "radio"
      ]
    },
    {
      "name": "radio-16",
      "type": "registry:component",
      "dependencies": [
        "@remixicon/react",
        "@timui/react"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/radio-group.json"
      ],
      "files": [
        {
          "path": "registry/default/components/radio/radio-16.tsx",
          "type": "registry:component",
          "target": "components/ui/radio-16.tsx",
          "content": "'use client'\n\nimport { useId, useState } from 'react'\nimport { RiStarFill } from '@remixicon/react'\nimport { RadioGroup, RadioGroupItem } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  const [hoverRating, setHoverRating] = useState('')\n  const [currentRating, setCurrentRating] = useState('')\n\n  return (\n    <fieldset className=\"space-y-4\">\n      <legend className=\"text-foreground text-sm leading-none font-medium\">\n        Rate your experience\n      </legend>\n      <RadioGroup className=\"inline-flex gap-0\" onValueChange={setCurrentRating}>\n        {['1', '2', '3', '4', '5'].map((value) => (\n          <label\n            key={value}\n            className=\"group has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative cursor-pointer rounded p-0.5 outline-none has-focus-visible:ring-[3px]\"\n            onMouseEnter={() => setHoverRating(value)}\n            onMouseLeave={() => setHoverRating('')}\n          >\n            <RadioGroupItem id={`${id}-${value}`} value={value} className=\"sr-only\" />\n            <RiStarFill\n              size={24}\n              className={`transition-all ${\n                (hoverRating || currentRating) >= value ? 'text-amber-500' : 'text-input'\n              } group-hover:scale-110`}\n            />\n            <span className=\"sr-only\">\n              {value} star{value === '1' ? '' : 's'}\n            </span>\n          </label>\n        ))}\n      </RadioGroup>\n    </fieldset>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/radio/radio-16.vue",
          "target": "components/ui/radio-16.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { StarIcon } from 'lucide-vue-next'\nimport { RadioGroup } from '@timui/vue'\nimport { RadioGroupItem } from '@timui/vue'\n\nconst hoverRating = ref('')\nconst currentRating = ref('')\nconst id = 'radio-16'\n\nconst setHoverRating = (next: string) => {\n  hoverRating.value = next\n}\n\nconst setCurrentRating = (next?: string) => {\n  currentRating.value = next ?? ''\n}\n</script>\n\n<template>\n  <fieldset class=\"space-y-4\">\n    <legend class=\"text-foreground text-sm leading-none font-medium\">Rate your experience</legend>\n    <RadioGroup class=\"inline-flex gap-0\" @update:modelValue=\"setCurrentRating\">\n      <label\n        v-for=\"value in ['1', '2', '3', '4', '5']\"\n        :key=\"value\"\n        class=\"group has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative cursor-pointer rounded p-0.5 outline-none has-focus-visible:ring-[3px]\"\n        @mouseenter=\"setHoverRating(value)\"\n        @mouseleave=\"setHoverRating('')\"\n      >\n        <RadioGroupItem :id=\"`${id}-${value}`\" :value=\"value\" class=\"sr-only\" />\n        <StarIcon\n          :size=\"24\"\n          class=\"fill-current transition-all group-hover:scale-110\"\n          :class=\"(hoverRating || currentRating) >= value ? 'text-amber-500' : 'text-input'\"\n        />\n        <span class=\"sr-only\">{{ value }} star{{ value === '1' ? '' : 's' }}</span>\n      </label>\n    </RadioGroup>\n  </fieldset>\n</template>\n"
        },
        {
          "path": "registry/default/components/radio/radio-16.html",
          "target": "components/ui/radio-16.html",
          "type": "registry:component",
          "content": "<template>\n  <fieldset class=\"space-y-4\"><legend class=\"text-foreground text-sm leading-none font-medium\">Rate your experience\n      </legend><RadioGroup class=\"inline-flex gap-0\" on-value-change=\"${setCurrentRating}\"><!-- Loop ['1', '2', '3', '4', '5'] -->\n<label key=\"${value}\" class=\"group has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative cursor-pointer rounded p-0.5 outline-none has-focus-visible:ring-[3px]\" onmouseenter=\"${() => setHoverRating(value)}\" onmouseleave=\"${() => setHoverRating('')}\"><RadioGroupItem id=\"${`${id}-${value}`}\" value=\"${value}\" class=\"sr-only\" /><RiStarFill size=\"${24}\" class=\"${`transition-all ${\n                (hoverRating || currentRating) >= value ? 'text-amber-500' : 'text-input'\n              } group-hover:scale-110`}\" /><span class=\"sr-only\">${value}star<!-- if value === '1' -->\n${''}\n<!-- else -->\n${'s'}\n<!-- endif --></span></label>\n<!-- End Loop --></RadioGroup></fieldset>\n</template>"
        },
        {
          "path": "registry/default/components/radio/radio-16.wxml",
          "target": "components/ui/radio-16/radio-16.wxml",
          "type": "registry:component",
          "content": "<view>\n  <fieldset class=\"space-y-4\"><legend class=\"text-foreground text-sm leading-none font-medium\">Rate your experience\n      </legend><radiogroup class=\"inline-flex gap-0\" bindchange=\"setCurrentRating\"><label wx:for=\"{{['1', '2', '3', '4', '5']}}\" wx:for-item=\"value\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{value}}\" class=\"group has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative cursor-pointer rounded p-0.5 outline-none has-focus-visible:ring-[3px]\" onmouseenter=\"{{() => setHoverRating(value)}}\" onmouseleave=\"{{() => setHoverRating('')}}\"><radiogroupitem id=\"{{`${id}-${value}`}}\" value=\"{{value}}\" class=\"sr-only\" /><ristarfill size=\"{{24}}\" class=\"{{`transition-all ${\n                (hoverRating || currentRating) >= value ? 'text-amber-500' : 'text-input'\n              } group-hover:scale-110`}}\" /><text class=\"sr-only\">{{ value }}star<block wx:if=\"{{value === '1'}}\">\n{{ '' }}\n</block>\n<block wx:else>\n{{ 's' }}\n</block></text></label></radiogroup></fieldset>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "radio",
          "label",
          "rating",
          "vote",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "radio-16",
          "group": "radio",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "radio-16",
              "path": "registry/default/components/radio/radio-16.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "radio-16",
              "path": "registry/default/components/radio/radio-16.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "radio-16",
              "path": "registry/default/components/radio/radio-16.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "radio-16",
              "path": "registry/default/components/radio/radio-16.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@remixicon/react",
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "radio",
        "title": "Radio · With label"
      },
      "categories": [
        "radio"
      ]
    },
    {
      "name": "switch-01",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/switch.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/switch/switch-01.tsx",
          "type": "registry:component",
          "target": "components/ui/switch-01.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Switch } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"inline-flex items-center gap-2\">\n      <Switch id={id} />\n      <Label htmlFor={id} className=\"sr-only\">\n        Simple switch\n      </Label>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/switch/switch-01.vue",
          "target": "components/ui/switch-01.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Switch } from '@timui/vue';\n\n\n\n\n\nconst id = 'switch-01';\n\n</script>\n\n<template>\n  <div class=\"inline-flex items-center gap-2\"><Switch :id=\"id\" /><Label :htmlFor=\"id\" class=\"sr-only\">Simple switch\n      </Label></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/switch/switch-01.html",
          "target": "components/ui/switch-01.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"inline-flex items-center gap-2\"><Switch id=\"${id}\" /><Label htmlfor=\"${id}\" class=\"sr-only\">Simple switch\n      </Label></div>\n</template>"
        },
        {
          "path": "registry/default/components/switch/switch-01.wxml",
          "target": "components/ui/switch-01/switch-01.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"inline-flex items-center gap-2\"><switch id=\"{{id}}\" /><label htmlfor=\"{{id}}\" class=\"sr-only\">Simple switch\n      </label></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "switch",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "switch-01",
          "group": "switch",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "switch-01",
              "path": "registry/default/components/switch/switch-01.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "switch-01",
              "path": "registry/default/components/switch/switch-01.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "switch-01",
              "path": "registry/default/components/switch/switch-01.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "switch-01",
              "path": "registry/default/components/switch/switch-01.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "switch",
        "title": "Switch · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "switch"
      ]
    },
    {
      "name": "switch-02",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/switch.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/switch/switch-02.tsx",
          "type": "registry:component",
          "target": "components/ui/switch-02.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Switch } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"inline-flex items-center gap-2\">\n      <Switch\n        id={id}\n        className=\"h-5 w-8 [&_span]:size-4 data-[state=checked]:[&_span]:translate-x-3 data-[state=checked]:[&_span]:rtl:-translate-x-3\"\n      />\n      <Label htmlFor={id} className=\"sr-only\">\n        Small switch\n      </Label>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/switch/switch-02.vue",
          "target": "components/ui/switch-02.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Switch } from '@timui/vue';\n\n\n\n\n\nconst id = 'switch-02';\n\n</script>\n\n<template>\n  <div class=\"inline-flex items-center gap-2\"><Switch :id=\"id\" class=\"h-5 w-8 [&_span]:size-4 data-[state=checked]:[&_span]:translate-x-3 data-[state=checked]:[&_span]:rtl:-translate-x-3\" /><Label :htmlFor=\"id\" class=\"sr-only\">Small switch\n      </Label></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/switch/switch-02.html",
          "target": "components/ui/switch-02.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"inline-flex items-center gap-2\"><Switch id=\"${id}\" class=\"h-5 w-8 [&_span]:size-4 data-[state=checked]:[&_span]:translate-x-3 data-[state=checked]:[&_span]:rtl:-translate-x-3\" /><Label htmlfor=\"${id}\" class=\"sr-only\">Small switch\n      </Label></div>\n</template>"
        },
        {
          "path": "registry/default/components/switch/switch-02.wxml",
          "target": "components/ui/switch-02/switch-02.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"inline-flex items-center gap-2\"><switch id=\"{{id}}\" class=\"h-5 w-8 [&_span]:size-4 data-[state=checked]:[&_span]:translate-x-3 data-[state=checked]:[&_span]:rtl:-translate-x-3\" /><label htmlfor=\"{{id}}\" class=\"sr-only\">Small switch\n      </label></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "switch",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "switch-02",
          "group": "switch",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "switch-02",
              "path": "registry/default/components/switch/switch-02.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "switch-02",
              "path": "registry/default/components/switch/switch-02.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "switch-02",
              "path": "registry/default/components/switch/switch-02.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "switch-02",
              "path": "registry/default/components/switch/switch-02.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "switch",
        "title": "Switch · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "switch"
      ]
    },
    {
      "name": "switch-03",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/switch.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/switch/switch-03.tsx",
          "type": "registry:component",
          "target": "components/ui/switch-03.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Switch } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"inline-flex items-center gap-2 [--primary:var(--color-indigo-500)] [--ring:var(--color-indigo-300)] in-[.dark]:[--primary:var(--color-indigo-500)] in-[.dark]:[--ring:var(--color-indigo-900)]\">\n      <Switch id={id} defaultChecked />\n      <Label htmlFor={id} className=\"sr-only\">\n        Colored switch\n      </Label>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/switch/switch-03.vue",
          "target": "components/ui/switch-03.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Switch } from '@timui/vue';\n\n\n\n\n\nconst id = 'switch-03';\n\n</script>\n\n<template>\n  <div class=\"inline-flex items-center gap-2 [--primary:var(--color-indigo-500)] [--ring:var(--color-indigo-300)] in-[.dark]:[--primary:var(--color-indigo-500)] in-[.dark]:[--ring:var(--color-indigo-900)]\"><Switch :id=\"id\" defaultChecked /><Label :htmlFor=\"id\" class=\"sr-only\">Colored switch\n      </Label></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/switch/switch-03.html",
          "target": "components/ui/switch-03.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"inline-flex items-center gap-2 [--primary:var(--color-indigo-500)] [--ring:var(--color-indigo-300)] in-[.dark]:[--primary:var(--color-indigo-500)] in-[.dark]:[--ring:var(--color-indigo-900)]\"><Switch id=\"${id}\" defaultchecked /><Label htmlfor=\"${id}\" class=\"sr-only\">Colored switch\n      </Label></div>\n</template>"
        },
        {
          "path": "registry/default/components/switch/switch-03.wxml",
          "target": "components/ui/switch-03/switch-03.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"inline-flex items-center gap-2 [--primary:var(--color-indigo-500)] [--ring:var(--color-indigo-300)] in-[.dark]:[--primary:var(--color-indigo-500)] in-[.dark]:[--ring:var(--color-indigo-900)]\"><switch id=\"{{id}}\" defaultchecked /><label htmlfor=\"{{id}}\" class=\"sr-only\">Colored switch\n      </label></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "switch",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "switch-03",
          "group": "switch",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "switch-03",
              "path": "registry/default/components/switch/switch-03.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "switch-03",
              "path": "registry/default/components/switch/switch-03.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "switch-03",
              "path": "registry/default/components/switch/switch-03.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "switch-03",
              "path": "registry/default/components/switch/switch-03.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "switch",
        "title": "Switch · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "switch"
      ]
    },
    {
      "name": "switch-04",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/switch.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/switch/switch-04.tsx",
          "type": "registry:component",
          "target": "components/ui/switch-04.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Switch } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"inline-flex items-center gap-2\">\n      <Switch id={id} disabled />\n      <Label htmlFor={id} className=\"sr-only\">\n        Disabled\n      </Label>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/switch/switch-04.vue",
          "target": "components/ui/switch-04.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Switch } from '@timui/vue';\n\n\n\n\n\nconst id = 'switch-04';\n\n</script>\n\n<template>\n  <div class=\"inline-flex items-center gap-2\"><Switch :id=\"id\" disabled /><Label :htmlFor=\"id\" class=\"sr-only\">Disabled\n      </Label></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/switch/switch-04.html",
          "target": "components/ui/switch-04.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"inline-flex items-center gap-2\"><Switch id=\"${id}\" disabled /><Label htmlfor=\"${id}\" class=\"sr-only\">Disabled\n      </Label></div>\n</template>"
        },
        {
          "path": "registry/default/components/switch/switch-04.wxml",
          "target": "components/ui/switch-04/switch-04.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"inline-flex items-center gap-2\"><switch id=\"{{id}}\" disabled /><label htmlfor=\"{{id}}\" class=\"sr-only\">Disabled\n      </label></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "switch",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "switch-04",
          "group": "switch",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "switch-04",
              "path": "registry/default/components/switch/switch-04.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "switch-04",
              "path": "registry/default/components/switch/switch-04.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "switch-04",
              "path": "registry/default/components/switch/switch-04.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "switch-04",
              "path": "registry/default/components/switch/switch-04.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "switch",
        "title": "Switch · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "switch"
      ]
    },
    {
      "name": "switch-05",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/switch.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/switch/switch-05.tsx",
          "type": "registry:component",
          "target": "components/ui/switch-05.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Switch } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"inline-flex items-center gap-2\">\n      <Switch id={id} className=\"rounded-sm [&_span]:rounded\" />\n      <Label htmlFor={id} className=\"sr-only\">\n        Square switch\n      </Label>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/switch/switch-05.vue",
          "target": "components/ui/switch-05.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Switch } from '@timui/vue';\n\n\n\n\n\nconst id = 'switch-05';\n\n</script>\n\n<template>\n  <div class=\"inline-flex items-center gap-2\"><Switch :id=\"id\" class=\"rounded-sm [&_span]:rounded\" /><Label :htmlFor=\"id\" class=\"sr-only\">Square switch\n      </Label></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/switch/switch-05.html",
          "target": "components/ui/switch-05.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"inline-flex items-center gap-2\"><Switch id=\"${id}\" class=\"rounded-sm [&_span]:rounded\" /><Label htmlfor=\"${id}\" class=\"sr-only\">Square switch\n      </Label></div>\n</template>"
        },
        {
          "path": "registry/default/components/switch/switch-05.wxml",
          "target": "components/ui/switch-05/switch-05.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"inline-flex items-center gap-2\"><switch id=\"{{id}}\" class=\"rounded-sm [&_span]:rounded\" /><label htmlfor=\"{{id}}\" class=\"sr-only\">Square switch\n      </label></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "switch",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "switch-05",
          "group": "switch",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "switch-05",
              "path": "registry/default/components/switch/switch-05.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "switch-05",
              "path": "registry/default/components/switch/switch-05.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "switch-05",
              "path": "registry/default/components/switch/switch-05.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "switch-05",
              "path": "registry/default/components/switch/switch-05.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "switch",
        "title": "Switch · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "switch"
      ]
    },
    {
      "name": "switch-06",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/switch.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/switch/switch-06.tsx",
          "type": "registry:component",
          "target": "components/ui/switch-06.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Switch } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"inline-flex items-center gap-2\">\n      <Switch\n        id={id}\n        className=\"[&_span]:border-input h-3 w-9 border-none outline-offset-[6px] [&_span]:border\"\n      />\n      <Label htmlFor={id} className=\"sr-only\">\n        M2-style switch\n      </Label>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/switch/switch-06.vue",
          "target": "components/ui/switch-06.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Switch } from '@timui/vue';\n\n\n\n\n\nconst id = 'switch-06';\n\n</script>\n\n<template>\n  <div class=\"inline-flex items-center gap-2\"><Switch :id=\"id\" class=\"[&_span]:border-input h-3 w-9 border-none outline-offset-[6px] [&_span]:border\" /><Label :htmlFor=\"id\" class=\"sr-only\">M2-style switch\n      </Label></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/switch/switch-06.html",
          "target": "components/ui/switch-06.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"inline-flex items-center gap-2\"><Switch id=\"${id}\" class=\"[&_span]:border-input h-3 w-9 border-none outline-offset-[6px] [&_span]:border\" /><Label htmlfor=\"${id}\" class=\"sr-only\">M2-style switch\n      </Label></div>\n</template>"
        },
        {
          "path": "registry/default/components/switch/switch-06.wxml",
          "target": "components/ui/switch-06/switch-06.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"inline-flex items-center gap-2\"><switch id=\"{{id}}\" class=\"[&_span]:border-input h-3 w-9 border-none outline-offset-[6px] [&_span]:border\" /><label htmlfor=\"{{id}}\" class=\"sr-only\">M2-style switch\n      </label></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "switch",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "switch-06",
          "group": "switch",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "switch-06",
              "path": "registry/default/components/switch/switch-06.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "switch-06",
              "path": "registry/default/components/switch/switch-06.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "switch-06",
              "path": "registry/default/components/switch/switch-06.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "switch-06",
              "path": "registry/default/components/switch/switch-06.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "switch",
        "title": "Switch · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "switch"
      ]
    },
    {
      "name": "switch-07",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/switch.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/switch/switch-07.tsx",
          "type": "registry:component",
          "target": "components/ui/switch-07.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Switch } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"inline-flex items-center gap-2\">\n      <Switch\n        id={id}\n        className=\"data-[state=unchecked]:border-input data-[state=unchecked]:[&_span]:bg-input data-[state=unchecked]:bg-transparent [&_span]:transition-all data-[state=unchecked]:[&_span]:size-4 data-[state=unchecked]:[&_span]:translate-x-0.5 data-[state=unchecked]:[&_span]:shadow-none data-[state=unchecked]:[&_span]:rtl:-translate-x-0.5\"\n      />\n      <Label htmlFor={id} className=\"sr-only\">\n        M3-style switch\n      </Label>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/switch/switch-07.vue",
          "target": "components/ui/switch-07.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Switch } from '@timui/vue';\n\n\n\n\n\nconst id = 'switch-07';\n\n</script>\n\n<template>\n  <div class=\"inline-flex items-center gap-2\"><Switch :id=\"id\" class=\"data-[state=unchecked]:border-input data-[state=unchecked]:[&_span]:bg-input data-[state=unchecked]:bg-transparent [&_span]:transition-all data-[state=unchecked]:[&_span]:size-4 data-[state=unchecked]:[&_span]:translate-x-0.5 data-[state=unchecked]:[&_span]:shadow-none data-[state=unchecked]:[&_span]:rtl:-translate-x-0.5\" /><Label :htmlFor=\"id\" class=\"sr-only\">M3-style switch\n      </Label></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/switch/switch-07.html",
          "target": "components/ui/switch-07.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"inline-flex items-center gap-2\"><Switch id=\"${id}\" class=\"data-[state=unchecked]:border-input data-[state=unchecked]:[&_span]:bg-input data-[state=unchecked]:bg-transparent [&_span]:transition-all data-[state=unchecked]:[&_span]:size-4 data-[state=unchecked]:[&_span]:translate-x-0.5 data-[state=unchecked]:[&_span]:shadow-none data-[state=unchecked]:[&_span]:rtl:-translate-x-0.5\" /><Label htmlfor=\"${id}\" class=\"sr-only\">M3-style switch\n      </Label></div>\n</template>"
        },
        {
          "path": "registry/default/components/switch/switch-07.wxml",
          "target": "components/ui/switch-07/switch-07.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"inline-flex items-center gap-2\"><switch id=\"{{id}}\" class=\"data-[state=unchecked]:border-input data-[state=unchecked]:[&_span]:bg-input data-[state=unchecked]:bg-transparent [&_span]:transition-all data-[state=unchecked]:[&_span]:size-4 data-[state=unchecked]:[&_span]:translate-x-0.5 data-[state=unchecked]:[&_span]:shadow-none data-[state=unchecked]:[&_span]:rtl:-translate-x-0.5\" /><label htmlfor=\"{{id}}\" class=\"sr-only\">M3-style switch\n      </label></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "switch",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "switch-07",
          "group": "switch",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "switch-07",
              "path": "registry/default/components/switch/switch-07.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "switch-07",
              "path": "registry/default/components/switch/switch-07.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "switch-07",
              "path": "registry/default/components/switch/switch-07.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "switch-07",
              "path": "registry/default/components/switch/switch-07.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "switch",
        "title": "Switch · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "switch"
      ]
    },
    {
      "name": "switch-08",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/switch.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/switch/switch-08.tsx",
          "type": "registry:component",
          "target": "components/ui/switch-08.tsx",
          "content": "'use client'\n\nimport { useId, useState } from 'react'\nimport { Label, Switch } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  const [checked, setChecked] = useState<boolean>(true)\n\n  return (\n    <div className=\"inline-flex items-center gap-2\">\n      <Switch id={id} checked={checked} onCheckedChange={setChecked} aria-label=\"Toggle switch\" />\n      <Label htmlFor={id} className=\"text-sm font-medium\">\n        {checked ? 'On' : 'Off'}\n      </Label>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/switch/switch-08.vue",
          "target": "components/ui/switch-08.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Label } from '@timui/vue';\nimport { Switch } from '@timui/vue';\n\n\n\nconst checked = ref<boolean>(true);\n\n\nconst id = 'switch-08';\n\n\nfunction setChecked(next: typeof checked.value | ((prev: typeof checked.value) => typeof checked.value)) {\n  checked.value = typeof next === 'function'\n    ? (next as (prev: typeof checked.value) => typeof checked.value)(checked.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <div class=\"inline-flex items-center gap-2\"><Switch :id=\"id\" :checked=\"checked\" :onCheckedChange=\"setChecked\" aria-label=\"Toggle switch\" /><Label :htmlFor=\"id\" class=\"text-sm font-medium\"><template v-if=\"checked\">\n{{ 'On' }}\n</template>\n<template v-else>\n{{ 'Off' }}\n</template></Label></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/switch/switch-08.html",
          "target": "components/ui/switch-08.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"inline-flex items-center gap-2\"><Switch id=\"${id}\" checked=\"${checked}\" oncheckedchange=\"${setChecked}\" aria-label=\"Toggle switch\" /><Label htmlfor=\"${id}\" class=\"text-sm font-medium\"><!-- if checked -->\n${'On'}\n<!-- else -->\n${'Off'}\n<!-- endif --></Label></div>\n</template>"
        },
        {
          "path": "registry/default/components/switch/switch-08.wxml",
          "target": "components/ui/switch-08/switch-08.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"inline-flex items-center gap-2\"><switch id=\"{{id}}\" checked=\"{{checked}}\" oncheckedchange=\"{{setChecked}}\" aria-label=\"Toggle switch\" /><label htmlfor=\"{{id}}\" class=\"text-sm font-medium\"><block wx:if=\"{{checked}}\">\n{{ 'On' }}\n</block>\n<block wx:else>\n{{ 'Off' }}\n</block></label></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "switch",
          "label",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "switch-08",
          "group": "switch",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "switch-08",
              "path": "registry/default/components/switch/switch-08.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "switch-08",
              "path": "registry/default/components/switch/switch-08.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "switch-08",
              "path": "registry/default/components/switch/switch-08.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "switch-08",
              "path": "registry/default/components/switch/switch-08.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "switch",
        "title": "Switch · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "switch"
      ]
    },
    {
      "name": "switch-09",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/switch.json"
      ],
      "files": [
        {
          "path": "registry/default/components/switch/switch-09.tsx",
          "type": "registry:component",
          "target": "components/ui/switch-09.tsx",
          "content": "'use client'\n\nimport { useId, useState } from 'react'\nimport { Switch } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  const [checked, setChecked] = useState(false)\n\n  const toggleSwitch = () => setChecked((prev) => !prev)\n\n  return (\n    <div\n      className=\"group inline-flex items-center gap-2\"\n      data-state={checked ? 'checked' : 'unchecked'}\n    >\n      <span\n        id={`${id}-off`}\n        className=\"group-data-[state=checked]:text-muted-foreground/70 flex-1 cursor-pointer text-right text-sm font-medium\"\n        aria-controls={id}\n        onClick={() => setChecked(false)}\n      >\n        Off\n      </span>\n      <Switch\n        id={id}\n        checked={checked}\n        onCheckedChange={toggleSwitch}\n        aria-labelledby={`${id}-off ${id}-on`}\n      />\n      <span\n        id={`${id}-on`}\n        className=\"group-data-[state=unchecked]:text-muted-foreground/70 flex-1 cursor-pointer text-left text-sm font-medium\"\n        aria-controls={id}\n        onClick={() => setChecked(true)}\n      >\n        On\n      </span>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/switch/switch-09.vue",
          "target": "components/ui/switch-09.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Switch } from '@timui/vue';\n\n\n\nconst checked = ref(false);\n\n\nfunction setChecked(next: typeof checked.value | ((prev: typeof checked.value) => typeof checked.value)) {\n  checked.value = typeof next === 'function'\n    ? (next as (prev: typeof checked.value) => typeof checked.value)(checked.value)\n    : next;\n}\n\n\nconst id = 'switch-09';\n\n</script>\n\n<template>\n  <div class=\"group inline-flex items-center gap-2\" :data-state=\"checked ? 'checked' : 'unchecked'\"><span :id=\"`${id}-off`\" class=\"group-data-[state=checked]:text-muted-foreground/70 flex-1 cursor-pointer text-right text-sm font-medium\" :aria-controls=\"id\" @click=\"setChecked(false)\">Off\n      </span><Switch :id=\"id\" :checked=\"checked\" :onCheckedChange=\"toggleSwitch\" :aria-labelledby=\"`${id}-off ${id}-on`\" /><span :id=\"`${id}-on`\" class=\"group-data-[state=unchecked]:text-muted-foreground/70 flex-1 cursor-pointer text-left text-sm font-medium\" :aria-controls=\"id\" @click=\"setChecked(true)\">On\n      </span></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/switch/switch-09.html",
          "target": "components/ui/switch-09.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"group inline-flex items-center gap-2\" data-state=\"${checked ? 'checked' : 'unchecked'}\"><span id=\"${`${id}-off`}\" class=\"group-data-[state=checked]:text-muted-foreground/70 flex-1 cursor-pointer text-right text-sm font-medium\" aria-controls=\"${id}\" on-click=\"${() => setChecked(false)}\">Off\n      </span><Switch id=\"${id}\" checked=\"${checked}\" oncheckedchange=\"${toggleSwitch}\" aria-labelledby=\"${`${id}-off ${id}-on`}\" /><span id=\"${`${id}-on`}\" class=\"group-data-[state=unchecked]:text-muted-foreground/70 flex-1 cursor-pointer text-left text-sm font-medium\" aria-controls=\"${id}\" on-click=\"${() => setChecked(true)}\">On\n      </span></div>\n</template>"
        },
        {
          "path": "registry/default/components/switch/switch-09.wxml",
          "target": "components/ui/switch-09/switch-09.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"group inline-flex items-center gap-2\" data-state=\"{{checked ? 'checked' : 'unchecked'}}\"><text id=\"{{`${id}-off`}}\" class=\"group-data-[state=checked]:text-muted-foreground/70 flex-1 cursor-pointer text-right text-sm font-medium\" aria-controls=\"{{id}}\" bindtap=\"setChecked(false)\">Off\n      </text><switch id=\"{{id}}\" checked=\"{{checked}}\" oncheckedchange=\"{{toggleSwitch}}\" aria-labelledby=\"{{`${id}-off ${id}-on`}}\" /><text id=\"{{`${id}-on`}}\" class=\"group-data-[state=unchecked]:text-muted-foreground/70 flex-1 cursor-pointer text-left text-sm font-medium\" aria-controls=\"{{id}}\" bindtap=\"setChecked(true)\">On\n      </text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "switch",
          "label",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "switch-09",
          "group": "switch",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "switch-09",
              "path": "registry/default/components/switch/switch-09.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "switch-09",
              "path": "registry/default/components/switch/switch-09.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "switch-09",
              "path": "registry/default/components/switch/switch-09.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "switch-09",
              "path": "registry/default/components/switch/switch-09.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "switch",
        "title": "Switch · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "switch"
      ]
    },
    {
      "name": "switch-10",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/switch.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/switch/switch-10.tsx",
          "type": "registry:component",
          "target": "components/ui/switch-10.tsx",
          "content": "'use client'\n\nimport { useId, useState } from 'react'\nimport { Label, Switch } from '@timui/react'\nimport { MoonIcon, SunIcon } from 'lucide-react'\n\nexport default function Component() {\n  const id = useId()\n  const [checked, setChecked] = useState<boolean>(true)\n\n  return (\n    <div className=\"inline-flex items-center gap-2\">\n      <Switch id={id} checked={checked} onCheckedChange={setChecked} aria-label=\"Toggle switch\" />\n      <Label htmlFor={id}>\n        <span className=\"sr-only\">Toggle switch</span>\n        {checked ? (\n          <SunIcon size={16} aria-hidden=\"true\" />\n        ) : (\n          <MoonIcon size={16} aria-hidden=\"true\" />\n        )}\n      </Label>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/switch/switch-10.vue",
          "target": "components/ui/switch-10.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { MoonIcon, SunIcon } from 'lucide-vue-next';\nimport { Label } from '@timui/vue';\nimport { Switch } from '@timui/vue';\n\n\n\nconst checked = ref<boolean>(true);\n\n\nconst id = 'switch-10';\n\n\nfunction setChecked(next: typeof checked.value | ((prev: typeof checked.value) => typeof checked.value)) {\n  checked.value = typeof next === 'function'\n    ? (next as (prev: typeof checked.value) => typeof checked.value)(checked.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <div class=\"inline-flex items-center gap-2\"><Switch :id=\"id\" :checked=\"checked\" :onCheckedChange=\"setChecked\" aria-label=\"Toggle switch\" /><Label :htmlFor=\"id\"><span class=\"sr-only\">Toggle switch</span><template v-if=\"checked\">\n<SunIcon :size=\"16\" aria-hidden=\"true\" />\n</template>\n<template v-else>\n<MoonIcon :size=\"16\" aria-hidden=\"true\" />\n</template></Label></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/switch/switch-10.html",
          "target": "components/ui/switch-10.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"inline-flex items-center gap-2\"><Switch id=\"${id}\" checked=\"${checked}\" oncheckedchange=\"${setChecked}\" aria-label=\"Toggle switch\" /><Label htmlfor=\"${id}\"><span class=\"sr-only\">Toggle switch</span><!-- if checked -->\n<SunIcon size=\"${16}\" aria-hidden=\"true\" />\n<!-- else -->\n<MoonIcon size=\"${16}\" aria-hidden=\"true\" />\n<!-- endif --></Label></div>\n</template>"
        },
        {
          "path": "registry/default/components/switch/switch-10.wxml",
          "target": "components/ui/switch-10/switch-10.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"inline-flex items-center gap-2\"><switch id=\"{{id}}\" checked=\"{{checked}}\" oncheckedchange=\"{{setChecked}}\" aria-label=\"Toggle switch\" /><label htmlfor=\"{{id}}\"><text class=\"sr-only\">Toggle switch</text><block wx:if=\"{{checked}}\">\n<sunicon size=\"{{16}}\" aria-hidden=\"true\" />\n</block>\n<block wx:else>\n<moonicon size=\"{{16}}\" aria-hidden=\"true\" />\n</block></label></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "switch",
          "label",
          "darkmode",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "switch-10",
          "group": "switch",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "switch-10",
              "path": "registry/default/components/switch/switch-10.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "switch-10",
              "path": "registry/default/components/switch/switch-10.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "switch-10",
              "path": "registry/default/components/switch/switch-10.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "switch-10",
              "path": "registry/default/components/switch/switch-10.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "switch",
        "title": "Switch · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "switch"
      ]
    },
    {
      "name": "switch-11",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/switch.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/switch/switch-11.tsx",
          "type": "registry:component",
          "target": "components/ui/switch-11.tsx",
          "content": "'use client'\n\nimport { useId, useState } from 'react'\nimport { Switch } from '@timui/react'\nimport { MoonIcon, SunIcon } from 'lucide-react'\n\nexport default function Component() {\n  const id = useId()\n  const [checked, setChecked] = useState(false)\n\n  const toggleSwitch = () => setChecked((prev) => !prev)\n\n  return (\n    <div\n      className=\"group inline-flex items-center gap-2\"\n      data-state={checked ? 'checked' : 'unchecked'}\n    >\n      <span\n        id={`${id}-off`}\n        className=\"group-data-[state=checked]:text-muted-foreground/70 flex-1 cursor-pointer text-right text-sm font-medium\"\n        aria-controls={id}\n        onClick={() => setChecked(false)}\n      >\n        <MoonIcon size={16} aria-hidden=\"true\" />\n      </span>\n      <Switch\n        id={id}\n        checked={checked}\n        onCheckedChange={toggleSwitch}\n        aria-labelledby={`${id}-off ${id}-on`}\n        aria-label=\"Toggle between dark and light mode\"\n      />\n      <span\n        id={`${id}-on`}\n        className=\"group-data-[state=unchecked]:text-muted-foreground/70 flex-1 cursor-pointer text-left text-sm font-medium\"\n        aria-controls={id}\n        onClick={() => setChecked(true)}\n      >\n        <SunIcon size={16} aria-hidden=\"true\" />\n      </span>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/switch/switch-11.vue",
          "target": "components/ui/switch-11.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { MoonIcon, SunIcon } from 'lucide-vue-next';\nimport { Switch } from '@timui/vue';\n\n\n\nconst checked = ref(false);\n\n\nfunction setChecked(next: typeof checked.value | ((prev: typeof checked.value) => typeof checked.value)) {\n  checked.value = typeof next === 'function'\n    ? (next as (prev: typeof checked.value) => typeof checked.value)(checked.value)\n    : next;\n}\n\n\nconst id = 'switch-11';\n\n</script>\n\n<template>\n  <div class=\"group inline-flex items-center gap-2\" :data-state=\"checked ? 'checked' : 'unchecked'\"><span :id=\"`${id}-off`\" class=\"group-data-[state=checked]:text-muted-foreground/70 flex-1 cursor-pointer text-right text-sm font-medium\" :aria-controls=\"id\" @click=\"setChecked(false)\"><MoonIcon :size=\"16\" aria-hidden=\"true\" /></span><Switch :id=\"id\" :checked=\"checked\" :onCheckedChange=\"toggleSwitch\" :aria-labelledby=\"`${id}-off ${id}-on`\" aria-label=\"Toggle between dark and light mode\" /><span :id=\"`${id}-on`\" class=\"group-data-[state=unchecked]:text-muted-foreground/70 flex-1 cursor-pointer text-left text-sm font-medium\" :aria-controls=\"id\" @click=\"setChecked(true)\"><SunIcon :size=\"16\" aria-hidden=\"true\" /></span></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/switch/switch-11.html",
          "target": "components/ui/switch-11.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"group inline-flex items-center gap-2\" data-state=\"${checked ? 'checked' : 'unchecked'}\"><span id=\"${`${id}-off`}\" class=\"group-data-[state=checked]:text-muted-foreground/70 flex-1 cursor-pointer text-right text-sm font-medium\" aria-controls=\"${id}\" on-click=\"${() => setChecked(false)}\"><MoonIcon size=\"${16}\" aria-hidden=\"true\" /></span><Switch id=\"${id}\" checked=\"${checked}\" oncheckedchange=\"${toggleSwitch}\" aria-labelledby=\"${`${id}-off ${id}-on`}\" aria-label=\"Toggle between dark and light mode\" /><span id=\"${`${id}-on`}\" class=\"group-data-[state=unchecked]:text-muted-foreground/70 flex-1 cursor-pointer text-left text-sm font-medium\" aria-controls=\"${id}\" on-click=\"${() => setChecked(true)}\"><SunIcon size=\"${16}\" aria-hidden=\"true\" /></span></div>\n</template>"
        },
        {
          "path": "registry/default/components/switch/switch-11.wxml",
          "target": "components/ui/switch-11/switch-11.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"group inline-flex items-center gap-2\" data-state=\"{{checked ? 'checked' : 'unchecked'}}\"><text id=\"{{`${id}-off`}}\" class=\"group-data-[state=checked]:text-muted-foreground/70 flex-1 cursor-pointer text-right text-sm font-medium\" aria-controls=\"{{id}}\" bindtap=\"setChecked(false)\"><moonicon size=\"{{16}}\" aria-hidden=\"true\" /></text><switch id=\"{{id}}\" checked=\"{{checked}}\" oncheckedchange=\"{{toggleSwitch}}\" aria-labelledby=\"{{`${id}-off ${id}-on`}}\" aria-label=\"Toggle between dark and light mode\" /><text id=\"{{`${id}-on`}}\" class=\"group-data-[state=unchecked]:text-muted-foreground/70 flex-1 cursor-pointer text-left text-sm font-medium\" aria-controls=\"{{id}}\" bindtap=\"setChecked(true)\"><sunicon size=\"{{16}}\" aria-hidden=\"true\" /></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "switch",
          "label",
          "darkmode",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "switch-11",
          "group": "switch",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "switch-11",
              "path": "registry/default/components/switch/switch-11.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "switch-11",
              "path": "registry/default/components/switch/switch-11.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "switch-11",
              "path": "registry/default/components/switch/switch-11.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "switch-11",
              "path": "registry/default/components/switch/switch-11.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "switch",
        "title": "Switch · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "switch"
      ]
    },
    {
      "name": "switch-12",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/switch.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/switch/switch-12.tsx",
          "type": "registry:component",
          "target": "components/ui/switch-12.tsx",
          "content": "'use client'\n\nimport { useId, useState } from 'react'\nimport { Label, Switch } from '@timui/react'\nimport { MoonIcon, SunIcon } from 'lucide-react'\n\nexport default function Component() {\n  const id = useId()\n  const [checked, setChecked] = useState<boolean>(true)\n\n  return (\n    <div>\n      <div className=\"relative inline-grid h-9 grid-cols-[1fr_1fr] items-center text-sm font-medium\">\n        <Switch\n          id={id}\n          checked={checked}\n          onCheckedChange={setChecked}\n          className=\"peer data-[state=checked]:bg-input/50 data-[state=unchecked]:bg-input/50 absolute inset-0 h-[inherit] w-auto [&_span]:h-full [&_span]:w-1/2 [&_span]:transition-transform [&_span]:duration-300 [&_span]:ease-[cubic-bezier(0.16,1,0.3,1)] [&_span]:data-[state=checked]:translate-x-full [&_span]:data-[state=checked]:rtl:-translate-x-full\"\n        />\n        <span className=\"peer-data-[state=checked]:text-muted-foreground/70 pointer-events-none relative ms-0.5 flex min-w-8 items-center justify-center text-center\">\n          <MoonIcon size={16} aria-hidden=\"true\" />\n        </span>\n        <span className=\"peer-data-[state=unchecked]:text-muted-foreground/70 pointer-events-none relative me-0.5 flex min-w-8 items-center justify-center text-center\">\n          <SunIcon size={16} aria-hidden=\"true\" />\n        </span>\n      </div>\n      <Label htmlFor={id} className=\"sr-only\">\n        Labeled switch\n      </Label>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/switch/switch-12.vue",
          "target": "components/ui/switch-12.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { MoonIcon, SunIcon } from 'lucide-vue-next';\nimport { Label } from '@timui/vue';\nimport { Switch } from '@timui/vue';\n\n\n\nconst checked = ref<boolean>(true);\n\n\nconst id = 'switch-12';\n\n\nfunction setChecked(next: typeof checked.value | ((prev: typeof checked.value) => typeof checked.value)) {\n  checked.value = typeof next === 'function'\n    ? (next as (prev: typeof checked.value) => typeof checked.value)(checked.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <div><div class=\"relative inline-grid h-9 grid-cols-[1fr_1fr] items-center text-sm font-medium\"><Switch :id=\"id\" :checked=\"checked\" :onCheckedChange=\"setChecked\" class=\"peer data-[state=checked]:bg-input/50 data-[state=unchecked]:bg-input/50 absolute inset-0 h-[inherit] w-auto [&_span]:h-full [&_span]:w-1/2 [&_span]:transition-transform [&_span]:duration-300 [&_span]:ease-[cubic-bezier(0.16,1,0.3,1)] [&_span]:data-[state=checked]:translate-x-full [&_span]:data-[state=checked]:rtl:-translate-x-full\" /><span class=\"peer-data-[state=checked]:text-muted-foreground/70 pointer-events-none relative ms-0.5 flex min-w-8 items-center justify-center text-center\"><MoonIcon :size=\"16\" aria-hidden=\"true\" /></span><span class=\"peer-data-[state=unchecked]:text-muted-foreground/70 pointer-events-none relative me-0.5 flex min-w-8 items-center justify-center text-center\"><SunIcon :size=\"16\" aria-hidden=\"true\" /></span></div><Label :htmlFor=\"id\" class=\"sr-only\">Labeled switch\n      </Label></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/switch/switch-12.html",
          "target": "components/ui/switch-12.html",
          "type": "registry:component",
          "content": "<template>\n  <div><div class=\"relative inline-grid h-9 grid-cols-[1fr_1fr] items-center text-sm font-medium\"><Switch id=\"${id}\" checked=\"${checked}\" oncheckedchange=\"${setChecked}\" class=\"peer data-[state=checked]:bg-input/50 data-[state=unchecked]:bg-input/50 absolute inset-0 h-[inherit] w-auto [&_span]:h-full [&_span]:w-1/2 [&_span]:transition-transform [&_span]:duration-300 [&_span]:ease-[cubic-bezier(0.16,1,0.3,1)] [&_span]:data-[state=checked]:translate-x-full [&_span]:data-[state=checked]:rtl:-translate-x-full\" /><span class=\"peer-data-[state=checked]:text-muted-foreground/70 pointer-events-none relative ms-0.5 flex min-w-8 items-center justify-center text-center\"><MoonIcon size=\"${16}\" aria-hidden=\"true\" /></span><span class=\"peer-data-[state=unchecked]:text-muted-foreground/70 pointer-events-none relative me-0.5 flex min-w-8 items-center justify-center text-center\"><SunIcon size=\"${16}\" aria-hidden=\"true\" /></span></div><Label htmlfor=\"${id}\" class=\"sr-only\">Labeled switch\n      </Label></div>\n</template>"
        },
        {
          "path": "registry/default/components/switch/switch-12.wxml",
          "target": "components/ui/switch-12/switch-12.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><view class=\"relative inline-grid h-9 grid-cols-[1fr_1fr] items-center text-sm font-medium\"><switch id=\"{{id}}\" checked=\"{{checked}}\" oncheckedchange=\"{{setChecked}}\" class=\"peer data-[state=checked]:bg-input/50 data-[state=unchecked]:bg-input/50 absolute inset-0 h-[inherit] w-auto [&_span]:h-full [&_span]:w-1/2 [&_span]:transition-transform [&_span]:duration-300 [&_span]:ease-[cubic-bezier(0.16,1,0.3,1)] [&_span]:data-[state=checked]:translate-x-full [&_span]:data-[state=checked]:rtl:-translate-x-full\" /><text class=\"peer-data-[state=checked]:text-muted-foreground/70 pointer-events-none relative ms-0.5 flex min-w-8 items-center justify-center text-center\"><moonicon size=\"{{16}}\" aria-hidden=\"true\" /></text><text class=\"peer-data-[state=unchecked]:text-muted-foreground/70 pointer-events-none relative me-0.5 flex min-w-8 items-center justify-center text-center\"><sunicon size=\"{{16}}\" aria-hidden=\"true\" /></text></view><label htmlfor=\"{{id}}\" class=\"sr-only\">Labeled switch\n      </label></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "switch",
          "label",
          "darkmode",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "switch-12",
          "group": "switch",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "switch-12",
              "path": "registry/default/components/switch/switch-12.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "switch-12",
              "path": "registry/default/components/switch/switch-12.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "switch-12",
              "path": "registry/default/components/switch/switch-12.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "switch-12",
              "path": "registry/default/components/switch/switch-12.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "switch",
        "title": "Switch · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "switch"
      ]
    },
    {
      "name": "switch-13",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/switch.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/switch/switch-13.tsx",
          "type": "registry:component",
          "target": "components/ui/switch-13.tsx",
          "content": "'use client'\n\nimport { useId, useState } from 'react'\nimport { Label, Switch } from '@timui/react'\nimport { MoonIcon, SunIcon } from 'lucide-react'\n\nexport default function Component() {\n  const id = useId()\n  const [checked, setChecked] = useState<boolean>(true)\n\n  return (\n    <div>\n      <div className=\"relative inline-grid h-9 grid-cols-[1fr_1fr] items-center text-sm font-medium\">\n        <Switch\n          id={id}\n          checked={checked}\n          onCheckedChange={setChecked}\n          className=\"peer data-[state=unchecked]:bg-input/50 absolute inset-0 h-[inherit] w-auto [&_span]:z-10 [&_span]:h-full [&_span]:w-1/2 [&_span]:transition-transform [&_span]:duration-300 [&_span]:ease-[cubic-bezier(0.16,1,0.3,1)] [&_span]:data-[state=checked]:translate-x-full [&_span]:data-[state=checked]:rtl:-translate-x-full\"\n        />\n        <span className=\"pointer-events-none relative ms-0.5 flex min-w-8 items-center justify-center text-center transition-transform duration-300 ease-[cubic-bezier(0.16,1,0.3,1)] peer-data-[state=checked]:invisible peer-data-[state=unchecked]:translate-x-full peer-data-[state=unchecked]:rtl:-translate-x-full\">\n          <MoonIcon size={16} aria-hidden=\"true\" />\n        </span>\n        <span className=\"peer-data-[state=checked]:text-background pointer-events-none relative me-0.5 flex min-w-8 items-center justify-center text-center transition-transform duration-300 ease-[cubic-bezier(0.16,1,0.3,1)] peer-data-[state=checked]:-translate-x-full peer-data-[state=unchecked]:invisible peer-data-[state=checked]:rtl:translate-x-full\">\n          <SunIcon size={16} aria-hidden=\"true\" />\n        </span>\n      </div>\n      <Label htmlFor={id} className=\"sr-only\">\n        Labeled switch\n      </Label>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/switch/switch-13.vue",
          "target": "components/ui/switch-13.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { MoonIcon, SunIcon } from 'lucide-vue-next';\nimport { Label } from '@timui/vue';\nimport { Switch } from '@timui/vue';\n\n\n\nconst checked = ref<boolean>(true);\n\n\nconst id = 'switch-13';\n\n\nfunction setChecked(next: typeof checked.value | ((prev: typeof checked.value) => typeof checked.value)) {\n  checked.value = typeof next === 'function'\n    ? (next as (prev: typeof checked.value) => typeof checked.value)(checked.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <div><div class=\"relative inline-grid h-9 grid-cols-[1fr_1fr] items-center text-sm font-medium\"><Switch :id=\"id\" :checked=\"checked\" :onCheckedChange=\"setChecked\" class=\"peer data-[state=unchecked]:bg-input/50 absolute inset-0 h-[inherit] w-auto [&_span]:z-10 [&_span]:h-full [&_span]:w-1/2 [&_span]:transition-transform [&_span]:duration-300 [&_span]:ease-[cubic-bezier(0.16,1,0.3,1)] [&_span]:data-[state=checked]:translate-x-full [&_span]:data-[state=checked]:rtl:-translate-x-full\" /><span class=\"pointer-events-none relative ms-0.5 flex min-w-8 items-center justify-center text-center transition-transform duration-300 ease-[cubic-bezier(0.16,1,0.3,1)] peer-data-[state=checked]:invisible peer-data-[state=unchecked]:translate-x-full peer-data-[state=unchecked]:rtl:-translate-x-full\"><MoonIcon :size=\"16\" aria-hidden=\"true\" /></span><span class=\"peer-data-[state=checked]:text-background pointer-events-none relative me-0.5 flex min-w-8 items-center justify-center text-center transition-transform duration-300 ease-[cubic-bezier(0.16,1,0.3,1)] peer-data-[state=checked]:-translate-x-full peer-data-[state=unchecked]:invisible peer-data-[state=checked]:rtl:translate-x-full\"><SunIcon :size=\"16\" aria-hidden=\"true\" /></span></div><Label :htmlFor=\"id\" class=\"sr-only\">Labeled switch\n      </Label></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/switch/switch-13.html",
          "target": "components/ui/switch-13.html",
          "type": "registry:component",
          "content": "<template>\n  <div><div class=\"relative inline-grid h-9 grid-cols-[1fr_1fr] items-center text-sm font-medium\"><Switch id=\"${id}\" checked=\"${checked}\" oncheckedchange=\"${setChecked}\" class=\"peer data-[state=unchecked]:bg-input/50 absolute inset-0 h-[inherit] w-auto [&_span]:z-10 [&_span]:h-full [&_span]:w-1/2 [&_span]:transition-transform [&_span]:duration-300 [&_span]:ease-[cubic-bezier(0.16,1,0.3,1)] [&_span]:data-[state=checked]:translate-x-full [&_span]:data-[state=checked]:rtl:-translate-x-full\" /><span class=\"pointer-events-none relative ms-0.5 flex min-w-8 items-center justify-center text-center transition-transform duration-300 ease-[cubic-bezier(0.16,1,0.3,1)] peer-data-[state=checked]:invisible peer-data-[state=unchecked]:translate-x-full peer-data-[state=unchecked]:rtl:-translate-x-full\"><MoonIcon size=\"${16}\" aria-hidden=\"true\" /></span><span class=\"peer-data-[state=checked]:text-background pointer-events-none relative me-0.5 flex min-w-8 items-center justify-center text-center transition-transform duration-300 ease-[cubic-bezier(0.16,1,0.3,1)] peer-data-[state=checked]:-translate-x-full peer-data-[state=unchecked]:invisible peer-data-[state=checked]:rtl:translate-x-full\"><SunIcon size=\"${16}\" aria-hidden=\"true\" /></span></div><Label htmlfor=\"${id}\" class=\"sr-only\">Labeled switch\n      </Label></div>\n</template>"
        },
        {
          "path": "registry/default/components/switch/switch-13.wxml",
          "target": "components/ui/switch-13/switch-13.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><view class=\"relative inline-grid h-9 grid-cols-[1fr_1fr] items-center text-sm font-medium\"><switch id=\"{{id}}\" checked=\"{{checked}}\" oncheckedchange=\"{{setChecked}}\" class=\"peer data-[state=unchecked]:bg-input/50 absolute inset-0 h-[inherit] w-auto [&_span]:z-10 [&_span]:h-full [&_span]:w-1/2 [&_span]:transition-transform [&_span]:duration-300 [&_span]:ease-[cubic-bezier(0.16,1,0.3,1)] [&_span]:data-[state=checked]:translate-x-full [&_span]:data-[state=checked]:rtl:-translate-x-full\" /><text class=\"pointer-events-none relative ms-0.5 flex min-w-8 items-center justify-center text-center transition-transform duration-300 ease-[cubic-bezier(0.16,1,0.3,1)] peer-data-[state=checked]:invisible peer-data-[state=unchecked]:translate-x-full peer-data-[state=unchecked]:rtl:-translate-x-full\"><moonicon size=\"{{16}}\" aria-hidden=\"true\" /></text><text class=\"peer-data-[state=checked]:text-background pointer-events-none relative me-0.5 flex min-w-8 items-center justify-center text-center transition-transform duration-300 ease-[cubic-bezier(0.16,1,0.3,1)] peer-data-[state=checked]:-translate-x-full peer-data-[state=unchecked]:invisible peer-data-[state=checked]:rtl:translate-x-full\"><sunicon size=\"{{16}}\" aria-hidden=\"true\" /></text></view><label htmlfor=\"{{id}}\" class=\"sr-only\">Labeled switch\n      </label></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "switch",
          "label",
          "darkmode",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "switch-13",
          "group": "switch",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "switch-13",
              "path": "registry/default/components/switch/switch-13.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "switch-13",
              "path": "registry/default/components/switch/switch-13.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "switch-13",
              "path": "registry/default/components/switch/switch-13.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "switch-13",
              "path": "registry/default/components/switch/switch-13.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "switch",
        "title": "Switch · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "switch"
      ]
    },
    {
      "name": "switch-14",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/switch.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/switch/switch-14.tsx",
          "type": "registry:component",
          "target": "components/ui/switch-14.tsx",
          "content": "'use client'\n\nimport { useId, useState } from 'react'\nimport { Label, Switch } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  const [checked, setChecked] = useState<boolean>(true)\n\n  return (\n    <div>\n      <div className=\"relative inline-grid h-9 grid-cols-[1fr_1fr] items-center text-sm font-medium\">\n        <Switch\n          id={id}\n          checked={checked}\n          onCheckedChange={setChecked}\n          className=\"peer data-[state=unchecked]:bg-input/50 absolute inset-0 h-[inherit] w-auto rounded-md [&_span]:z-10 [&_span]:h-full [&_span]:w-1/2 [&_span]:rounded-sm [&_span]:transition-transform [&_span]:duration-300 [&_span]:ease-[cubic-bezier(0.16,1,0.3,1)] [&_span]:data-[state=checked]:translate-x-full [&_span]:data-[state=checked]:rtl:-translate-x-full\"\n        />\n        <span className=\"pointer-events-none relative ms-0.5 flex items-center justify-center px-2 text-center transition-transform duration-300 ease-[cubic-bezier(0.16,1,0.3,1)] peer-data-[state=checked]:invisible peer-data-[state=unchecked]:translate-x-full peer-data-[state=unchecked]:rtl:-translate-x-full\">\n          <span className=\"text-[10px] font-medium uppercase\">Off</span>\n        </span>\n        <span className=\"peer-data-[state=checked]:text-background pointer-events-none relative me-0.5 flex items-center justify-center px-2 text-center transition-transform duration-300 ease-[cubic-bezier(0.16,1,0.3,1)] peer-data-[state=checked]:-translate-x-full peer-data-[state=unchecked]:invisible peer-data-[state=checked]:rtl:translate-x-full\">\n          <span className=\"text-[10px] font-medium uppercase\">On</span>\n        </span>\n      </div>\n      <Label htmlFor={id} className=\"sr-only\">\n        Labeled switch\n      </Label>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/switch/switch-14.vue",
          "target": "components/ui/switch-14.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Label } from '@timui/vue';\nimport { Switch } from '@timui/vue';\n\n\n\nconst checked = ref<boolean>(true);\n\n\nconst id = 'switch-14';\n\n\nfunction setChecked(next: typeof checked.value | ((prev: typeof checked.value) => typeof checked.value)) {\n  checked.value = typeof next === 'function'\n    ? (next as (prev: typeof checked.value) => typeof checked.value)(checked.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <div><div class=\"relative inline-grid h-9 grid-cols-[1fr_1fr] items-center text-sm font-medium\"><Switch :id=\"id\" :checked=\"checked\" :onCheckedChange=\"setChecked\" class=\"peer data-[state=unchecked]:bg-input/50 absolute inset-0 h-[inherit] w-auto rounded-md [&_span]:z-10 [&_span]:h-full [&_span]:w-1/2 [&_span]:rounded-sm [&_span]:transition-transform [&_span]:duration-300 [&_span]:ease-[cubic-bezier(0.16,1,0.3,1)] [&_span]:data-[state=checked]:translate-x-full [&_span]:data-[state=checked]:rtl:-translate-x-full\" /><span class=\"pointer-events-none relative ms-0.5 flex items-center justify-center px-2 text-center transition-transform duration-300 ease-[cubic-bezier(0.16,1,0.3,1)] peer-data-[state=checked]:invisible peer-data-[state=unchecked]:translate-x-full peer-data-[state=unchecked]:rtl:-translate-x-full\"><span class=\"text-[10px] font-medium uppercase\">Off</span></span><span class=\"peer-data-[state=checked]:text-background pointer-events-none relative me-0.5 flex items-center justify-center px-2 text-center transition-transform duration-300 ease-[cubic-bezier(0.16,1,0.3,1)] peer-data-[state=checked]:-translate-x-full peer-data-[state=unchecked]:invisible peer-data-[state=checked]:rtl:translate-x-full\"><span class=\"text-[10px] font-medium uppercase\">On</span></span></div><Label :htmlFor=\"id\" class=\"sr-only\">Labeled switch\n      </Label></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/switch/switch-14.html",
          "target": "components/ui/switch-14.html",
          "type": "registry:component",
          "content": "<template>\n  <div><div class=\"relative inline-grid h-9 grid-cols-[1fr_1fr] items-center text-sm font-medium\"><Switch id=\"${id}\" checked=\"${checked}\" oncheckedchange=\"${setChecked}\" class=\"peer data-[state=unchecked]:bg-input/50 absolute inset-0 h-[inherit] w-auto rounded-md [&_span]:z-10 [&_span]:h-full [&_span]:w-1/2 [&_span]:rounded-sm [&_span]:transition-transform [&_span]:duration-300 [&_span]:ease-[cubic-bezier(0.16,1,0.3,1)] [&_span]:data-[state=checked]:translate-x-full [&_span]:data-[state=checked]:rtl:-translate-x-full\" /><span class=\"pointer-events-none relative ms-0.5 flex items-center justify-center px-2 text-center transition-transform duration-300 ease-[cubic-bezier(0.16,1,0.3,1)] peer-data-[state=checked]:invisible peer-data-[state=unchecked]:translate-x-full peer-data-[state=unchecked]:rtl:-translate-x-full\"><span class=\"text-[10px] font-medium uppercase\">Off</span></span><span class=\"peer-data-[state=checked]:text-background pointer-events-none relative me-0.5 flex items-center justify-center px-2 text-center transition-transform duration-300 ease-[cubic-bezier(0.16,1,0.3,1)] peer-data-[state=checked]:-translate-x-full peer-data-[state=unchecked]:invisible peer-data-[state=checked]:rtl:translate-x-full\"><span class=\"text-[10px] font-medium uppercase\">On</span></span></div><Label htmlfor=\"${id}\" class=\"sr-only\">Labeled switch\n      </Label></div>\n</template>"
        },
        {
          "path": "registry/default/components/switch/switch-14.wxml",
          "target": "components/ui/switch-14/switch-14.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><view class=\"relative inline-grid h-9 grid-cols-[1fr_1fr] items-center text-sm font-medium\"><switch id=\"{{id}}\" checked=\"{{checked}}\" oncheckedchange=\"{{setChecked}}\" class=\"peer data-[state=unchecked]:bg-input/50 absolute inset-0 h-[inherit] w-auto rounded-md [&_span]:z-10 [&_span]:h-full [&_span]:w-1/2 [&_span]:rounded-sm [&_span]:transition-transform [&_span]:duration-300 [&_span]:ease-[cubic-bezier(0.16,1,0.3,1)] [&_span]:data-[state=checked]:translate-x-full [&_span]:data-[state=checked]:rtl:-translate-x-full\" /><text class=\"pointer-events-none relative ms-0.5 flex items-center justify-center px-2 text-center transition-transform duration-300 ease-[cubic-bezier(0.16,1,0.3,1)] peer-data-[state=checked]:invisible peer-data-[state=unchecked]:translate-x-full peer-data-[state=unchecked]:rtl:-translate-x-full\"><text class=\"text-[10px] font-medium uppercase\">Off</text></text><text class=\"peer-data-[state=checked]:text-background pointer-events-none relative me-0.5 flex items-center justify-center px-2 text-center transition-transform duration-300 ease-[cubic-bezier(0.16,1,0.3,1)] peer-data-[state=checked]:-translate-x-full peer-data-[state=unchecked]:invisible peer-data-[state=checked]:rtl:translate-x-full\"><text class=\"text-[10px] font-medium uppercase\">On</text></text></view><label htmlfor=\"{{id}}\" class=\"sr-only\">Labeled switch\n      </label></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "switch",
          "label",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "switch-14",
          "group": "switch",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "switch-14",
              "path": "registry/default/components/switch/switch-14.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "switch-14",
              "path": "registry/default/components/switch/switch-14.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "switch-14",
              "path": "registry/default/components/switch/switch-14.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "switch-14",
              "path": "registry/default/components/switch/switch-14.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "switch",
        "title": "Switch · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "switch"
      ]
    },
    {
      "name": "switch-15",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/switch.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/switch/switch-15.tsx",
          "type": "registry:component",
          "target": "components/ui/switch-15.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Switch } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\">\n      <Switch\n        id={id}\n        className=\"order-1 h-4 w-6 after:absolute after:inset-0 [&_span]:size-3 data-[state=checked]:[&_span]:translate-x-2 data-[state=checked]:[&_span]:rtl:-translate-x-2\"\n        aria-describedby={`${id}-description`}\n      />\n      <div className=\"grid grow gap-2\">\n        <Label htmlFor={id}>\n          Label{' '}\n          <span className=\"text-muted-foreground text-xs leading-[inherit] font-normal\">\n            (Sublabel)\n          </span>\n        </Label>\n        <p id={`${id}-description`} className=\"text-muted-foreground text-xs\">\n          A short description goes here.\n        </p>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/switch/switch-15.vue",
          "target": "components/ui/switch-15.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Switch } from '@timui/vue';\n\n\n\n\n\nconst id = 'switch-15';\n\n</script>\n\n<template>\n  <div class=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\"><Switch :id=\"id\" class=\"order-1 h-4 w-6 after:absolute after:inset-0 [&_span]:size-3 data-[state=checked]:[&_span]:translate-x-2 data-[state=checked]:[&_span]:rtl:-translate-x-2\" :aria-describedby=\"`${id}-description`\" /><div class=\"grid grow gap-2\"><Label :htmlFor=\"id\">Label{{ ' ' }}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n          </span></Label><p :id=\"`${id}-description`\" class=\"text-muted-foreground text-xs\">A short description goes here.\n        </p></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/switch/switch-15.html",
          "target": "components/ui/switch-15.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\"><Switch id=\"${id}\" class=\"order-1 h-4 w-6 after:absolute after:inset-0 [&_span]:size-3 data-[state=checked]:[&_span]:translate-x-2 data-[state=checked]:[&_span]:rtl:-translate-x-2\" aria-describedby=\"${`${id}-description`}\" /><div class=\"grid grow gap-2\"><Label htmlfor=\"${id}\">Label${' '}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n          </span></Label><p id=\"${`${id}-description`}\" class=\"text-muted-foreground text-xs\">A short description goes here.\n        </p></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/switch/switch-15.wxml",
          "target": "components/ui/switch-15/switch-15.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\"><switch id=\"{{id}}\" class=\"order-1 h-4 w-6 after:absolute after:inset-0 [&_span]:size-3 data-[state=checked]:[&_span]:translate-x-2 data-[state=checked]:[&_span]:rtl:-translate-x-2\" aria-describedby=\"{{`${id}-description`}}\" /><view class=\"grid grow gap-2\"><label htmlfor=\"{{id}}\">Label{{ ' ' }}<text class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n          </text></label><text id=\"{{`${id}-description`}}\" class=\"text-muted-foreground text-xs\">A short description goes here.\n        </text></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "switch",
          "label",
          "card",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "switch-15",
          "group": "switch",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "switch-15",
              "path": "registry/default/components/switch/switch-15.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "switch-15",
              "path": "registry/default/components/switch/switch-15.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "switch-15",
              "path": "registry/default/components/switch/switch-15.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "switch-15",
              "path": "registry/default/components/switch/switch-15.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "switch",
        "title": "Switch · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "switch"
      ]
    },
    {
      "name": "switch-16",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/switch.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/switch/switch-16.tsx",
          "type": "registry:component",
          "target": "components/ui/switch-16.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Switch } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\">\n      <Switch\n        id={id}\n        className=\"order-1 h-4 w-6 after:absolute after:inset-0 [&_span]:size-3 data-[state=checked]:[&_span]:translate-x-2 data-[state=checked]:[&_span]:rtl:-translate-x-2\"\n        aria-describedby={`${id}-description`}\n      />\n      <div className=\"flex grow items-start gap-3\">\n        <svg\n          className=\"shrink-0\"\n          width={32}\n          height={24}\n          viewBox=\"0 0 32 24\"\n          xmlns=\"http://www.w3.org/2000/svg\"\n          aria-hidden=\"true\"\n        >\n          <rect width=\"32\" height=\"24\" rx=\"4\" fill=\"#252525\" />\n          <path d=\"M19.0537 6.49742H12.9282V17.5026H19.0537V6.49742Z\" fill=\"#FF5A00\" />\n          <path\n            d=\"M13.3359 12C13.3359 9.76408 14.3871 7.77961 16 6.49741C14.8129 5.56408 13.3155 5 11.6822 5C7.81295 5 4.68221 8.13074 4.68221 12C4.68221 15.8693 7.81295 19 11.6822 19C13.3155 19 14.8129 18.4359 16 17.5026C14.3848 16.2385 13.3359 14.2359 13.3359 12Z\"\n            fill=\"#EB001B\"\n          />\n          <path\n            d=\"M27.3178 12C27.3178 15.8693 24.1871 19 20.3178 19C18.6845 19 17.1871 18.4359 16 17.5026C17.6333 16.2181 18.6641 14.2359 18.6641 12C18.6641 9.76408 17.6129 7.77961 16 6.49741C17.1848 5.56408 18.6822 5 20.3155 5C24.1871 5 27.3178 8.15113 27.3178 12Z\"\n            fill=\"#F79E1B\"\n          />\n        </svg>\n        <div className=\"grid grow gap-2\">\n          <Label htmlFor={id}>\n            Label{' '}\n            <span className=\"text-muted-foreground text-xs leading-[inherit] font-normal\">\n              (Sublabel)\n            </span>\n          </Label>\n          <p id={`${id}-description`} className=\"text-muted-foreground text-xs\">\n            A short description goes here.\n          </p>\n        </div>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/switch/switch-16.vue",
          "target": "components/ui/switch-16.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Switch } from '@timui/vue';\n\n\n\n\n\nconst id = 'switch-16';\n\n</script>\n\n<template>\n  <div class=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\"><Switch :id=\"id\" class=\"order-1 h-4 w-6 after:absolute after:inset-0 [&_span]:size-3 data-[state=checked]:[&_span]:translate-x-2 data-[state=checked]:[&_span]:rtl:-translate-x-2\" :aria-describedby=\"`${id}-description`\" /><div class=\"flex grow items-start gap-3\"><svg class=\"shrink-0\" :width=\"32\" :height=\"24\" viewBox=\"0 0 32 24\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\"><rect width=\"32\" height=\"24\" rx=\"4\" fill=\"#252525\" /><path d=\"M19.0537 6.49742H12.9282V17.5026H19.0537V6.49742Z\" fill=\"#FF5A00\" /><path d=\"M13.3359 12C13.3359 9.76408 14.3871 7.77961 16 6.49741C14.8129 5.56408 13.3155 5 11.6822 5C7.81295 5 4.68221 8.13074 4.68221 12C4.68221 15.8693 7.81295 19 11.6822 19C13.3155 19 14.8129 18.4359 16 17.5026C14.3848 16.2385 13.3359 14.2359 13.3359 12Z\" fill=\"#EB001B\" /><path d=\"M27.3178 12C27.3178 15.8693 24.1871 19 20.3178 19C18.6845 19 17.1871 18.4359 16 17.5026C17.6333 16.2181 18.6641 14.2359 18.6641 12C18.6641 9.76408 17.6129 7.77961 16 6.49741C17.1848 5.56408 18.6822 5 20.3155 5C24.1871 5 27.3178 8.15113 27.3178 12Z\" fill=\"#F79E1B\" /></svg><div class=\"grid grow gap-2\"><Label :htmlFor=\"id\">Label{{ ' ' }}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n            </span></Label><p :id=\"`${id}-description`\" class=\"text-muted-foreground text-xs\">A short description goes here.\n          </p></div></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/switch/switch-16.html",
          "target": "components/ui/switch-16.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\"><Switch id=\"${id}\" class=\"order-1 h-4 w-6 after:absolute after:inset-0 [&_span]:size-3 data-[state=checked]:[&_span]:translate-x-2 data-[state=checked]:[&_span]:rtl:-translate-x-2\" aria-describedby=\"${`${id}-description`}\" /><div class=\"flex grow items-start gap-3\"><svg class=\"shrink-0\" width=\"${32}\" height=\"${24}\" viewbox=\"0 0 32 24\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\"><rect width=\"32\" height=\"24\" rx=\"4\" fill=\"#252525\" /><path d=\"M19.0537 6.49742H12.9282V17.5026H19.0537V6.49742Z\" fill=\"#FF5A00\" /><path d=\"M13.3359 12C13.3359 9.76408 14.3871 7.77961 16 6.49741C14.8129 5.56408 13.3155 5 11.6822 5C7.81295 5 4.68221 8.13074 4.68221 12C4.68221 15.8693 7.81295 19 11.6822 19C13.3155 19 14.8129 18.4359 16 17.5026C14.3848 16.2385 13.3359 14.2359 13.3359 12Z\" fill=\"#EB001B\" /><path d=\"M27.3178 12C27.3178 15.8693 24.1871 19 20.3178 19C18.6845 19 17.1871 18.4359 16 17.5026C17.6333 16.2181 18.6641 14.2359 18.6641 12C18.6641 9.76408 17.6129 7.77961 16 6.49741C17.1848 5.56408 18.6822 5 20.3155 5C24.1871 5 27.3178 8.15113 27.3178 12Z\" fill=\"#F79E1B\" /></svg><div class=\"grid grow gap-2\"><Label htmlfor=\"${id}\">Label${' '}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n            </span></Label><p id=\"${`${id}-description`}\" class=\"text-muted-foreground text-xs\">A short description goes here.\n          </p></div></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/switch/switch-16.wxml",
          "target": "components/ui/switch-16/switch-16.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\"><switch id=\"{{id}}\" class=\"order-1 h-4 w-6 after:absolute after:inset-0 [&_span]:size-3 data-[state=checked]:[&_span]:translate-x-2 data-[state=checked]:[&_span]:rtl:-translate-x-2\" aria-describedby=\"{{`${id}-description`}}\" /><view class=\"flex grow items-start gap-3\"><svg class=\"shrink-0\" width=\"{{32}}\" height=\"{{24}}\" viewbox=\"0 0 32 24\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\"><rect width=\"32\" height=\"24\" rx=\"4\" fill=\"#252525\" /><path d=\"M19.0537 6.49742H12.9282V17.5026H19.0537V6.49742Z\" fill=\"#FF5A00\" /><path d=\"M13.3359 12C13.3359 9.76408 14.3871 7.77961 16 6.49741C14.8129 5.56408 13.3155 5 11.6822 5C7.81295 5 4.68221 8.13074 4.68221 12C4.68221 15.8693 7.81295 19 11.6822 19C13.3155 19 14.8129 18.4359 16 17.5026C14.3848 16.2385 13.3359 14.2359 13.3359 12Z\" fill=\"#EB001B\" /><path d=\"M27.3178 12C27.3178 15.8693 24.1871 19 20.3178 19C18.6845 19 17.1871 18.4359 16 17.5026C17.6333 16.2181 18.6641 14.2359 18.6641 12C18.6641 9.76408 17.6129 7.77961 16 6.49741C17.1848 5.56408 18.6822 5 20.3155 5C24.1871 5 27.3178 8.15113 27.3178 12Z\" fill=\"#F79E1B\" /></svg><view class=\"grid grow gap-2\"><label htmlfor=\"{{id}}\">Label{{ ' ' }}<text class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n            </text></label><text id=\"{{`${id}-description`}}\" class=\"text-muted-foreground text-xs\">A short description goes here.\n          </text></view></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "switch",
          "label",
          "card",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "switch-16",
          "group": "switch",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "switch-16",
              "path": "registry/default/components/switch/switch-16.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "switch-16",
              "path": "registry/default/components/switch/switch-16.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "switch-16",
              "path": "registry/default/components/switch/switch-16.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "switch-16",
              "path": "registry/default/components/switch/switch-16.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "switch",
        "title": "Switch · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "switch"
      ]
    },
    {
      "name": "switch-17",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/switch.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/switch/switch-17.tsx",
          "type": "registry:component",
          "target": "components/ui/switch-17.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Switch } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\">\n      <Switch\n        id={id}\n        className=\"order-1 h-4 w-6 after:absolute after:inset-0 [&_span]:size-3 data-[state=checked]:[&_span]:translate-x-2 data-[state=checked]:[&_span]:rtl:-translate-x-2\"\n        aria-describedby={`${id}-description`}\n      />\n      <div className=\"flex grow items-center gap-3\">\n        <svg\n          className=\"shrink-0\"\n          xmlns=\"http://www.w3.org/2000/svg\"\n          width={32}\n          height={32}\n          aria-hidden=\"true\"\n        >\n          <circle cx=\"16\" cy=\"16\" r=\"16\" fill=\"#121212\" />\n          <g clipPath=\"url(#sb-a)\">\n            <path\n              fill=\"url(#sb-b)\"\n              d=\"M17.63 25.52c-.506.637-1.533.287-1.545-.526l-.178-11.903h8.003c1.45 0 2.259 1.674 1.357 2.81l-7.637 9.618Z\"\n            />\n            <path\n              fill=\"url(#sb-c)\"\n              fillOpacity=\".2\"\n              d=\"M17.63 25.52c-.506.637-1.533.287-1.545-.526l-.178-11.903h8.003c1.45 0 2.259 1.674 1.357 2.81l-7.637 9.618Z\"\n            />\n            <path\n              fill=\"#3ECF8E\"\n              d=\"M14.375 6.367c.506-.638 1.532-.289 1.544.525l.078 11.903H8.094c-1.45 0-2.258-1.674-1.357-2.81l7.638-9.618Z\"\n            />\n          </g>\n          <defs>\n            <linearGradient\n              id=\"sb-b\"\n              x1=\"15.907\"\n              x2=\"23.02\"\n              y1=\"15.73\"\n              y2=\"18.713\"\n              gradientUnits=\"userSpaceOnUse\"\n            >\n              <stop stopColor=\"#249361\" />\n              <stop offset=\"1\" stopColor=\"#3ECF8E\" />\n            </linearGradient>\n            <linearGradient\n              id=\"sb-c\"\n              x1=\"12.753\"\n              x2=\"15.997\"\n              y1=\"11.412\"\n              y2=\"17.519\"\n              gradientUnits=\"userSpaceOnUse\"\n            >\n              <stop />\n              <stop offset=\"1\" stopOpacity=\"0\" />\n            </linearGradient>\n            <clipPath id=\"sb-a\">\n              <path fill=\"#fff\" d=\"M6.354 6h19.292v20H6.354z\" />\n            </clipPath>\n          </defs>\n        </svg>\n        <div className=\"grid grow gap-2\">\n          <Label htmlFor={id}>\n            Label{' '}\n            <span className=\"text-muted-foreground text-xs leading-[inherit] font-normal\">\n              (Sublabel)\n            </span>\n          </Label>\n          <p id={`${id}-description`} className=\"text-muted-foreground text-xs\">\n            A short description goes here.\n          </p>\n        </div>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/switch/switch-17.vue",
          "target": "components/ui/switch-17.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Switch } from '@timui/vue';\n\n\n\n\n\nconst id = 'switch-17';\n\n</script>\n\n<template>\n  <div class=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\"><Switch :id=\"id\" class=\"order-1 h-4 w-6 after:absolute after:inset-0 [&_span]:size-3 data-[state=checked]:[&_span]:translate-x-2 data-[state=checked]:[&_span]:rtl:-translate-x-2\" :aria-describedby=\"`${id}-description`\" /><div class=\"flex grow items-center gap-3\"><svg class=\"shrink-0\" xmlns=\"http://www.w3.org/2000/svg\" :width=\"32\" :height=\"32\" aria-hidden=\"true\"><circle cx=\"16\" cy=\"16\" r=\"16\" fill=\"#121212\" /><g clipPath=\"url(#sb-a)\"><path fill=\"url(#sb-b)\" d=\"M17.63 25.52c-.506.637-1.533.287-1.545-.526l-.178-11.903h8.003c1.45 0 2.259 1.674 1.357 2.81l-7.637 9.618Z\" /><path fill=\"url(#sb-c)\" fillOpacity=\".2\" d=\"M17.63 25.52c-.506.637-1.533.287-1.545-.526l-.178-11.903h8.003c1.45 0 2.259 1.674 1.357 2.81l-7.637 9.618Z\" /><path fill=\"#3ECF8E\" d=\"M14.375 6.367c.506-.638 1.532-.289 1.544.525l.078 11.903H8.094c-1.45 0-2.258-1.674-1.357-2.81l7.638-9.618Z\" /></g><defs><linearGradient id=\"sb-b\" x1=\"15.907\" x2=\"23.02\" y1=\"15.73\" y2=\"18.713\" gradientUnits=\"userSpaceOnUse\"><stop stopColor=\"#249361\" /><stop offset=\"1\" stopColor=\"#3ECF8E\" /></linearGradient><linearGradient id=\"sb-c\" x1=\"12.753\" x2=\"15.997\" y1=\"11.412\" y2=\"17.519\" gradientUnits=\"userSpaceOnUse\"><stop /><stop offset=\"1\" stopOpacity=\"0\" /></linearGradient><clipPath id=\"sb-a\"><path fill=\"#fff\" d=\"M6.354 6h19.292v20H6.354z\" /></clipPath></defs></svg><div class=\"grid grow gap-2\"><Label :htmlFor=\"id\">Label{{ ' ' }}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n            </span></Label><p :id=\"`${id}-description`\" class=\"text-muted-foreground text-xs\">A short description goes here.\n          </p></div></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/switch/switch-17.html",
          "target": "components/ui/switch-17.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\"><Switch id=\"${id}\" class=\"order-1 h-4 w-6 after:absolute after:inset-0 [&_span]:size-3 data-[state=checked]:[&_span]:translate-x-2 data-[state=checked]:[&_span]:rtl:-translate-x-2\" aria-describedby=\"${`${id}-description`}\" /><div class=\"flex grow items-center gap-3\"><svg class=\"shrink-0\" xmlns=\"http://www.w3.org/2000/svg\" width=\"${32}\" height=\"${32}\" aria-hidden=\"true\"><circle cx=\"16\" cy=\"16\" r=\"16\" fill=\"#121212\" /><g clippath=\"url(#sb-a)\"><path fill=\"url(#sb-b)\" d=\"M17.63 25.52c-.506.637-1.533.287-1.545-.526l-.178-11.903h8.003c1.45 0 2.259 1.674 1.357 2.81l-7.637 9.618Z\" /><path fill=\"url(#sb-c)\" fillopacity=\".2\" d=\"M17.63 25.52c-.506.637-1.533.287-1.545-.526l-.178-11.903h8.003c1.45 0 2.259 1.674 1.357 2.81l-7.637 9.618Z\" /><path fill=\"#3ECF8E\" d=\"M14.375 6.367c.506-.638 1.532-.289 1.544.525l.078 11.903H8.094c-1.45 0-2.258-1.674-1.357-2.81l7.638-9.618Z\" /></g><defs><linearGradient id=\"sb-b\" x1=\"15.907\" x2=\"23.02\" y1=\"15.73\" y2=\"18.713\" gradientunits=\"userSpaceOnUse\"><stop stopcolor=\"#249361\" /><stop offset=\"1\" stopcolor=\"#3ECF8E\" /></linearGradient><linearGradient id=\"sb-c\" x1=\"12.753\" x2=\"15.997\" y1=\"11.412\" y2=\"17.519\" gradientunits=\"userSpaceOnUse\"><stop /><stop offset=\"1\" stopopacity=\"0\" /></linearGradient><clipPath id=\"sb-a\"><path fill=\"#fff\" d=\"M6.354 6h19.292v20H6.354z\" /></clipPath></defs></svg><div class=\"grid grow gap-2\"><Label htmlfor=\"${id}\">Label${' '}<span class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n            </span></Label><p id=\"${`${id}-description`}\" class=\"text-muted-foreground text-xs\">A short description goes here.\n          </p></div></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/switch/switch-17.wxml",
          "target": "components/ui/switch-17/switch-17.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none\"><switch id=\"{{id}}\" class=\"order-1 h-4 w-6 after:absolute after:inset-0 [&_span]:size-3 data-[state=checked]:[&_span]:translate-x-2 data-[state=checked]:[&_span]:rtl:-translate-x-2\" aria-describedby=\"{{`${id}-description`}}\" /><view class=\"flex grow items-center gap-3\"><svg class=\"shrink-0\" xmlns=\"http://www.w3.org/2000/svg\" width=\"{{32}}\" height=\"{{32}}\" aria-hidden=\"true\"><circle cx=\"16\" cy=\"16\" r=\"16\" fill=\"#121212\" /><g clippath=\"url(#sb-a)\"><path fill=\"url(#sb-b)\" d=\"M17.63 25.52c-.506.637-1.533.287-1.545-.526l-.178-11.903h8.003c1.45 0 2.259 1.674 1.357 2.81l-7.637 9.618Z\" /><path fill=\"url(#sb-c)\" fillopacity=\".2\" d=\"M17.63 25.52c-.506.637-1.533.287-1.545-.526l-.178-11.903h8.003c1.45 0 2.259 1.674 1.357 2.81l-7.637 9.618Z\" /><path fill=\"#3ECF8E\" d=\"M14.375 6.367c.506-.638 1.532-.289 1.544.525l.078 11.903H8.094c-1.45 0-2.258-1.674-1.357-2.81l7.638-9.618Z\" /></g><defs><lineargradient id=\"sb-b\" x1=\"15.907\" x2=\"23.02\" y1=\"15.73\" y2=\"18.713\" gradientunits=\"userSpaceOnUse\"><stop stopcolor=\"#249361\" /><stop offset=\"1\" stopcolor=\"#3ECF8E\" /></lineargradient><lineargradient id=\"sb-c\" x1=\"12.753\" x2=\"15.997\" y1=\"11.412\" y2=\"17.519\" gradientunits=\"userSpaceOnUse\"><stop /><stop offset=\"1\" stopopacity=\"0\" /></lineargradient><clippath id=\"sb-a\"><path fill=\"#fff\" d=\"M6.354 6h19.292v20H6.354z\" /></clippath></defs></svg><view class=\"grid grow gap-2\"><label htmlfor=\"{{id}}\">Label{{ ' ' }}<text class=\"text-muted-foreground text-xs leading-[inherit] font-normal\">(Sublabel)\n            </text></label><text id=\"{{`${id}-description`}}\" class=\"text-muted-foreground text-xs\">A short description goes here.\n          </text></view></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "switch",
          "label",
          "card",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "switch-17",
          "group": "switch",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "switch-17",
              "path": "registry/default/components/switch/switch-17.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "switch-17",
              "path": "registry/default/components/switch/switch-17.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "switch-17",
              "path": "registry/default/components/switch/switch-17.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "switch-17",
              "path": "registry/default/components/switch/switch-17.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "switch",
        "title": "Switch · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "switch"
      ]
    },
    {
      "name": "select-01",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select-native.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-01.tsx",
          "type": "registry:component",
          "target": "components/ui/select-01.tsx",
          "content": "import { useId } from 'react'\nimport { Label, SelectNative } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Simple select (native)</Label>\n      <SelectNative id={id}>\n        <option value=\"1\">React</option>\n        <option value=\"2\">Next.js</option>\n        <option value=\"3\">Astro</option>\n        <option value=\"4\">Gatsby</option>\n      </SelectNative>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-01.vue",
          "target": "components/ui/select-01.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { SelectNative } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-01';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Simple select (native)</Label><SelectNative :id=\"id\"><option value=\"1\">React</option><option value=\"2\">Next.js</option><option value=\"3\">Astro</option><option value=\"4\">Gatsby</option></SelectNative></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-01.html",
          "target": "components/ui/select-01.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Simple select (native)</Label><SelectNative id=\"${id}\"><option value=\"1\">React</option><option value=\"2\">Next.js</option><option value=\"3\">Astro</option><option value=\"4\">Gatsby</option></SelectNative></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-01.wxml",
          "target": "components/ui/select-01/select-01.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Simple select (native)</label><selectnative id=\"{{id}}\"><option value=\"1\">React</option><option value=\"2\">Next.js</option><option value=\"3\">Astro</option><option value=\"4\">Gatsby</option></selectnative></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "native select"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-01",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-01",
              "path": "registry/default/components/select/select-01.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-01",
              "path": "registry/default/components/select/select-01.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-01",
              "path": "registry/default/components/select/select-01.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-01",
              "path": "registry/default/components/select/select-01.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-02",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select-native.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-02.tsx",
          "type": "registry:component",
          "target": "components/ui/select-02.tsx",
          "content": "import { useId } from 'react'\nimport { Label, SelectNative } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Select with placeholder (native)</Label>\n      <SelectNative id={id} defaultValue=\"\">\n        <option value=\"\" disabled>\n          Please select a value\n        </option>\n        <option value=\"1\">1 to 5</option>\n        <option value=\"2\">5 to 10</option>\n        <option value=\"3\">More than 10</option>\n      </SelectNative>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-02.vue",
          "target": "components/ui/select-02.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { SelectNative } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-02';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Select with placeholder (native)</Label><SelectNative :id=\"id\" default-value=\"\"><option value=\"\" disabled>Please select a value\n        </option><option value=\"1\">1 to 5</option><option value=\"2\">5 to 10</option><option value=\"3\">More than 10</option></SelectNative></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-02.html",
          "target": "components/ui/select-02.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Select with placeholder (native)</Label><SelectNative id=\"${id}\" default-value=\"\"><option value=\"\" disabled>Please select a value\n        </option><option value=\"1\">1 to 5</option><option value=\"2\">5 to 10</option><option value=\"3\">More than 10</option></SelectNative></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-02.wxml",
          "target": "components/ui/select-02/select-02.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Select with placeholder (native)</label><selectnative id=\"{{id}}\" default-value=\"\"><option value=\"\" disabled>Please select a value\n        </option><option value=\"1\">1 to 5</option><option value=\"2\">5 to 10</option><option value=\"3\">More than 10</option></selectnative></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "native select"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-02",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-02",
              "path": "registry/default/components/select/select-02.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-02",
              "path": "registry/default/components/select/select-02.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-02",
              "path": "registry/default/components/select/select-02.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-02",
              "path": "registry/default/components/select/select-02.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-03",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select-native.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-03.tsx",
          "type": "registry:component",
          "target": "components/ui/select-03.tsx",
          "content": "import { useId } from 'react'\nimport { Label, SelectNative } from '@timui/react'\nimport { ClockIcon } from 'lucide-react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Select with icon (native)</Label>\n      <div className=\"group relative\">\n        <SelectNative id={id} className=\"ps-9\">\n          <option value=\"1\">00:00 AM - 11:59 PM</option>\n          <option value=\"2\">01:00 AM - 12:59 PM</option>\n          <option value=\"3\">02:00 AM - 01:59 PM</option>\n          <option value=\"4\">03:00 AM - 02:59 PM</option>\n        </SelectNative>\n        <div className=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 group-has-[select[disabled]]:opacity-50\">\n          <ClockIcon size={16} aria-hidden=\"true\" />\n        </div>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-03.vue",
          "target": "components/ui/select-03.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ClockIcon } from 'lucide-vue-next';\nimport { Label } from '@timui/vue';\nimport { SelectNative } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-03';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Select with icon (native)</Label><div class=\"group relative\"><SelectNative :id=\"id\" class=\"ps-9\"><option value=\"1\">00:00 AM - 11:59 PM</option><option value=\"2\">01:00 AM - 12:59 PM</option><option value=\"3\">02:00 AM - 01:59 PM</option><option value=\"4\">03:00 AM - 02:59 PM</option></SelectNative><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 group-has-[select[disabled]]:opacity-50\"><ClockIcon :size=\"16\" aria-hidden=\"true\" /></div></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-03.html",
          "target": "components/ui/select-03.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Select with icon (native)</Label><div class=\"group relative\"><SelectNative id=\"${id}\" class=\"ps-9\"><option value=\"1\">00:00 AM - 11:59 PM</option><option value=\"2\">01:00 AM - 12:59 PM</option><option value=\"3\">02:00 AM - 01:59 PM</option><option value=\"4\">03:00 AM - 02:59 PM</option></SelectNative><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 group-has-[select[disabled]]:opacity-50\"><ClockIcon size=\"${16}\" aria-hidden=\"true\" /></div></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-03.wxml",
          "target": "components/ui/select-03/select-03.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Select with icon (native)</label><view class=\"group relative\"><selectnative id=\"{{id}}\" class=\"ps-9\"><option value=\"1\">00:00 AM - 11:59 PM</option><option value=\"2\">01:00 AM - 12:59 PM</option><option value=\"3\">02:00 AM - 01:59 PM</option><option value=\"4\">03:00 AM - 02:59 PM</option></selectnative><view class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 group-has-[select[disabled]]:opacity-50\"><clockicon size=\"{{16}}\" aria-hidden=\"true\" /></view></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "native select",
          "time"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-03",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-03",
              "path": "registry/default/components/select/select-03.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-03",
              "path": "registry/default/components/select/select-03.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-03",
              "path": "registry/default/components/select/select-03.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-03",
              "path": "registry/default/components/select/select-03.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-04",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select-native.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-04.tsx",
          "type": "registry:component",
          "target": "components/ui/select-04.tsx",
          "content": "import { useId } from 'react'\nimport { Label, SelectNative } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Select with helper text (native)</Label>\n      <SelectNative id={id}>\n        <option value=\"1\">React</option>\n        <option value=\"2\">Next.js</option>\n        <option value=\"3\">Astro</option>\n        <option value=\"4\">Gatsby</option>\n      </SelectNative>\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Tell us what&lsquo;s your favorite Select framework\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-04.vue",
          "target": "components/ui/select-04.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { SelectNative } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-04';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Select with helper text (native)</Label><SelectNative :id=\"id\"><option value=\"1\">React</option><option value=\"2\">Next.js</option><option value=\"3\">Astro</option><option value=\"4\">Gatsby</option></SelectNative><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Tell us what&lsquo;s your favorite Select framework\n      </p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-04.html",
          "target": "components/ui/select-04.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Select with helper text (native)</Label><SelectNative id=\"${id}\"><option value=\"1\">React</option><option value=\"2\">Next.js</option><option value=\"3\">Astro</option><option value=\"4\">Gatsby</option></SelectNative><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Tell us what&lsquo;s your favorite Select framework\n      </p></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-04.wxml",
          "target": "components/ui/select-04/select-04.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Select with helper text (native)</label><selectnative id=\"{{id}}\"><option value=\"1\">React</option><option value=\"2\">Next.js</option><option value=\"3\">Astro</option><option value=\"4\">Gatsby</option></selectnative><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Tell us what&lsquo;s your favorite Select framework\n      </text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "native select"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-04",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-04",
              "path": "registry/default/components/select/select-04.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-04",
              "path": "registry/default/components/select/select-04.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-04",
              "path": "registry/default/components/select/select-04.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-04",
              "path": "registry/default/components/select/select-04.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-05",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select-native.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-05.tsx",
          "type": "registry:component",
          "target": "components/ui/select-05.tsx",
          "content": "import { useId } from 'react'\nimport { Label, SelectNative } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"[--ring:var(--color-indigo-300)] *:not-first:mt-2 in-[.dark]:[--ring:var(--color-indigo-900)]\">\n      <Label htmlFor={id}>Select with colored border (native)</Label>\n      <SelectNative id={id}>\n        <option value=\"1\">React</option>\n        <option value=\"2\">Next.js</option>\n        <option value=\"3\">Astro</option>\n        <option value=\"4\">Gatsby</option>\n      </SelectNative>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-05.vue",
          "target": "components/ui/select-05.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { SelectNative } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-05';\n\n</script>\n\n<template>\n  <div class=\"[--ring:var(--color-indigo-300)] *:not-first:mt-2 in-[.dark]:[--ring:var(--color-indigo-900)]\"><Label :htmlFor=\"id\">Select with colored border (native)</Label><SelectNative :id=\"id\"><option value=\"1\">React</option><option value=\"2\">Next.js</option><option value=\"3\">Astro</option><option value=\"4\">Gatsby</option></SelectNative></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-05.html",
          "target": "components/ui/select-05.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"[--ring:var(--color-indigo-300)] *:not-first:mt-2 in-[.dark]:[--ring:var(--color-indigo-900)]\"><Label htmlfor=\"${id}\">Select with colored border (native)</Label><SelectNative id=\"${id}\"><option value=\"1\">React</option><option value=\"2\">Next.js</option><option value=\"3\">Astro</option><option value=\"4\">Gatsby</option></SelectNative></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-05.wxml",
          "target": "components/ui/select-05/select-05.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"[--ring:var(--color-indigo-300)] *:not-first:mt-2 in-[.dark]:[--ring:var(--color-indigo-900)]\"><label htmlfor=\"{{id}}\">Select with colored border (native)</label><selectnative id=\"{{id}}\"><option value=\"1\">React</option><option value=\"2\">Next.js</option><option value=\"3\">Astro</option><option value=\"4\">Gatsby</option></selectnative></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "native select"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-05",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-05",
              "path": "registry/default/components/select/select-05.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-05",
              "path": "registry/default/components/select/select-05.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-05",
              "path": "registry/default/components/select/select-05.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-05",
              "path": "registry/default/components/select/select-05.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-06",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select-native.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-06.tsx",
          "type": "registry:component",
          "target": "components/ui/select-06.tsx",
          "content": "import { useId } from 'react'\nimport { Label, SelectNative } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Select with error (native)</Label>\n      <SelectNative id={id} aria-invalid>\n        <option value=\"1\">React</option>\n        <option value=\"2\">Next.js</option>\n        <option value=\"3\">Astro</option>\n        <option value=\"4\">Gatsby</option>\n      </SelectNative>\n      <p className=\"text-destructive mt-2 text-xs\" role=\"alert\" aria-live=\"polite\">\n        Selected option is invalid\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-06.vue",
          "target": "components/ui/select-06.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { SelectNative } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-06';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Select with error (native)</Label><SelectNative :id=\"id\" aria-invalid><option value=\"1\">React</option><option value=\"2\">Next.js</option><option value=\"3\">Astro</option><option value=\"4\">Gatsby</option></SelectNative><p class=\"text-destructive mt-2 text-xs\" role=\"alert\" aria-live=\"polite\">Selected option is invalid\n      </p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-06.html",
          "target": "components/ui/select-06.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Select with error (native)</Label><SelectNative id=\"${id}\" aria-invalid><option value=\"1\">React</option><option value=\"2\">Next.js</option><option value=\"3\">Astro</option><option value=\"4\">Gatsby</option></SelectNative><p class=\"text-destructive mt-2 text-xs\" role=\"alert\" aria-live=\"polite\">Selected option is invalid\n      </p></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-06.wxml",
          "target": "components/ui/select-06/select-06.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Select with error (native)</label><selectnative id=\"{{id}}\" aria-invalid><option value=\"1\">React</option><option value=\"2\">Next.js</option><option value=\"3\">Astro</option><option value=\"4\">Gatsby</option></selectnative><text class=\"text-destructive mt-2 text-xs\" role=\"alert\" aria-live=\"polite\">Selected option is invalid\n      </text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "native select",
          "error"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-06",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-06",
              "path": "registry/default/components/select/select-06.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-06",
              "path": "registry/default/components/select/select-06.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-06",
              "path": "registry/default/components/select/select-06.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-06",
              "path": "registry/default/components/select/select-06.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-07",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select-native.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-07.tsx",
          "type": "registry:component",
          "target": "components/ui/select-07.tsx",
          "content": "import { useId } from 'react'\nimport { Label, SelectNative } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Select with gray background (native)</Label>\n      <SelectNative id={id} className=\"bg-muted border-transparent shadow-none\">\n        <option value=\"1\">React</option>\n        <option value=\"2\">Next.js</option>\n        <option value=\"3\">Astro</option>\n        <option value=\"4\">Gatsby</option>\n      </SelectNative>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-07.vue",
          "target": "components/ui/select-07.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { SelectNative } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-07';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Select with gray background (native)</Label><SelectNative :id=\"id\" class=\"bg-muted border-transparent shadow-none\"><option value=\"1\">React</option><option value=\"2\">Next.js</option><option value=\"3\">Astro</option><option value=\"4\">Gatsby</option></SelectNative></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-07.html",
          "target": "components/ui/select-07.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Select with gray background (native)</Label><SelectNative id=\"${id}\" class=\"bg-muted border-transparent shadow-none\"><option value=\"1\">React</option><option value=\"2\">Next.js</option><option value=\"3\">Astro</option><option value=\"4\">Gatsby</option></SelectNative></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-07.wxml",
          "target": "components/ui/select-07/select-07.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Select with gray background (native)</label><selectnative id=\"{{id}}\" class=\"bg-muted border-transparent shadow-none\"><option value=\"1\">React</option><option value=\"2\">Next.js</option><option value=\"3\">Astro</option><option value=\"4\">Gatsby</option></selectnative></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "native select"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-07",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-07",
              "path": "registry/default/components/select/select-07.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-07",
              "path": "registry/default/components/select/select-07.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-07",
              "path": "registry/default/components/select/select-07.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-07",
              "path": "registry/default/components/select/select-07.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-08",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select-native.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-08.tsx",
          "type": "registry:component",
          "target": "components/ui/select-08.tsx",
          "content": "import { useId } from 'react'\nimport { Label, SelectNative } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Disabled select (native)</Label>\n      <SelectNative id={id} disabled>\n        <option value=\"1\">React</option>\n        <option value=\"2\">Next.js</option>\n        <option value=\"3\">Astro</option>\n        <option value=\"4\">Gatsby</option>\n      </SelectNative>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-08.vue",
          "target": "components/ui/select-08.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { SelectNative } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-08';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Disabled select (native)</Label><SelectNative :id=\"id\" disabled><option value=\"1\">React</option><option value=\"2\">Next.js</option><option value=\"3\">Astro</option><option value=\"4\">Gatsby</option></SelectNative></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-08.html",
          "target": "components/ui/select-08.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Disabled select (native)</Label><SelectNative id=\"${id}\" disabled><option value=\"1\">React</option><option value=\"2\">Next.js</option><option value=\"3\">Astro</option><option value=\"4\">Gatsby</option></SelectNative></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-08.wxml",
          "target": "components/ui/select-08/select-08.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Disabled select (native)</label><selectnative id=\"{{id}}\" disabled><option value=\"1\">React</option><option value=\"2\">Next.js</option><option value=\"3\">Astro</option><option value=\"4\">Gatsby</option></selectnative></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "native select",
          "disabled"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-08",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-08",
              "path": "registry/default/components/select/select-08.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-08",
              "path": "registry/default/components/select/select-08.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-08",
              "path": "registry/default/components/select/select-08.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-08",
              "path": "registry/default/components/select/select-08.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-09",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select-native.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-09.tsx",
          "type": "registry:component",
          "target": "components/ui/select-09.tsx",
          "content": "import { useId } from 'react'\nimport { Label, SelectNative } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>\n        Required select (native) <span className=\"text-destructive\">*</span>\n      </Label>\n      <SelectNative id={id}>\n        <option value=\"1\">React</option>\n        <option value=\"2\">Next.js</option>\n        <option value=\"3\">Astro</option>\n        <option value=\"4\">Gatsby</option>\n      </SelectNative>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-09.vue",
          "target": "components/ui/select-09.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { SelectNative } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-09';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Required select (native) <span class=\"text-destructive\">*</span></Label><SelectNative :id=\"id\"><option value=\"1\">React</option><option value=\"2\">Next.js</option><option value=\"3\">Astro</option><option value=\"4\">Gatsby</option></SelectNative></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-09.html",
          "target": "components/ui/select-09.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Required select (native) <span class=\"text-destructive\">*</span></Label><SelectNative id=\"${id}\"><option value=\"1\">React</option><option value=\"2\">Next.js</option><option value=\"3\">Astro</option><option value=\"4\">Gatsby</option></SelectNative></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-09.wxml",
          "target": "components/ui/select-09/select-09.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Required select (native) <text class=\"text-destructive\">*</text></label><selectnative id=\"{{id}}\"><option value=\"1\">React</option><option value=\"2\">Next.js</option><option value=\"3\">Astro</option><option value=\"4\">Gatsby</option></selectnative></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "native select"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-09",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-09",
              "path": "registry/default/components/select/select-09.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-09",
              "path": "registry/default/components/select/select-09.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-09",
              "path": "registry/default/components/select/select-09.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-09",
              "path": "registry/default/components/select/select-09.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-10",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select-native.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-10.tsx",
          "type": "registry:component",
          "target": "components/ui/select-10.tsx",
          "content": "import { useId } from 'react'\nimport { Label, SelectNative } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Select with auto-width (native)</Label>\n      <div className=\"w-fit\">\n        <SelectNative id={id}>\n          <option value=\"1\">React</option>\n          <option value=\"2\">Next.js</option>\n          <option value=\"3\">Astro</option>\n          <option value=\"4\">Gatsby</option>\n        </SelectNative>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-10.vue",
          "target": "components/ui/select-10.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { SelectNative } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-10';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Select with auto-width (native)</Label><div class=\"w-fit\"><SelectNative :id=\"id\"><option value=\"1\">React</option><option value=\"2\">Next.js</option><option value=\"3\">Astro</option><option value=\"4\">Gatsby</option></SelectNative></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-10.html",
          "target": "components/ui/select-10.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Select with auto-width (native)</Label><div class=\"w-fit\"><SelectNative id=\"${id}\"><option value=\"1\">React</option><option value=\"2\">Next.js</option><option value=\"3\">Astro</option><option value=\"4\">Gatsby</option></SelectNative></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-10.wxml",
          "target": "components/ui/select-10/select-10.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Select with auto-width (native)</label><view class=\"w-fit\"><selectnative id=\"{{id}}\"><option value=\"1\">React</option><option value=\"2\">Next.js</option><option value=\"3\">Astro</option><option value=\"4\">Gatsby</option></selectnative></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "native select"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-10",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-10",
              "path": "registry/default/components/select/select-10.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-10",
              "path": "registry/default/components/select/select-10.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-10",
              "path": "registry/default/components/select/select-10.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-10",
              "path": "registry/default/components/select/select-10.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-11",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select-native.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-11.tsx",
          "type": "registry:component",
          "target": "components/ui/select-11.tsx",
          "content": "import { useId } from 'react'\nimport { Label, SelectNative } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Select with option groups (native)</Label>\n      <SelectNative id={id}>\n        <optgroup label=\"Frontend\">\n          <option value=\"1\">React</option>\n          <option value=\"2\">Vue</option>\n          <option value=\"3\">Angular</option>\n        </optgroup>\n        <optgroup label=\"Backend\">\n          <option value=\"4\">Node.js</option>\n          <option value=\"5\">Python</option>\n          <option value=\"6\">Java</option>\n        </optgroup>\n      </SelectNative>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-11.vue",
          "target": "components/ui/select-11.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { SelectNative } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-11';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Select with option groups (native)</Label><SelectNative :id=\"id\"><optgroup label=\"Frontend\"><option value=\"1\">React</option><option value=\"2\">Vue</option><option value=\"3\">Angular</option></optgroup><optgroup label=\"Backend\"><option value=\"4\">Node.js</option><option value=\"5\">Python</option><option value=\"6\">Java</option></optgroup></SelectNative></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-11.html",
          "target": "components/ui/select-11.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Select with option groups (native)</Label><SelectNative id=\"${id}\"><optgroup label=\"Frontend\"><option value=\"1\">React</option><option value=\"2\">Vue</option><option value=\"3\">Angular</option></optgroup><optgroup label=\"Backend\"><option value=\"4\">Node.js</option><option value=\"5\">Python</option><option value=\"6\">Java</option></optgroup></SelectNative></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-11.wxml",
          "target": "components/ui/select-11/select-11.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Select with option groups (native)</label><selectnative id=\"{{id}}\"><optgroup label=\"Frontend\"><option value=\"1\">React</option><option value=\"2\">Vue</option><option value=\"3\">Angular</option></optgroup><optgroup label=\"Backend\"><option value=\"4\">Node.js</option><option value=\"5\">Python</option><option value=\"6\">Java</option></optgroup></selectnative></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "native select"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-11",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-11",
              "path": "registry/default/components/select/select-11.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-11",
              "path": "registry/default/components/select/select-11.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-11",
              "path": "registry/default/components/select/select-11.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-11",
              "path": "registry/default/components/select/select-11.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-12",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select-native.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-12.tsx",
          "type": "registry:component",
          "target": "components/ui/select-12.tsx",
          "content": "import { useId, useMemo } from 'react'\nimport { Label, SelectNative } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n\n  const timezones = Intl.supportedValuesOf('timeZone')\n\n  const formattedTimezones = useMemo(() => {\n    return timezones\n      .map((timezone) => {\n        const formatter = new Intl.DateTimeFormat('en', {\n          timeZone: timezone,\n          timeZoneName: 'shortOffset',\n        })\n        const parts = formatter.formatToParts(new Date())\n        const offset = parts.find((part) => part.type === 'timeZoneName')?.value || ''\n        const modifiedOffset = offset === 'GMT' ? 'GMT+0' : offset\n\n        return {\n          value: timezone,\n          label: `(${modifiedOffset}) ${timezone.replace(/_/g, ' ')}`,\n          numericOffset: parseInt(offset.replace('GMT', '').replace('+', '') || '0'),\n        }\n      })\n      .sort((a, b) => a.numericOffset - b.numericOffset)\n  }, [timezones])\n\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Timezone select (native)</Label>\n      <SelectNative id={id} defaultValue=\"Europe/London\">\n        {formattedTimezones.map(({ value, label }) => (\n          <option key={value} value={value}>\n            {label}\n          </option>\n        ))}\n      </SelectNative>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-12.vue",
          "target": "components/ui/select-12.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { SelectNative } from '@timui/vue';\n\nconst id = 'select-12';\nconst timezones = Intl.supportedValuesOf('timeZone');\nconst formattedTimezones = timezones\n  .map((timezone) => {\n    const formatter = new Intl.DateTimeFormat('en', {\n      timeZone: timezone,\n      timeZoneName: 'shortOffset',\n    });\n    const parts = formatter.formatToParts(new Date());\n    const offset = parts.find((part) => part.type === 'timeZoneName')?.value || '';\n    const modifiedOffset = offset === 'GMT' ? 'GMT+0' : offset;\n\n    return {\n      value: timezone,\n      label: `(${modifiedOffset}) ${timezone.replace(/_/g, ' ')}`,\n      numericOffset: parseInt(offset.replace('GMT', '').replace('+', '') || '0'),\n    };\n  })\n  .sort((a, b) => a.numericOffset - b.numericOffset);\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Timezone select (native)</Label><SelectNative :id=\"id\" default-value=\"Europe/London\"><option v-for=\"({ value, label }, index) in formattedTimezones\" :key=\"value\" :value=\"value\">{{ label }}</option></SelectNative></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-12.html",
          "target": "components/ui/select-12.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Timezone select (native)</Label><SelectNative id=\"${id}\" default-value=\"Europe/London\"><!-- Loop formattedTimezones -->\n<option key=\"${value}\" value=\"${value}\">${label}</option>\n<!-- End Loop --></SelectNative></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-12.wxml",
          "target": "components/ui/select-12/select-12.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Timezone select (native)</label><selectnative id=\"{{id}}\" default-value=\"Europe/London\"><option wx:for=\"{{formattedTimezones}}\" wx:for-item=\"{ value, label }\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{value}}\" value=\"{{value}}\">{{ label }}</option></selectnative></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "native select",
          "timezone",
          "time"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-12",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-12",
              "path": "registry/default/components/select/select-12.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-12",
              "path": "registry/default/components/select/select-12.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-12",
              "path": "registry/default/components/select/select-12.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-12",
              "path": "registry/default/components/select/select-12.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-13",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select-native.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-13.tsx",
          "type": "registry:component",
          "target": "components/ui/select-13.tsx",
          "content": "import { useId } from 'react'\nimport { SelectNative } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"group relative\">\n      <label\n        htmlFor={id}\n        className=\"bg-background text-foreground absolute start-1 top-0 z-10 block -translate-y-1/2 px-2 text-xs font-medium group-has-[select:disabled]:opacity-50\"\n      >\n        Select with overlapping label (native)\n      </label>\n      <SelectNative id={id} defaultValue=\"\">\n        <option value=\"\" disabled>\n          Select framework\n        </option>\n        <option value=\"1\">React</option>\n        <option value=\"2\">Next.js</option>\n        <option value=\"3\">Astro</option>\n        <option value=\"4\">Gatsby</option>\n      </SelectNative>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-13.vue",
          "target": "components/ui/select-13.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { SelectNative } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-13';\n\n</script>\n\n<template>\n  <div class=\"group relative\"><label :for=\"id\" class=\"bg-background text-foreground absolute start-1 top-0 z-10 block -translate-y-1/2 px-2 text-xs font-medium group-has-[select:disabled]:opacity-50\">Select with overlapping label (native)\n      </label><SelectNative :id=\"id\" default-value=\"\"><option value=\"\" disabled>Select framework\n        </option><option value=\"1\">React</option><option value=\"2\">Next.js</option><option value=\"3\">Astro</option><option value=\"4\">Gatsby</option></SelectNative></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-13.html",
          "target": "components/ui/select-13.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"group relative\"><label htmlfor=\"${id}\" class=\"bg-background text-foreground absolute start-1 top-0 z-10 block -translate-y-1/2 px-2 text-xs font-medium group-has-[select:disabled]:opacity-50\">Select with overlapping label (native)\n      </label><SelectNative id=\"${id}\" default-value=\"\"><option value=\"\" disabled>Select framework\n        </option><option value=\"1\">React</option><option value=\"2\">Next.js</option><option value=\"3\">Astro</option><option value=\"4\">Gatsby</option></SelectNative></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-13.wxml",
          "target": "components/ui/select-13/select-13.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"group relative\"><label htmlfor=\"{{id}}\" class=\"bg-background text-foreground absolute start-1 top-0 z-10 block -translate-y-1/2 px-2 text-xs font-medium group-has-[select:disabled]:opacity-50\">Select with overlapping label (native)\n      </label><selectnative id=\"{{id}}\" default-value=\"\"><option value=\"\" disabled>Select framework\n        </option><option value=\"1\">React</option><option value=\"2\">Next.js</option><option value=\"3\">Astro</option><option value=\"4\">Gatsby</option></selectnative></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "native select"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-13",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-13",
              "path": "registry/default/components/select/select-13.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-13",
              "path": "registry/default/components/select/select-13.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-13",
              "path": "registry/default/components/select/select-13.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-13",
              "path": "registry/default/components/select/select-13.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-14",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select-native.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-14.tsx",
          "type": "registry:component",
          "target": "components/ui/select-14.tsx",
          "content": "import { useId } from 'react'\nimport { SelectNative } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"border-input bg-background focus-within:border-ring focus-within:ring-ring/50 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40 has-aria-invalid:border-destructive relative rounded-md border shadow-xs transition-[color,box-shadow] outline-none focus-within:ring-[3px] has-[select:disabled]:cursor-not-allowed has-[select:disabled]:opacity-50 has-[select:is(:disabled)_*]:pointer-events-none\">\n      <label htmlFor={id} className=\"text-foreground block px-3 pt-2 text-xs font-medium\">\n        Select with inset label (native)\n      </label>\n      <SelectNative\n        id={id}\n        defaultValue=\"\"\n        className=\"border-none bg-transparent shadow-none focus-visible:ring-0 focus-visible:ring-offset-0\"\n      >\n        <option value=\"\" disabled>\n          Select framework\n        </option>\n        <option value=\"1\">React</option>\n        <option value=\"2\">Next.js</option>\n        <option value=\"3\">Astro</option>\n        <option value=\"4\">Gatsby</option>\n      </SelectNative>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-14.vue",
          "target": "components/ui/select-14.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { SelectNative } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-14';\n\n</script>\n\n<template>\n  <div class=\"border-input bg-background focus-within:border-ring focus-within:ring-ring/50 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40 has-aria-invalid:border-destructive relative rounded-md border shadow-xs transition-[color,box-shadow] outline-none focus-within:ring-[3px] has-[select:disabled]:cursor-not-allowed has-[select:disabled]:opacity-50 has-[select:is(:disabled)_*]:pointer-events-none\"><label :for=\"id\" class=\"text-foreground block px-3 pt-2 text-xs font-medium\">Select with inset label (native)\n      </label><SelectNative :id=\"id\" default-value=\"\" class=\"border-none bg-transparent shadow-none focus-visible:ring-0 focus-visible:ring-offset-0\"><option value=\"\" disabled>Select framework\n        </option><option value=\"1\">React</option><option value=\"2\">Next.js</option><option value=\"3\">Astro</option><option value=\"4\">Gatsby</option></SelectNative></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-14.html",
          "target": "components/ui/select-14.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"border-input bg-background focus-within:border-ring focus-within:ring-ring/50 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40 has-aria-invalid:border-destructive relative rounded-md border shadow-xs transition-[color,box-shadow] outline-none focus-within:ring-[3px] has-[select:disabled]:cursor-not-allowed has-[select:disabled]:opacity-50 has-[select:is(:disabled)_*]:pointer-events-none\"><label htmlfor=\"${id}\" class=\"text-foreground block px-3 pt-2 text-xs font-medium\">Select with inset label (native)\n      </label><SelectNative id=\"${id}\" default-value=\"\" class=\"border-none bg-transparent shadow-none focus-visible:ring-0 focus-visible:ring-offset-0\"><option value=\"\" disabled>Select framework\n        </option><option value=\"1\">React</option><option value=\"2\">Next.js</option><option value=\"3\">Astro</option><option value=\"4\">Gatsby</option></SelectNative></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-14.wxml",
          "target": "components/ui/select-14/select-14.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"border-input bg-background focus-within:border-ring focus-within:ring-ring/50 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40 has-aria-invalid:border-destructive relative rounded-md border shadow-xs transition-[color,box-shadow] outline-none focus-within:ring-[3px] has-[select:disabled]:cursor-not-allowed has-[select:disabled]:opacity-50 has-[select:is(:disabled)_*]:pointer-events-none\"><label htmlfor=\"{{id}}\" class=\"text-foreground block px-3 pt-2 text-xs font-medium\">Select with inset label (native)\n      </label><selectnative id=\"{{id}}\" default-value=\"\" class=\"border-none bg-transparent shadow-none focus-visible:ring-0 focus-visible:ring-offset-0\"><option value=\"\" disabled>Select framework\n        </option><option value=\"1\">React</option><option value=\"2\">Next.js</option><option value=\"3\">Astro</option><option value=\"4\">Gatsby</option></selectnative></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "native select"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-14",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-14",
              "path": "registry/default/components/select/select-14.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-14",
              "path": "registry/default/components/select/select-14.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-14",
              "path": "registry/default/components/select/select-14.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-14",
              "path": "registry/default/components/select/select-14.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-15",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-15.tsx",
          "type": "registry:component",
          "target": "components/ui/select-15.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Simple select with default value</Label>\n      <Select defaultValue=\"1\">\n        <SelectTrigger id={id}>\n          <SelectValue placeholder=\"Select framework\" />\n        </SelectTrigger>\n        <SelectContent>\n          <SelectItem value=\"1\">React</SelectItem>\n          <SelectItem value=\"2\">Next.js</SelectItem>\n          <SelectItem value=\"3\">Astro</SelectItem>\n          <SelectItem value=\"4\">Gatsby</SelectItem>\n        </SelectContent>\n      </Select>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-15.vue",
          "target": "components/ui/select-15.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-15';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Simple select with default value</Label><Select default-value=\"1\"><SelectTrigger :id=\"id\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent><SelectItem value=\"1\">React</SelectItem><SelectItem value=\"2\">Next.js</SelectItem><SelectItem value=\"3\">Astro</SelectItem><SelectItem value=\"4\">Gatsby</SelectItem></SelectContent></Select></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-15.html",
          "target": "components/ui/select-15.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Simple select with default value</Label><Select default-value=\"1\"><SelectTrigger id=\"${id}\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent><SelectItem value=\"1\">React</SelectItem><SelectItem value=\"2\">Next.js</SelectItem><SelectItem value=\"3\">Astro</SelectItem><SelectItem value=\"4\">Gatsby</SelectItem></SelectContent></Select></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-15.wxml",
          "target": "components/ui/select-15/select-15.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Simple select with default value</label><select default-value=\"1\"><selecttrigger id=\"{{id}}\"><selectvalue placeholder=\"Select framework\" /></selecttrigger><selectcontent><selectitem value=\"1\">React</selectitem><selectitem value=\"2\">Next.js</selectitem><selectitem value=\"3\">Astro</selectitem><selectitem value=\"4\">Gatsby</selectitem></selectcontent></select></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-15",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-15",
              "path": "registry/default/components/select/select-15.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-15",
              "path": "registry/default/components/select/select-15.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-15",
              "path": "registry/default/components/select/select-15.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-15",
              "path": "registry/default/components/select/select-15.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-16",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-16.tsx",
          "type": "registry:component",
          "target": "components/ui/select-16.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Select with placeholder</Label>\n      <Select>\n        <SelectTrigger id={id}>\n          <SelectValue placeholder=\"Select framework\" />\n        </SelectTrigger>\n        <SelectContent>\n          <SelectItem value=\"1\">React</SelectItem>\n          <SelectItem value=\"2\">Next.js</SelectItem>\n          <SelectItem value=\"3\">Astro</SelectItem>\n          <SelectItem value=\"4\">Gatsby</SelectItem>\n        </SelectContent>\n      </Select>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-16.vue",
          "target": "components/ui/select-16.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-16';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Select with placeholder</Label><Select><SelectTrigger :id=\"id\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent><SelectItem value=\"1\">React</SelectItem><SelectItem value=\"2\">Next.js</SelectItem><SelectItem value=\"3\">Astro</SelectItem><SelectItem value=\"4\">Gatsby</SelectItem></SelectContent></Select></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-16.html",
          "target": "components/ui/select-16.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Select with placeholder</Label><Select><SelectTrigger id=\"${id}\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent><SelectItem value=\"1\">React</SelectItem><SelectItem value=\"2\">Next.js</SelectItem><SelectItem value=\"3\">Astro</SelectItem><SelectItem value=\"4\">Gatsby</SelectItem></SelectContent></Select></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-16.wxml",
          "target": "components/ui/select-16/select-16.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Select with placeholder</label><select><selecttrigger id=\"{{id}}\"><selectvalue placeholder=\"Select framework\" /></selecttrigger><selectcontent><selectitem value=\"1\">React</selectitem><selectitem value=\"2\">Next.js</selectitem><selectitem value=\"3\">Astro</selectitem><selectitem value=\"4\">Gatsby</selectitem></selectcontent></select></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-16",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-16",
              "path": "registry/default/components/select/select-16.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-16",
              "path": "registry/default/components/select/select-16.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-16",
              "path": "registry/default/components/select/select-16.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-16",
              "path": "registry/default/components/select/select-16.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-17",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-17.tsx",
          "type": "registry:component",
          "target": "components/ui/select-17.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/react'\nimport { ClockIcon } from 'lucide-react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Select with icon</Label>\n      <Select defaultValue=\"1\">\n        <SelectTrigger id={id} className=\"relative ps-9\">\n          <div className=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 group-has-[select[disabled]]:opacity-50\">\n            <ClockIcon size={16} aria-hidden=\"true\" />\n          </div>\n          <SelectValue placeholder=\"Select time\" />\n        </SelectTrigger>\n        <SelectContent>\n          <SelectItem value=\"1\">00:00 AM - 11:59 PM</SelectItem>\n          <SelectItem value=\"2\">01:00 AM - 12:59 PM</SelectItem>\n          <SelectItem value=\"3\">02:00 AM - 01:59 PM</SelectItem>\n          <SelectItem value=\"4\">03:00 AM - 02:59 PM</SelectItem>\n        </SelectContent>\n      </Select>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-17.vue",
          "target": "components/ui/select-17.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ClockIcon } from 'lucide-vue-next';\nimport { Label } from '@timui/vue';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-17';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Select with icon</Label><Select default-value=\"1\"><SelectTrigger :id=\"id\" class=\"relative ps-9\"><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 group-has-[select[disabled]]:opacity-50\"><ClockIcon :size=\"16\" aria-hidden=\"true\" /></div><SelectValue placeholder=\"Select time\" /></SelectTrigger><SelectContent><SelectItem value=\"1\">00:00 AM - 11:59 PM</SelectItem><SelectItem value=\"2\">01:00 AM - 12:59 PM</SelectItem><SelectItem value=\"3\">02:00 AM - 01:59 PM</SelectItem><SelectItem value=\"4\">03:00 AM - 02:59 PM</SelectItem></SelectContent></Select></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-17.html",
          "target": "components/ui/select-17.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Select with icon</Label><Select default-value=\"1\"><SelectTrigger id=\"${id}\" class=\"relative ps-9\"><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 group-has-[select[disabled]]:opacity-50\"><ClockIcon size=\"${16}\" aria-hidden=\"true\" /></div><SelectValue placeholder=\"Select time\" /></SelectTrigger><SelectContent><SelectItem value=\"1\">00:00 AM - 11:59 PM</SelectItem><SelectItem value=\"2\">01:00 AM - 12:59 PM</SelectItem><SelectItem value=\"3\">02:00 AM - 01:59 PM</SelectItem><SelectItem value=\"4\">03:00 AM - 02:59 PM</SelectItem></SelectContent></Select></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-17.wxml",
          "target": "components/ui/select-17/select-17.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Select with icon</label><select default-value=\"1\"><selecttrigger id=\"{{id}}\" class=\"relative ps-9\"><view class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 group-has-[select[disabled]]:opacity-50\"><clockicon size=\"{{16}}\" aria-hidden=\"true\" /></view><selectvalue placeholder=\"Select time\" /></selecttrigger><selectcontent><selectitem value=\"1\">00:00 AM - 11:59 PM</selectitem><selectitem value=\"2\">01:00 AM - 12:59 PM</selectitem><selectitem value=\"3\">02:00 AM - 01:59 PM</selectitem><selectitem value=\"4\">03:00 AM - 02:59 PM</selectitem></selectcontent></select></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-17",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-17",
              "path": "registry/default/components/select/select-17.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-17",
              "path": "registry/default/components/select/select-17.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-17",
              "path": "registry/default/components/select/select-17.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-17",
              "path": "registry/default/components/select/select-17.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-18",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-18.tsx",
          "type": "registry:component",
          "target": "components/ui/select-18.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Select with helper text</Label>\n      <Select defaultValue=\"3\">\n        <SelectTrigger id={id}>\n          <SelectValue placeholder=\"Select framework\" />\n        </SelectTrigger>\n        <SelectContent>\n          <SelectItem value=\"1\">React</SelectItem>\n          <SelectItem value=\"2\">Next.js</SelectItem>\n          <SelectItem value=\"3\">Astro</SelectItem>\n          <SelectItem value=\"4\">Gatsby</SelectItem>\n        </SelectContent>\n      </Select>\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Tell us what&lsquo;s your favorite Select framework\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-18.vue",
          "target": "components/ui/select-18.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-18';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Select with helper text</Label><Select default-value=\"3\"><SelectTrigger :id=\"id\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent><SelectItem value=\"1\">React</SelectItem><SelectItem value=\"2\">Next.js</SelectItem><SelectItem value=\"3\">Astro</SelectItem><SelectItem value=\"4\">Gatsby</SelectItem></SelectContent></Select><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Tell us what&lsquo;s your favorite Select framework\n      </p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-18.html",
          "target": "components/ui/select-18.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Select with helper text</Label><Select default-value=\"3\"><SelectTrigger id=\"${id}\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent><SelectItem value=\"1\">React</SelectItem><SelectItem value=\"2\">Next.js</SelectItem><SelectItem value=\"3\">Astro</SelectItem><SelectItem value=\"4\">Gatsby</SelectItem></SelectContent></Select><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Tell us what&lsquo;s your favorite Select framework\n      </p></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-18.wxml",
          "target": "components/ui/select-18/select-18.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Select with helper text</label><select default-value=\"3\"><selecttrigger id=\"{{id}}\"><selectvalue placeholder=\"Select framework\" /></selecttrigger><selectcontent><selectitem value=\"1\">React</selectitem><selectitem value=\"2\">Next.js</selectitem><selectitem value=\"3\">Astro</selectitem><selectitem value=\"4\">Gatsby</selectitem></selectcontent></select><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Tell us what&lsquo;s your favorite Select framework\n      </text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "helper",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-18",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-18",
              "path": "registry/default/components/select/select-18.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-18",
              "path": "registry/default/components/select/select-18.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-18",
              "path": "registry/default/components/select/select-18.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-18",
              "path": "registry/default/components/select/select-18.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-19",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-19.tsx",
          "type": "registry:component",
          "target": "components/ui/select-19.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"[--ring:var(--color-indigo-300)] *:not-first:mt-2 in-[.dark]:[--ring:var(--color-indigo-900)]\">\n      <Label htmlFor={id}>Select with colored border and ring</Label>\n      <Select defaultValue=\"1\">\n        <SelectTrigger id={id}>\n          <SelectValue placeholder=\"Select framework\" />\n        </SelectTrigger>\n        <SelectContent>\n          <SelectItem value=\"1\">React</SelectItem>\n          <SelectItem value=\"2\">Next.js</SelectItem>\n          <SelectItem value=\"3\">Astro</SelectItem>\n          <SelectItem value=\"4\">Gatsby</SelectItem>\n        </SelectContent>\n      </Select>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-19.vue",
          "target": "components/ui/select-19.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-19';\n\n</script>\n\n<template>\n  <div class=\"[--ring:var(--color-indigo-300)] *:not-first:mt-2 in-[.dark]:[--ring:var(--color-indigo-900)]\"><Label :htmlFor=\"id\">Select with colored border and ring</Label><Select default-value=\"1\"><SelectTrigger :id=\"id\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent><SelectItem value=\"1\">React</SelectItem><SelectItem value=\"2\">Next.js</SelectItem><SelectItem value=\"3\">Astro</SelectItem><SelectItem value=\"4\">Gatsby</SelectItem></SelectContent></Select></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-19.html",
          "target": "components/ui/select-19.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"[--ring:var(--color-indigo-300)] *:not-first:mt-2 in-[.dark]:[--ring:var(--color-indigo-900)]\"><Label htmlfor=\"${id}\">Select with colored border and ring</Label><Select default-value=\"1\"><SelectTrigger id=\"${id}\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent><SelectItem value=\"1\">React</SelectItem><SelectItem value=\"2\">Next.js</SelectItem><SelectItem value=\"3\">Astro</SelectItem><SelectItem value=\"4\">Gatsby</SelectItem></SelectContent></Select></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-19.wxml",
          "target": "components/ui/select-19/select-19.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"[--ring:var(--color-indigo-300)] *:not-first:mt-2 in-[.dark]:[--ring:var(--color-indigo-900)]\"><label htmlfor=\"{{id}}\">Select with colored border and ring</label><select default-value=\"1\"><selecttrigger id=\"{{id}}\"><selectvalue placeholder=\"Select framework\" /></selecttrigger><selectcontent><selectitem value=\"1\">React</selectitem><selectitem value=\"2\">Next.js</selectitem><selectitem value=\"3\">Astro</selectitem><selectitem value=\"4\">Gatsby</selectitem></selectcontent></select></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-19",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-19",
              "path": "registry/default/components/select/select-19.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-19",
              "path": "registry/default/components/select/select-19.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-19",
              "path": "registry/default/components/select/select-19.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-19",
              "path": "registry/default/components/select/select-19.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-20",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-20.tsx",
          "type": "registry:component",
          "target": "components/ui/select-20.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Select with error</Label>\n      <Select defaultValue=\"1\">\n        <SelectTrigger id={id} aria-invalid>\n          <SelectValue />\n        </SelectTrigger>\n        <SelectContent>\n          <SelectItem value=\"1\">React</SelectItem>\n          <SelectItem value=\"2\">Next.js</SelectItem>\n          <SelectItem value=\"3\">Astro</SelectItem>\n          <SelectItem value=\"4\">Gatsby</SelectItem>\n        </SelectContent>\n      </Select>\n      <p className=\"text-destructive mt-2 text-xs\" role=\"alert\" aria-live=\"polite\">\n        Selected option is invalid\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-20.vue",
          "target": "components/ui/select-20.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-20';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Select with error</Label><Select default-value=\"1\"><SelectTrigger :id=\"id\" aria-invalid><SelectValue /></SelectTrigger><SelectContent><SelectItem value=\"1\">React</SelectItem><SelectItem value=\"2\">Next.js</SelectItem><SelectItem value=\"3\">Astro</SelectItem><SelectItem value=\"4\">Gatsby</SelectItem></SelectContent></Select><p class=\"text-destructive mt-2 text-xs\" role=\"alert\" aria-live=\"polite\">Selected option is invalid\n      </p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-20.html",
          "target": "components/ui/select-20.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Select with error</Label><Select default-value=\"1\"><SelectTrigger id=\"${id}\" aria-invalid><SelectValue /></SelectTrigger><SelectContent><SelectItem value=\"1\">React</SelectItem><SelectItem value=\"2\">Next.js</SelectItem><SelectItem value=\"3\">Astro</SelectItem><SelectItem value=\"4\">Gatsby</SelectItem></SelectContent></Select><p class=\"text-destructive mt-2 text-xs\" role=\"alert\" aria-live=\"polite\">Selected option is invalid\n      </p></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-20.wxml",
          "target": "components/ui/select-20/select-20.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Select with error</label><select default-value=\"1\"><selecttrigger id=\"{{id}}\" aria-invalid><selectvalue /></selecttrigger><selectcontent><selectitem value=\"1\">React</selectitem><selectitem value=\"2\">Next.js</selectitem><selectitem value=\"3\">Astro</selectitem><selectitem value=\"4\">Gatsby</selectitem></selectcontent></select><text class=\"text-destructive mt-2 text-xs\" role=\"alert\" aria-live=\"polite\">Selected option is invalid\n      </text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-20",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-20",
              "path": "registry/default/components/select/select-20.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-20",
              "path": "registry/default/components/select/select-20.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-20",
              "path": "registry/default/components/select/select-20.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-20",
              "path": "registry/default/components/select/select-20.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-21",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-21.tsx",
          "type": "registry:component",
          "target": "components/ui/select-21.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Select with gray background</Label>\n      <Select defaultValue=\"2\">\n        <SelectTrigger id={id} className=\"bg-muted border-transparent shadow-none\">\n          <SelectValue placeholder=\"Select framework\" />\n        </SelectTrigger>\n        <SelectContent>\n          <SelectItem value=\"1\">React</SelectItem>\n          <SelectItem value=\"2\">Next.js</SelectItem>\n          <SelectItem value=\"3\">Astro</SelectItem>\n          <SelectItem value=\"4\">Gatsby</SelectItem>\n        </SelectContent>\n      </Select>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-21.vue",
          "target": "components/ui/select-21.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-21';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Select with gray background</Label><Select default-value=\"2\"><SelectTrigger :id=\"id\" class=\"bg-muted border-transparent shadow-none\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent><SelectItem value=\"1\">React</SelectItem><SelectItem value=\"2\">Next.js</SelectItem><SelectItem value=\"3\">Astro</SelectItem><SelectItem value=\"4\">Gatsby</SelectItem></SelectContent></Select></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-21.html",
          "target": "components/ui/select-21.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Select with gray background</Label><Select default-value=\"2\"><SelectTrigger id=\"${id}\" class=\"bg-muted border-transparent shadow-none\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent><SelectItem value=\"1\">React</SelectItem><SelectItem value=\"2\">Next.js</SelectItem><SelectItem value=\"3\">Astro</SelectItem><SelectItem value=\"4\">Gatsby</SelectItem></SelectContent></Select></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-21.wxml",
          "target": "components/ui/select-21/select-21.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Select with gray background</label><select default-value=\"2\"><selecttrigger id=\"{{id}}\" class=\"bg-muted border-transparent shadow-none\"><selectvalue placeholder=\"Select framework\" /></selecttrigger><selectcontent><selectitem value=\"1\">React</selectitem><selectitem value=\"2\">Next.js</selectitem><selectitem value=\"3\">Astro</selectitem><selectitem value=\"4\">Gatsby</selectitem></selectcontent></select></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-21",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-21",
              "path": "registry/default/components/select/select-21.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-21",
              "path": "registry/default/components/select/select-21.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-21",
              "path": "registry/default/components/select/select-21.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-21",
              "path": "registry/default/components/select/select-21.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-22",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-22.tsx",
          "type": "registry:component",
          "target": "components/ui/select-22.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Disabled select</Label>\n      <Select defaultValue=\"1\" disabled>\n        <SelectTrigger id={id}>\n          <SelectValue placeholder=\"Select framework\" />\n        </SelectTrigger>\n        <SelectContent>\n          <SelectItem value=\"1\">React</SelectItem>\n          <SelectItem value=\"2\">Next.js</SelectItem>\n          <SelectItem value=\"3\">Astro</SelectItem>\n          <SelectItem value=\"4\">Gatsby</SelectItem>\n        </SelectContent>\n      </Select>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-22.vue",
          "target": "components/ui/select-22.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-22';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Disabled select</Label><Select default-value=\"1\" disabled><SelectTrigger :id=\"id\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent><SelectItem value=\"1\">React</SelectItem><SelectItem value=\"2\">Next.js</SelectItem><SelectItem value=\"3\">Astro</SelectItem><SelectItem value=\"4\">Gatsby</SelectItem></SelectContent></Select></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-22.html",
          "target": "components/ui/select-22.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Disabled select</Label><Select default-value=\"1\" disabled><SelectTrigger id=\"${id}\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent><SelectItem value=\"1\">React</SelectItem><SelectItem value=\"2\">Next.js</SelectItem><SelectItem value=\"3\">Astro</SelectItem><SelectItem value=\"4\">Gatsby</SelectItem></SelectContent></Select></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-22.wxml",
          "target": "components/ui/select-22/select-22.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Disabled select</label><select default-value=\"1\" disabled><selecttrigger id=\"{{id}}\"><selectvalue placeholder=\"Select framework\" /></selecttrigger><selectcontent><selectitem value=\"1\">React</selectitem><selectitem value=\"2\">Next.js</selectitem><selectitem value=\"3\">Astro</selectitem><selectitem value=\"4\">Gatsby</selectitem></selectcontent></select></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "disabled",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-22",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-22",
              "path": "registry/default/components/select/select-22.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-22",
              "path": "registry/default/components/select/select-22.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-22",
              "path": "registry/default/components/select/select-22.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-22",
              "path": "registry/default/components/select/select-22.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-23",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-23.tsx",
          "type": "registry:component",
          "target": "components/ui/select-23.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>\n        Required select <span className=\"text-destructive\">*</span>\n      </Label>\n      <Select defaultValue=\"4\" required>\n        <SelectTrigger id={id}>\n          <SelectValue placeholder=\"Select framework\" />\n        </SelectTrigger>\n        <SelectContent>\n          <SelectItem value=\"1\">React</SelectItem>\n          <SelectItem value=\"2\">Next.js</SelectItem>\n          <SelectItem value=\"3\">Astro</SelectItem>\n          <SelectItem value=\"4\">Gatsby</SelectItem>\n        </SelectContent>\n      </Select>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-23.vue",
          "target": "components/ui/select-23.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-23';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Required select <span class=\"text-destructive\">*</span></Label><Select default-value=\"4\" required><SelectTrigger :id=\"id\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent><SelectItem value=\"1\">React</SelectItem><SelectItem value=\"2\">Next.js</SelectItem><SelectItem value=\"3\">Astro</SelectItem><SelectItem value=\"4\">Gatsby</SelectItem></SelectContent></Select></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-23.html",
          "target": "components/ui/select-23.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Required select <span class=\"text-destructive\">*</span></Label><Select default-value=\"4\" required><SelectTrigger id=\"${id}\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent><SelectItem value=\"1\">React</SelectItem><SelectItem value=\"2\">Next.js</SelectItem><SelectItem value=\"3\">Astro</SelectItem><SelectItem value=\"4\">Gatsby</SelectItem></SelectContent></Select></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-23.wxml",
          "target": "components/ui/select-23/select-23.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Required select <text class=\"text-destructive\">*</text></label><select default-value=\"4\" required><selecttrigger id=\"{{id}}\"><selectvalue placeholder=\"Select framework\" /></selecttrigger><selectcontent><selectitem value=\"1\">React</selectitem><selectitem value=\"2\">Next.js</selectitem><selectitem value=\"3\">Astro</selectitem><selectitem value=\"4\">Gatsby</selectitem></selectcontent></select></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "required",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-23",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-23",
              "path": "registry/default/components/select/select-23.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-23",
              "path": "registry/default/components/select/select-23.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-23",
              "path": "registry/default/components/select/select-23.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-23",
              "path": "registry/default/components/select/select-23.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-24",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-24.tsx",
          "type": "registry:component",
          "target": "components/ui/select-24.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Select with auto-width</Label>\n      <Select defaultValue=\"1\">\n        {/* Adjust the min-width to fit the longest option */}\n        <SelectTrigger id={id} className=\"w-auto max-w-full min-w-48\">\n          <SelectValue placeholder=\"Select framework\" />\n        </SelectTrigger>\n        <SelectContent>\n          <SelectItem value=\"1\">React</SelectItem>\n          <SelectItem value=\"2\">Next.js</SelectItem>\n          <SelectItem value=\"3\">Astro</SelectItem>\n          <SelectItem value=\"4\">Gatsby</SelectItem>\n        </SelectContent>\n      </Select>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-24.vue",
          "target": "components/ui/select-24.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-24';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Select with auto-width</Label><Select default-value=\"1\"><SelectTrigger :id=\"id\" class=\"w-auto max-w-full min-w-48\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent><SelectItem value=\"1\">React</SelectItem><SelectItem value=\"2\">Next.js</SelectItem><SelectItem value=\"3\">Astro</SelectItem><SelectItem value=\"4\">Gatsby</SelectItem></SelectContent></Select></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-24.html",
          "target": "components/ui/select-24.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Select with auto-width</Label><Select default-value=\"1\"><SelectTrigger id=\"${id}\" class=\"w-auto max-w-full min-w-48\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent><SelectItem value=\"1\">React</SelectItem><SelectItem value=\"2\">Next.js</SelectItem><SelectItem value=\"3\">Astro</SelectItem><SelectItem value=\"4\">Gatsby</SelectItem></SelectContent></Select></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-24.wxml",
          "target": "components/ui/select-24/select-24.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Select with auto-width</label><select default-value=\"1\"><selecttrigger id=\"{{id}}\" class=\"w-auto max-w-full min-w-48\"><selectvalue placeholder=\"Select framework\" /></selecttrigger><selectcontent><selectitem value=\"1\">React</selectitem><selectitem value=\"2\">Next.js</selectitem><selectitem value=\"3\">Astro</selectitem><selectitem value=\"4\">Gatsby</selectitem></selectcontent></select></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-24",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-24",
              "path": "registry/default/components/select/select-24.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-24",
              "path": "registry/default/components/select/select-24.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-24",
              "path": "registry/default/components/select/select-24.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-24",
              "path": "registry/default/components/select/select-24.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-25",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-25.tsx",
          "type": "registry:component",
          "target": "components/ui/select-25.tsx",
          "content": "import { useId } from 'react'\nimport {\n  Label,\n  Select,\n  SelectContent,\n  SelectGroup,\n  SelectItem,\n  SelectLabel,\n  SelectTrigger,\n  SelectValue,\n} from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Select with options groups</Label>\n      <Select defaultValue=\"1\">\n        <SelectTrigger id={id}>\n          <SelectValue placeholder=\"Select framework\" />\n        </SelectTrigger>\n        <SelectContent>\n          <SelectGroup>\n            <SelectLabel>Frontend</SelectLabel>\n            <SelectItem value=\"1\">React</SelectItem>\n            <SelectItem value=\"2\">Vue</SelectItem>\n            <SelectItem value=\"3\">Angular</SelectItem>\n          </SelectGroup>\n          <SelectGroup>\n            <SelectLabel>Backend</SelectLabel>\n            <SelectItem value=\"4\">Node.js</SelectItem>\n            <SelectItem value=\"5\">Python</SelectItem>\n            <SelectItem value=\"6\">Java</SelectItem>\n          </SelectGroup>\n        </SelectContent>\n      </Select>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-25.vue",
          "target": "components/ui/select-25.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-25';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Select with options groups</Label><Select default-value=\"1\"><SelectTrigger :id=\"id\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent><SelectGroup><SelectLabel>Frontend</SelectLabel><SelectItem value=\"1\">React</SelectItem><SelectItem value=\"2\">Vue</SelectItem><SelectItem value=\"3\">Angular</SelectItem></SelectGroup><SelectGroup><SelectLabel>Backend</SelectLabel><SelectItem value=\"4\">Node.js</SelectItem><SelectItem value=\"5\">Python</SelectItem><SelectItem value=\"6\">Java</SelectItem></SelectGroup></SelectContent></Select></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-25.html",
          "target": "components/ui/select-25.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Select with options groups</Label><Select default-value=\"1\"><SelectTrigger id=\"${id}\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent><SelectGroup><SelectLabel>Frontend</SelectLabel><SelectItem value=\"1\">React</SelectItem><SelectItem value=\"2\">Vue</SelectItem><SelectItem value=\"3\">Angular</SelectItem></SelectGroup><SelectGroup><SelectLabel>Backend</SelectLabel><SelectItem value=\"4\">Node.js</SelectItem><SelectItem value=\"5\">Python</SelectItem><SelectItem value=\"6\">Java</SelectItem></SelectGroup></SelectContent></Select></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-25.wxml",
          "target": "components/ui/select-25/select-25.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Select with options groups</label><select default-value=\"1\"><selecttrigger id=\"{{id}}\"><selectvalue placeholder=\"Select framework\" /></selecttrigger><selectcontent><selectgroup><selectlabel>Frontend</selectlabel><selectitem value=\"1\">React</selectitem><selectitem value=\"2\">Vue</selectitem><selectitem value=\"3\">Angular</selectitem></selectgroup><selectgroup><selectlabel>Backend</selectlabel><selectitem value=\"4\">Node.js</selectitem><selectitem value=\"5\">Python</selectitem><selectitem value=\"6\">Java</selectitem></selectgroup></selectcontent></select></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-25",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-25",
              "path": "registry/default/components/select/select-25.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-25",
              "path": "registry/default/components/select/select-25.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-25",
              "path": "registry/default/components/select/select-25.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-25",
              "path": "registry/default/components/select/select-25.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-26",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-26.tsx",
          "type": "registry:component",
          "target": "components/ui/select-26.tsx",
          "content": "import { useId } from 'react'\nimport {\n  Label,\n  Select,\n  SelectContent,\n  SelectGroup,\n  SelectItem,\n  SelectLabel,\n  SelectSeparator,\n  SelectTrigger,\n  SelectValue,\n} from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Select with separator</Label>\n      <Select defaultValue=\"1\">\n        <SelectTrigger id={id}>\n          <SelectValue placeholder=\"Select framework\" />\n        </SelectTrigger>\n        <SelectContent>\n          <SelectGroup>\n            <SelectLabel>Frontend</SelectLabel>\n            <SelectItem value=\"1\">React</SelectItem>\n            <SelectItem value=\"2\">Vue</SelectItem>\n            <SelectItem value=\"3\">Angular</SelectItem>\n          </SelectGroup>\n          <SelectSeparator />\n          <SelectGroup>\n            <SelectLabel>Backend</SelectLabel>\n            <SelectItem value=\"4\">Node.js</SelectItem>\n            <SelectItem value=\"5\">Python</SelectItem>\n            <SelectItem value=\"6\">Java</SelectItem>\n          </SelectGroup>\n        </SelectContent>\n      </Select>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-26.vue",
          "target": "components/ui/select-26.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectSeparator, SelectTrigger, SelectValue } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-26';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Select with separator</Label><Select default-value=\"1\"><SelectTrigger :id=\"id\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent><SelectGroup><SelectLabel>Frontend</SelectLabel><SelectItem value=\"1\">React</SelectItem><SelectItem value=\"2\">Vue</SelectItem><SelectItem value=\"3\">Angular</SelectItem></SelectGroup><SelectSeparator /><SelectGroup><SelectLabel>Backend</SelectLabel><SelectItem value=\"4\">Node.js</SelectItem><SelectItem value=\"5\">Python</SelectItem><SelectItem value=\"6\">Java</SelectItem></SelectGroup></SelectContent></Select></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-26.html",
          "target": "components/ui/select-26.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Select with separator</Label><Select default-value=\"1\"><SelectTrigger id=\"${id}\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent><SelectGroup><SelectLabel>Frontend</SelectLabel><SelectItem value=\"1\">React</SelectItem><SelectItem value=\"2\">Vue</SelectItem><SelectItem value=\"3\">Angular</SelectItem></SelectGroup><SelectSeparator /><SelectGroup><SelectLabel>Backend</SelectLabel><SelectItem value=\"4\">Node.js</SelectItem><SelectItem value=\"5\">Python</SelectItem><SelectItem value=\"6\">Java</SelectItem></SelectGroup></SelectContent></Select></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-26.wxml",
          "target": "components/ui/select-26/select-26.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Select with separator</label><select default-value=\"1\"><selecttrigger id=\"{{id}}\"><selectvalue placeholder=\"Select framework\" /></selecttrigger><selectcontent><selectgroup><selectlabel>Frontend</selectlabel><selectitem value=\"1\">React</selectitem><selectitem value=\"2\">Vue</selectitem><selectitem value=\"3\">Angular</selectitem></selectgroup><selectseparator /><selectgroup><selectlabel>Backend</selectlabel><selectitem value=\"4\">Node.js</selectitem><selectitem value=\"5\">Python</selectitem><selectitem value=\"6\">Java</selectitem></selectgroup></selectcontent></select></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-26",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-26",
              "path": "registry/default/components/select/select-26.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-26",
              "path": "registry/default/components/select/select-26.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-26",
              "path": "registry/default/components/select/select-26.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-26",
              "path": "registry/default/components/select/select-26.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-27",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-27.tsx",
          "type": "registry:component",
          "target": "components/ui/select-27.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Select with disabled options</Label>\n      <Select defaultValue=\"2\">\n        <SelectTrigger id={id}>\n          <SelectValue placeholder=\"Select framework\" />\n        </SelectTrigger>\n        <SelectContent>\n          <SelectItem value=\"1\" disabled>\n            React\n          </SelectItem>\n          <SelectItem value=\"2\">Next.js</SelectItem>\n          <SelectItem value=\"3\" disabled>\n            Astro\n          </SelectItem>\n          <SelectItem value=\"4\">Gatsby</SelectItem>\n        </SelectContent>\n      </Select>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-27.vue",
          "target": "components/ui/select-27.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-27';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Select with disabled options</Label><Select default-value=\"2\"><SelectTrigger :id=\"id\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent><SelectItem value=\"1\" disabled>React\n          </SelectItem><SelectItem value=\"2\">Next.js</SelectItem><SelectItem value=\"3\" disabled>Astro\n          </SelectItem><SelectItem value=\"4\">Gatsby</SelectItem></SelectContent></Select></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-27.html",
          "target": "components/ui/select-27.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Select with disabled options</Label><Select default-value=\"2\"><SelectTrigger id=\"${id}\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent><SelectItem value=\"1\" disabled>React\n          </SelectItem><SelectItem value=\"2\">Next.js</SelectItem><SelectItem value=\"3\" disabled>Astro\n          </SelectItem><SelectItem value=\"4\">Gatsby</SelectItem></SelectContent></Select></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-27.wxml",
          "target": "components/ui/select-27/select-27.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Select with disabled options</label><select default-value=\"2\"><selecttrigger id=\"{{id}}\"><selectvalue placeholder=\"Select framework\" /></selecttrigger><selectcontent><selectitem value=\"1\" disabled>React\n          </selectitem><selectitem value=\"2\">Next.js</selectitem><selectitem value=\"3\" disabled>Astro\n          </selectitem><selectitem value=\"4\">Gatsby</selectitem></selectcontent></select></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "disabled",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-27",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-27",
              "path": "registry/default/components/select/select-27.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-27",
              "path": "registry/default/components/select/select-27.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-27",
              "path": "registry/default/components/select/select-27.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-27",
              "path": "registry/default/components/select/select-27.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-28",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-28.tsx",
          "type": "registry:component",
          "target": "components/ui/select-28.tsx",
          "content": "import { useId } from 'react'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"group relative\">\n      <label\n        htmlFor={id}\n        className=\"bg-background text-foreground absolute start-1 top-0 z-10 block -translate-y-1/2 px-2 text-xs font-medium group-has-disabled:opacity-50\"\n      >\n        Select with overlapping label\n      </label>\n      <Select>\n        <SelectTrigger id={id}>\n          <SelectValue placeholder=\"Select framework\" />\n        </SelectTrigger>\n        <SelectContent>\n          <SelectItem value=\"1\">React</SelectItem>\n          <SelectItem value=\"2\">Next.js</SelectItem>\n          <SelectItem value=\"3\">Astro</SelectItem>\n          <SelectItem value=\"4\">Gatsby</SelectItem>\n        </SelectContent>\n      </Select>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-28.vue",
          "target": "components/ui/select-28.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-28';\n\n</script>\n\n<template>\n  <div class=\"group relative\"><label :for=\"id\" class=\"bg-background text-foreground absolute start-1 top-0 z-10 block -translate-y-1/2 px-2 text-xs font-medium group-has-disabled:opacity-50\">Select with overlapping label\n      </label><Select><SelectTrigger :id=\"id\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent><SelectItem value=\"1\">React</SelectItem><SelectItem value=\"2\">Next.js</SelectItem><SelectItem value=\"3\">Astro</SelectItem><SelectItem value=\"4\">Gatsby</SelectItem></SelectContent></Select></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-28.html",
          "target": "components/ui/select-28.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"group relative\"><label htmlfor=\"${id}\" class=\"bg-background text-foreground absolute start-1 top-0 z-10 block -translate-y-1/2 px-2 text-xs font-medium group-has-disabled:opacity-50\">Select with overlapping label\n      </label><Select><SelectTrigger id=\"${id}\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent><SelectItem value=\"1\">React</SelectItem><SelectItem value=\"2\">Next.js</SelectItem><SelectItem value=\"3\">Astro</SelectItem><SelectItem value=\"4\">Gatsby</SelectItem></SelectContent></Select></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-28.wxml",
          "target": "components/ui/select-28/select-28.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"group relative\"><label htmlfor=\"{{id}}\" class=\"bg-background text-foreground absolute start-1 top-0 z-10 block -translate-y-1/2 px-2 text-xs font-medium group-has-disabled:opacity-50\">Select with overlapping label\n      </label><select><selecttrigger id=\"{{id}}\"><selectvalue placeholder=\"Select framework\" /></selecttrigger><selectcontent><selectitem value=\"1\">React</selectitem><selectitem value=\"2\">Next.js</selectitem><selectitem value=\"3\">Astro</selectitem><selectitem value=\"4\">Gatsby</selectitem></selectcontent></select></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-28",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-28",
              "path": "registry/default/components/select/select-28.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-28",
              "path": "registry/default/components/select/select-28.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-28",
              "path": "registry/default/components/select/select-28.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-28",
              "path": "registry/default/components/select/select-28.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-29",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-29.tsx",
          "type": "registry:component",
          "target": "components/ui/select-29.tsx",
          "content": "import { useId } from 'react'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"border-input bg-background focus-within:border-ring focus-within:ring-ring/50 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40 has-aria-invalid:border-destructive relative rounded-md border shadow-xs transition-[color,box-shadow] outline-none focus-within:ring-[3px] has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50 has-[input:is(:disabled)]:*:pointer-events-none\">\n      <label htmlFor={id} className=\"text-foreground block px-3 pt-2 text-xs font-medium\">\n        Select with inset label\n      </label>\n      <Select>\n        <SelectTrigger\n          id={id}\n          className=\"border-none bg-transparent shadow-none focus:ring-0 focus:ring-offset-0\"\n        >\n          <SelectValue placeholder=\"Select framework\" />\n        </SelectTrigger>\n        <SelectContent>\n          <SelectItem value=\"1\">React</SelectItem>\n          <SelectItem value=\"2\">Next.js</SelectItem>\n          <SelectItem value=\"3\">Astro</SelectItem>\n          <SelectItem value=\"4\">Gatsby</SelectItem>\n        </SelectContent>\n      </Select>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-29.vue",
          "target": "components/ui/select-29.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-29';\n\n</script>\n\n<template>\n  <div class=\"border-input bg-background focus-within:border-ring focus-within:ring-ring/50 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40 has-aria-invalid:border-destructive relative rounded-md border shadow-xs transition-[color,box-shadow] outline-none focus-within:ring-[3px] has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50 has-[input:is(:disabled)]:*:pointer-events-none\"><label :for=\"id\" class=\"text-foreground block px-3 pt-2 text-xs font-medium\">Select with inset label\n      </label><Select><SelectTrigger :id=\"id\" class=\"border-none bg-transparent shadow-none focus:ring-0 focus:ring-offset-0\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent><SelectItem value=\"1\">React</SelectItem><SelectItem value=\"2\">Next.js</SelectItem><SelectItem value=\"3\">Astro</SelectItem><SelectItem value=\"4\">Gatsby</SelectItem></SelectContent></Select></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-29.html",
          "target": "components/ui/select-29.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"border-input bg-background focus-within:border-ring focus-within:ring-ring/50 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40 has-aria-invalid:border-destructive relative rounded-md border shadow-xs transition-[color,box-shadow] outline-none focus-within:ring-[3px] has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50 has-[input:is(:disabled)]:*:pointer-events-none\"><label htmlfor=\"${id}\" class=\"text-foreground block px-3 pt-2 text-xs font-medium\">Select with inset label\n      </label><Select><SelectTrigger id=\"${id}\" class=\"border-none bg-transparent shadow-none focus:ring-0 focus:ring-offset-0\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent><SelectItem value=\"1\">React</SelectItem><SelectItem value=\"2\">Next.js</SelectItem><SelectItem value=\"3\">Astro</SelectItem><SelectItem value=\"4\">Gatsby</SelectItem></SelectContent></Select></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-29.wxml",
          "target": "components/ui/select-29/select-29.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"border-input bg-background focus-within:border-ring focus-within:ring-ring/50 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40 has-aria-invalid:border-destructive relative rounded-md border shadow-xs transition-[color,box-shadow] outline-none focus-within:ring-[3px] has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50 has-[input:is(:disabled)]:*:pointer-events-none\"><label htmlfor=\"{{id}}\" class=\"text-foreground block px-3 pt-2 text-xs font-medium\">Select with inset label\n      </label><select><selecttrigger id=\"{{id}}\" class=\"border-none bg-transparent shadow-none focus:ring-0 focus:ring-offset-0\"><selectvalue placeholder=\"Select framework\" /></selecttrigger><selectcontent><selectitem value=\"1\">React</selectitem><selectitem value=\"2\">Next.js</selectitem><selectitem value=\"3\">Astro</selectitem><selectitem value=\"4\">Gatsby</selectitem></selectcontent></select></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-29",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-29",
              "path": "registry/default/components/select/select-29.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-29",
              "path": "registry/default/components/select/select-29.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-29",
              "path": "registry/default/components/select/select-29.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-29",
              "path": "registry/default/components/select/select-29.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-30",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-30.tsx",
          "type": "registry:component",
          "target": "components/ui/select-30.tsx",
          "content": "import { useId, useMemo } from 'react'\nimport { Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n\n  const timezones = Intl.supportedValuesOf('timeZone')\n\n  const formattedTimezones = useMemo(() => {\n    return timezones\n      .map((timezone) => {\n        const formatter = new Intl.DateTimeFormat('en', {\n          timeZone: timezone,\n          timeZoneName: 'shortOffset',\n        })\n        const parts = formatter.formatToParts(new Date())\n        const offset = parts.find((part) => part.type === 'timeZoneName')?.value || ''\n        const modifiedOffset = offset === 'GMT' ? 'GMT+0' : offset\n\n        return {\n          value: timezone,\n          label: `(${modifiedOffset}) ${timezone.replace(/_/g, ' ')}`,\n          numericOffset: parseInt(offset.replace('GMT', '').replace('+', '') || '0'),\n        }\n      })\n      .sort((a, b) => a.numericOffset - b.numericOffset)\n  }, [timezones])\n\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Timezone select</Label>\n      <Select defaultValue=\"Europe/London\">\n        <SelectTrigger id={id}>\n          <SelectValue placeholder=\"Select timezone\" />\n        </SelectTrigger>\n        <SelectContent>\n          {formattedTimezones.map(({ value, label }) => (\n            <SelectItem key={value} value={value}>\n              {label}\n            </SelectItem>\n          ))}\n        </SelectContent>\n      </Select>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-30.vue",
          "target": "components/ui/select-30.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/vue';\n\nconst id = 'select-30';\nconst timezones = Intl.supportedValuesOf('timeZone');\nconst formattedTimezones = timezones\n  .map((timezone) => {\n    const formatter = new Intl.DateTimeFormat('en', {\n      timeZone: timezone,\n      timeZoneName: 'shortOffset',\n    });\n    const parts = formatter.formatToParts(new Date());\n    const offset = parts.find((part) => part.type === 'timeZoneName')?.value || '';\n    const modifiedOffset = offset === 'GMT' ? 'GMT+0' : offset;\n\n    return {\n      value: timezone,\n      label: `(${modifiedOffset}) ${timezone.replace(/_/g, ' ')}`,\n      numericOffset: parseInt(offset.replace('GMT', '').replace('+', '') || '0'),\n    };\n  })\n  .sort((a, b) => a.numericOffset - b.numericOffset);\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Timezone select</Label><Select default-value=\"Europe/London\"><SelectTrigger :id=\"id\"><SelectValue placeholder=\"Select timezone\" /></SelectTrigger><SelectContent><SelectItem v-for=\"({ value, label }, index) in formattedTimezones\" :key=\"value\" :value=\"value\">{{ label }}</SelectItem></SelectContent></Select></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-30.html",
          "target": "components/ui/select-30.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Timezone select</Label><Select default-value=\"Europe/London\"><SelectTrigger id=\"${id}\"><SelectValue placeholder=\"Select timezone\" /></SelectTrigger><SelectContent><!-- Loop formattedTimezones -->\n<SelectItem key=\"${value}\" value=\"${value}\">${label}</SelectItem>\n<!-- End Loop --></SelectContent></Select></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-30.wxml",
          "target": "components/ui/select-30/select-30.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Timezone select</label><select default-value=\"Europe/London\"><selecttrigger id=\"{{id}}\"><selectvalue placeholder=\"Select timezone\" /></selecttrigger><selectcontent><selectitem wx:for=\"{{formattedTimezones}}\" wx:for-item=\"{ value, label }\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{value}}\" value=\"{{value}}\">{{ label }}</selectitem></selectcontent></select></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "timezone",
          "time",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-30",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-30",
              "path": "registry/default/components/select/select-30.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-30",
              "path": "registry/default/components/select/select-30.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-30",
              "path": "registry/default/components/select/select-30.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-30",
              "path": "registry/default/components/select/select-30.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-31",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-31.tsx",
          "type": "registry:component",
          "target": "components/ui/select-31.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Select with right indicator</Label>\n      <Select defaultValue=\"1\">\n        <SelectTrigger id={id}>\n          <SelectValue placeholder=\"Select framework\" />\n        </SelectTrigger>\n        <SelectContent className=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\">\n          <SelectItem value=\"1\">React</SelectItem>\n          <SelectItem value=\"2\">Next.js</SelectItem>\n          <SelectItem value=\"3\">Astro</SelectItem>\n          <SelectItem value=\"4\">Gatsby</SelectItem>\n        </SelectContent>\n      </Select>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-31.vue",
          "target": "components/ui/select-31.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-31';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Select with right indicator</Label><Select default-value=\"1\"><SelectTrigger :id=\"id\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\"><SelectItem value=\"1\">React</SelectItem><SelectItem value=\"2\">Next.js</SelectItem><SelectItem value=\"3\">Astro</SelectItem><SelectItem value=\"4\">Gatsby</SelectItem></SelectContent></Select></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-31.html",
          "target": "components/ui/select-31.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Select with right indicator</Label><Select default-value=\"1\"><SelectTrigger id=\"${id}\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\"><SelectItem value=\"1\">React</SelectItem><SelectItem value=\"2\">Next.js</SelectItem><SelectItem value=\"3\">Astro</SelectItem><SelectItem value=\"4\">Gatsby</SelectItem></SelectContent></Select></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-31.wxml",
          "target": "components/ui/select-31/select-31.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Select with right indicator</label><select default-value=\"1\"><selecttrigger id=\"{{id}}\"><selectvalue placeholder=\"Select framework\" /></selecttrigger><selectcontent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\"><selectitem value=\"1\">React</selectitem><selectitem value=\"2\">Next.js</selectitem><selectitem value=\"3\">Astro</selectitem><selectitem value=\"4\">Gatsby</selectitem></selectcontent></select></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-31",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-31",
              "path": "registry/default/components/select/select-31.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-31",
              "path": "registry/default/components/select/select-31.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-31",
              "path": "registry/default/components/select/select-31.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-31",
              "path": "registry/default/components/select/select-31.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-32",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-32.tsx",
          "type": "registry:component",
          "target": "components/ui/select-32.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/react'\n\nfunction StatusDot({ className }: { className?: string }) {\n  return (\n    <svg\n      width=\"8\"\n      height=\"8\"\n      fill=\"currentColor\"\n      viewBox=\"0 0 8 8\"\n      xmlns=\"http://www.w3.org/2000/svg\"\n      className={className}\n      aria-hidden=\"true\"\n    >\n      <circle cx=\"4\" cy=\"4\" r=\"4\" />\n    </svg>\n  )\n}\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Status select</Label>\n      <Select defaultValue=\"1\">\n        <SelectTrigger\n          id={id}\n          className=\"[&>span]:flex [&>span]:items-center [&>span]:gap-2 [&>span_svg]:shrink-0\"\n        >\n          <SelectValue placeholder=\"Select status\" />\n        </SelectTrigger>\n        <SelectContent className=\"[&_*[role=option]>span>svg]:text-muted-foreground/80 [&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2 [&_*[role=option]>span]:flex [&_*[role=option]>span]:items-center [&_*[role=option]>span]:gap-2 [&_*[role=option]>span>svg]:shrink-0\">\n          <SelectItem value=\"1\">\n            <span className=\"flex items-center gap-2\">\n              <StatusDot className=\"text-emerald-600\" />\n              <span className=\"truncate\">Completed</span>\n            </span>\n          </SelectItem>\n          <SelectItem value=\"2\">\n            <span className=\"flex items-center gap-2\">\n              <StatusDot className=\"text-blue-500\" />\n              <span className=\"truncate\">In Progress</span>\n            </span>\n          </SelectItem>\n          <SelectItem value=\"3\">\n            <span className=\"flex items-center gap-2\">\n              <StatusDot className=\"text-amber-500\" />\n              <span className=\"truncate\">Pending</span>\n            </span>\n          </SelectItem>\n          <SelectItem value=\"4\">\n            <span className=\"flex items-center gap-2\">\n              <StatusDot className=\"text-gray-500\" />\n              <span className=\"truncate\">Cancelled</span>\n            </span>\n          </SelectItem>\n          <SelectItem value=\"5\">\n            <span className=\"flex items-center gap-2\">\n              <StatusDot className=\"text-red-500\" />\n              <span className=\"truncate\">Failed</span>\n            </span>\n          </SelectItem>\n        </SelectContent>\n      </Select>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-32.vue",
          "target": "components/ui/select-32.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/vue'\n\nconst id = 'select-32'\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\">\n    <Label :htmlFor=\"id\">Status select</Label>\n    <Select default-value=\"1\">\n      <SelectTrigger :id=\"id\" class=\"[&>span]:flex [&>span]:items-center [&>span]:gap-2 [&>span_svg]:shrink-0\">\n        <SelectValue placeholder=\"Select status\" />\n      </SelectTrigger>\n      <SelectContent class=\"[&_*[role=option]>span>svg]:text-muted-foreground/80 [&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2 [&_*[role=option]>span]:flex [&_*[role=option]>span]:items-center [&_*[role=option]>span]:gap-2 [&_*[role=option]>span>svg]:shrink-0\">\n        <SelectItem value=\"1\">\n          <span class=\"flex items-center gap-2\">\n            <svg width=\"8\" height=\"8\" fill=\"currentColor\" viewBox=\"0 0 8 8\" class=\"text-emerald-600\" aria-hidden=\"true\"><circle cx=\"4\" cy=\"4\" r=\"4\" /></svg>\n            <span class=\"truncate\">Completed</span>\n          </span>\n        </SelectItem>\n        <SelectItem value=\"2\">\n          <span class=\"flex items-center gap-2\">\n            <svg width=\"8\" height=\"8\" fill=\"currentColor\" viewBox=\"0 0 8 8\" class=\"text-blue-500\" aria-hidden=\"true\"><circle cx=\"4\" cy=\"4\" r=\"4\" /></svg>\n            <span class=\"truncate\">In Progress</span>\n          </span>\n        </SelectItem>\n        <SelectItem value=\"3\">\n          <span class=\"flex items-center gap-2\">\n            <svg width=\"8\" height=\"8\" fill=\"currentColor\" viewBox=\"0 0 8 8\" class=\"text-amber-500\" aria-hidden=\"true\"><circle cx=\"4\" cy=\"4\" r=\"4\" /></svg>\n            <span class=\"truncate\">Pending</span>\n          </span>\n        </SelectItem>\n        <SelectItem value=\"4\">\n          <span class=\"flex items-center gap-2\">\n            <svg width=\"8\" height=\"8\" fill=\"currentColor\" viewBox=\"0 0 8 8\" class=\"text-gray-500\" aria-hidden=\"true\"><circle cx=\"4\" cy=\"4\" r=\"4\" /></svg>\n            <span class=\"truncate\">Cancelled</span>\n          </span>\n        </SelectItem>\n        <SelectItem value=\"5\">\n          <span class=\"flex items-center gap-2\">\n            <svg width=\"8\" height=\"8\" fill=\"currentColor\" viewBox=\"0 0 8 8\" class=\"text-red-500\" aria-hidden=\"true\"><circle cx=\"4\" cy=\"4\" r=\"4\" /></svg>\n            <span class=\"truncate\">Failed</span>\n          </span>\n        </SelectItem>\n      </SelectContent>\n    </Select>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-32.html",
          "target": "components/ui/select-32.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Status select</Label><Select default-value=\"1\"><SelectTrigger id=\"${id}\" class=\"[&>span]:flex [&>span]:items-center [&>span]:gap-2 [&>span_svg]:shrink-0\"><SelectValue placeholder=\"Select status\" /></SelectTrigger><SelectContent class=\"[&_*[role=option]>span>svg]:text-muted-foreground/80 [&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2 [&_*[role=option]>span]:flex [&_*[role=option]>span]:items-center [&_*[role=option]>span]:gap-2 [&_*[role=option]>span>svg]:shrink-0\"><SelectItem value=\"1\"><span class=\"flex items-center gap-2\"><StatusDot class=\"text-emerald-600\" /><span class=\"truncate\">Completed</span></span></SelectItem><SelectItem value=\"2\"><span class=\"flex items-center gap-2\"><StatusDot class=\"text-blue-500\" /><span class=\"truncate\">In Progress</span></span></SelectItem><SelectItem value=\"3\"><span class=\"flex items-center gap-2\"><StatusDot class=\"text-amber-500\" /><span class=\"truncate\">Pending</span></span></SelectItem><SelectItem value=\"4\"><span class=\"flex items-center gap-2\"><StatusDot class=\"text-gray-500\" /><span class=\"truncate\">Cancelled</span></span></SelectItem><SelectItem value=\"5\"><span class=\"flex items-center gap-2\"><StatusDot class=\"text-red-500\" /><span class=\"truncate\">Failed</span></span></SelectItem></SelectContent></Select></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-32.wxml",
          "target": "components/ui/select-32/select-32.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Status select</label><select default-value=\"1\"><selecttrigger id=\"{{id}}\" class=\"[&>span]:flex [&>span]:items-center [&>span]:gap-2 [&>span_svg]:shrink-0\"><selectvalue placeholder=\"Select status\" /></selecttrigger><selectcontent class=\"[&_*[role=option]>span>svg]:text-muted-foreground/80 [&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2 [&_*[role=option]>span]:flex [&_*[role=option]>span]:items-center [&_*[role=option]>span]:gap-2 [&_*[role=option]>span>svg]:shrink-0\"><selectitem value=\"1\"><text class=\"flex items-center gap-2\"><statusdot class=\"text-emerald-600\" /><text class=\"truncate\">Completed</text></text></selectitem><selectitem value=\"2\"><text class=\"flex items-center gap-2\"><statusdot class=\"text-blue-500\" /><text class=\"truncate\">In Progress</text></text></selectitem><selectitem value=\"3\"><text class=\"flex items-center gap-2\"><statusdot class=\"text-amber-500\" /><text class=\"truncate\">Pending</text></text></selectitem><selectitem value=\"4\"><text class=\"flex items-center gap-2\"><statusdot class=\"text-gray-500\" /><text class=\"truncate\">Cancelled</text></text></selectitem><selectitem value=\"5\"><text class=\"flex items-center gap-2\"><statusdot class=\"text-red-500\" /><text class=\"truncate\">Failed</text></text></selectitem></selectcontent></select></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "status",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-32",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-32",
              "path": "registry/default/components/select/select-32.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-32",
              "path": "registry/default/components/select/select-32.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-32",
              "path": "registry/default/components/select/select-32.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-32",
              "path": "registry/default/components/select/select-32.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-33",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-33.tsx",
          "type": "registry:component",
          "target": "components/ui/select-33.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Select with left text</Label>\n      <Select defaultValue=\"1\">\n        <SelectTrigger id={id}>\n          <span>\n            Language: <SelectValue placeholder=\"Select a language\" />\n          </span>\n        </SelectTrigger>\n        <SelectContent>\n          <SelectItem value=\"1\">Javascript</SelectItem>\n          <SelectItem value=\"2\">Bash</SelectItem>\n        </SelectContent>\n      </Select>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-33.vue",
          "target": "components/ui/select-33.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-33';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Select with left text</Label><Select default-value=\"1\"><SelectTrigger :id=\"id\"><span>Language: <SelectValue placeholder=\"Select a language\" /></span></SelectTrigger><SelectContent><SelectItem value=\"1\">Javascript</SelectItem><SelectItem value=\"2\">Bash</SelectItem></SelectContent></Select></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-33.html",
          "target": "components/ui/select-33.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Select with left text</Label><Select default-value=\"1\"><SelectTrigger id=\"${id}\"><span>Language: <SelectValue placeholder=\"Select a language\" /></span></SelectTrigger><SelectContent><SelectItem value=\"1\">Javascript</SelectItem><SelectItem value=\"2\">Bash</SelectItem></SelectContent></Select></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-33.wxml",
          "target": "components/ui/select-33/select-33.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Select with left text</label><select default-value=\"1\"><selecttrigger id=\"{{id}}\"><text>Language: <selectvalue placeholder=\"Select a language\" /></text></selecttrigger><selectcontent><selectitem value=\"1\">Javascript</selectitem><selectitem value=\"2\">Bash</selectitem></selectcontent></select></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-33",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-33",
              "path": "registry/default/components/select/select-33.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-33",
              "path": "registry/default/components/select/select-33.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-33",
              "path": "registry/default/components/select/select-33.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-33",
              "path": "registry/default/components/select/select-33.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-34",
      "type": "registry:component",
      "dependencies": [
        "@remixicon/react",
        "@timui/react"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/select.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-34.tsx",
          "type": "registry:component",
          "target": "components/ui/select-34.tsx",
          "content": "import { useId } from 'react'\nimport { RiGatsbyLine, RiNextjsLine, RiReactjsLine } from '@remixicon/react'\nimport { Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Options with icon</Label>\n      <Select defaultValue=\"3\">\n        <SelectTrigger\n          id={id}\n          className=\"[&>span_svg]:text-muted-foreground/80 [&>span]:flex [&>span]:items-center [&>span]:gap-2 [&>span_svg]:shrink-0\"\n        >\n          <SelectValue placeholder=\"Select framework\" />\n        </SelectTrigger>\n        <SelectContent className=\"[&_*[role=option]>span>svg]:text-muted-foreground/80 [&_*[role=option]>span]:flex [&_*[role=option]>span]:gap-2 [&_*[role=option]>span>svg]:shrink-0\">\n          <SelectItem value=\"1\">\n            <RiReactjsLine size={16} aria-hidden=\"true\" />\n            <span className=\"truncate\">React</span>\n          </SelectItem>\n          <SelectItem value=\"2\">\n            <RiNextjsLine size={16} aria-hidden=\"true\" />\n            <span className=\"truncate\">Next.js</span>\n          </SelectItem>\n          <SelectItem value=\"3\">\n            <RiGatsbyLine size={16} aria-hidden=\"true\" />\n            <span className=\"truncate\">Gatsby</span>\n          </SelectItem>\n        </SelectContent>\n      </Select>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-34.vue",
          "target": "components/ui/select-34.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { AtomIcon, GlobeIcon, RocketIcon } from 'lucide-vue-next'\nimport { Label } from '@timui/vue'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/vue'\n\nconst id = 'select-34'\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\">\n    <Label :htmlFor=\"id\">Options with icon</Label>\n    <Select default-value=\"3\">\n      <SelectTrigger :id=\"id\" class=\"[&>span_svg]:text-muted-foreground/80 [&>span]:flex [&>span]:items-center [&>span]:gap-2 [&>span_svg]:shrink-0\">\n        <SelectValue placeholder=\"Select framework\" />\n      </SelectTrigger>\n      <SelectContent class=\"[&_*[role=option]>span>svg]:text-muted-foreground/80 [&_*[role=option]>span]:flex [&_*[role=option]>span]:gap-2 [&_*[role=option]>span>svg]:shrink-0\">\n        <SelectItem value=\"1\">\n          <AtomIcon :size=\"16\" aria-hidden=\"true\" />\n          <span class=\"truncate\">React</span>\n        </SelectItem>\n        <SelectItem value=\"2\">\n          <RocketIcon :size=\"16\" aria-hidden=\"true\" />\n          <span class=\"truncate\">Next.js</span>\n        </SelectItem>\n        <SelectItem value=\"3\">\n          <GlobeIcon :size=\"16\" aria-hidden=\"true\" />\n          <span class=\"truncate\">Gatsby</span>\n        </SelectItem>\n      </SelectContent>\n    </Select>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-34.html",
          "target": "components/ui/select-34.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Options with icon</Label><Select default-value=\"3\"><SelectTrigger id=\"${id}\" class=\"[&>span_svg]:text-muted-foreground/80 [&>span]:flex [&>span]:items-center [&>span]:gap-2 [&>span_svg]:shrink-0\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent class=\"[&_*[role=option]>span>svg]:text-muted-foreground/80 [&_*[role=option]>span]:flex [&_*[role=option]>span]:gap-2 [&_*[role=option]>span>svg]:shrink-0\"><SelectItem value=\"1\"><RiReactjsLine size=\"${16}\" aria-hidden=\"true\" /><span class=\"truncate\">React</span></SelectItem><SelectItem value=\"2\"><RiNextjsLine size=\"${16}\" aria-hidden=\"true\" /><span class=\"truncate\">Next.js</span></SelectItem><SelectItem value=\"3\"><RiGatsbyLine size=\"${16}\" aria-hidden=\"true\" /><span class=\"truncate\">Gatsby</span></SelectItem></SelectContent></Select></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-34.wxml",
          "target": "components/ui/select-34/select-34.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Options with icon</label><select default-value=\"3\"><selecttrigger id=\"{{id}}\" class=\"[&>span_svg]:text-muted-foreground/80 [&>span]:flex [&>span]:items-center [&>span]:gap-2 [&>span_svg]:shrink-0\"><selectvalue placeholder=\"Select framework\" /></selecttrigger><selectcontent class=\"[&_*[role=option]>span>svg]:text-muted-foreground/80 [&_*[role=option]>span]:flex [&_*[role=option]>span]:gap-2 [&_*[role=option]>span>svg]:shrink-0\"><selectitem value=\"1\"><rireactjsline size=\"{{16}}\" aria-hidden=\"true\" /><text class=\"truncate\">React</text></selectitem><selectitem value=\"2\"><rinextjsline size=\"{{16}}\" aria-hidden=\"true\" /><text class=\"truncate\">Next.js</text></selectitem><selectitem value=\"3\"><rigatsbyline size=\"{{16}}\" aria-hidden=\"true\" /><text class=\"truncate\">Gatsby</text></selectitem></selectcontent></select></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-34",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-34",
              "path": "registry/default/components/select/select-34.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-34",
              "path": "registry/default/components/select/select-34.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-34",
              "path": "registry/default/components/select/select-34.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-34",
              "path": "registry/default/components/select/select-34.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@remixicon/react",
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-35",
      "type": "registry:component",
      "dependencies": [
        "@remixicon/react",
        "@timui/react"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/select.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-35.tsx",
          "type": "registry:component",
          "target": "components/ui/select-35.tsx",
          "content": "import { useId } from 'react'\nimport { RiGatsbyLine, RiNextjsLine, RiReactjsLine } from '@remixicon/react'\nimport { Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Options with icon and right indicator</Label>\n      <Select defaultValue=\"2\">\n        <SelectTrigger\n          id={id}\n          className=\"[&>span_svg]:text-muted-foreground/80 [&>span]:flex [&>span]:items-center [&>span]:gap-2 [&>span_svg]:shrink-0\"\n        >\n          <SelectValue placeholder=\"Select framework\" />\n        </SelectTrigger>\n        <SelectContent className=\"[&_*[role=option]>span>svg]:text-muted-foreground/80 [&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2 [&_*[role=option]>span]:flex [&_*[role=option]>span]:items-center [&_*[role=option]>span]:gap-2 [&_*[role=option]>span>svg]:shrink-0\">\n          <SelectItem value=\"1\">\n            <RiReactjsLine size={16} aria-hidden=\"true\" />\n            <span className=\"truncate\">React</span>\n          </SelectItem>\n          <SelectItem value=\"2\">\n            <RiNextjsLine size={16} aria-hidden=\"true\" />\n            <span className=\"truncate\">Next.js</span>\n          </SelectItem>\n          <SelectItem value=\"3\">\n            <RiGatsbyLine size={16} aria-hidden=\"true\" />\n            <span className=\"truncate\">Gatsby</span>\n          </SelectItem>\n        </SelectContent>\n      </Select>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-35.vue",
          "target": "components/ui/select-35.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { AtomIcon, GlobeIcon, RocketIcon } from 'lucide-vue-next'\nimport { Label } from '@timui/vue'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/vue'\n\nconst id = 'select-35'\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\">\n    <Label :htmlFor=\"id\">Options with icon and right indicator</Label>\n    <Select default-value=\"2\">\n      <SelectTrigger :id=\"id\" class=\"[&>span_svg]:text-muted-foreground/80 [&>span]:flex [&>span]:items-center [&>span]:gap-2 [&>span_svg]:shrink-0\">\n        <SelectValue placeholder=\"Select framework\" />\n      </SelectTrigger>\n      <SelectContent class=\"[&_*[role=option]>span>svg]:text-muted-foreground/80 [&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2 [&_*[role=option]>span]:flex [&_*[role=option]>span]:items-center [&_*[role=option]>span]:gap-2 [&_*[role=option]>span>svg]:shrink-0\">\n        <SelectItem value=\"1\">\n          <AtomIcon :size=\"16\" aria-hidden=\"true\" />\n          <span class=\"truncate\">React</span>\n        </SelectItem>\n        <SelectItem value=\"2\">\n          <RocketIcon :size=\"16\" aria-hidden=\"true\" />\n          <span class=\"truncate\">Next.js</span>\n        </SelectItem>\n        <SelectItem value=\"3\">\n          <GlobeIcon :size=\"16\" aria-hidden=\"true\" />\n          <span class=\"truncate\">Gatsby</span>\n        </SelectItem>\n      </SelectContent>\n    </Select>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-35.html",
          "target": "components/ui/select-35.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Options with icon and right indicator</Label><Select default-value=\"2\"><SelectTrigger id=\"${id}\" class=\"[&>span_svg]:text-muted-foreground/80 [&>span]:flex [&>span]:items-center [&>span]:gap-2 [&>span_svg]:shrink-0\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent class=\"[&_*[role=option]>span>svg]:text-muted-foreground/80 [&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2 [&_*[role=option]>span]:flex [&_*[role=option]>span]:items-center [&_*[role=option]>span]:gap-2 [&_*[role=option]>span>svg]:shrink-0\"><SelectItem value=\"1\"><RiReactjsLine size=\"${16}\" aria-hidden=\"true\" /><span class=\"truncate\">React</span></SelectItem><SelectItem value=\"2\"><RiNextjsLine size=\"${16}\" aria-hidden=\"true\" /><span class=\"truncate\">Next.js</span></SelectItem><SelectItem value=\"3\"><RiGatsbyLine size=\"${16}\" aria-hidden=\"true\" /><span class=\"truncate\">Gatsby</span></SelectItem></SelectContent></Select></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-35.wxml",
          "target": "components/ui/select-35/select-35.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Options with icon and right indicator</label><select default-value=\"2\"><selecttrigger id=\"{{id}}\" class=\"[&>span_svg]:text-muted-foreground/80 [&>span]:flex [&>span]:items-center [&>span]:gap-2 [&>span_svg]:shrink-0\"><selectvalue placeholder=\"Select framework\" /></selecttrigger><selectcontent class=\"[&_*[role=option]>span>svg]:text-muted-foreground/80 [&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2 [&_*[role=option]>span]:flex [&_*[role=option]>span]:items-center [&_*[role=option]>span]:gap-2 [&_*[role=option]>span>svg]:shrink-0\"><selectitem value=\"1\"><rireactjsline size=\"{{16}}\" aria-hidden=\"true\" /><text class=\"truncate\">React</text></selectitem><selectitem value=\"2\"><rinextjsline size=\"{{16}}\" aria-hidden=\"true\" /><text class=\"truncate\">Next.js</text></selectitem><selectitem value=\"3\"><rigatsbyline size=\"{{16}}\" aria-hidden=\"true\" /><text class=\"truncate\">Gatsby</text></selectitem></selectcontent></select></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-35",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-35",
              "path": "registry/default/components/select/select-35.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-35",
              "path": "registry/default/components/select/select-35.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-35",
              "path": "registry/default/components/select/select-35.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-35",
              "path": "registry/default/components/select/select-35.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@remixicon/react",
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-36",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-36.tsx",
          "type": "registry:component",
          "target": "components/ui/select-36.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Select with description and right indicator</Label>\n      <Select defaultValue=\"2\">\n        <SelectTrigger id={id} className=\"**:data-desc:hidden\">\n          <SelectValue placeholder=\"Choose a plan\" />\n        </SelectTrigger>\n        <SelectContent className=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\">\n          <SelectItem value=\"1\">\n            Standard Plan\n            <span className=\"text-muted-foreground mt-1 block text-xs\" data-desc>\n              Ideal for individuals\n            </span>\n          </SelectItem>\n          <SelectItem value=\"2\">\n            Pro Plan\n            <span className=\"text-muted-foreground mt-1 block text-xs\" data-desc>\n              For professional users\n            </span>\n          </SelectItem>\n          <SelectItem value=\"3\">\n            Enterprise Plan\n            <span className=\"text-muted-foreground mt-1 block text-xs\" data-desc>\n              Built for large teams\n            </span>\n          </SelectItem>\n        </SelectContent>\n      </Select>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-36.vue",
          "target": "components/ui/select-36.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-36';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Select with description and right indicator</Label><Select default-value=\"2\"><SelectTrigger :id=\"id\" class=\"**:data-desc:hidden\"><SelectValue placeholder=\"Choose a plan\" /></SelectTrigger><SelectContent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\"><SelectItem value=\"1\">Standard Plan\n            <span class=\"text-muted-foreground mt-1 block text-xs\" data-desc>Ideal for individuals\n            </span></SelectItem><SelectItem value=\"2\">Pro Plan\n            <span class=\"text-muted-foreground mt-1 block text-xs\" data-desc>For professional users\n            </span></SelectItem><SelectItem value=\"3\">Enterprise Plan\n            <span class=\"text-muted-foreground mt-1 block text-xs\" data-desc>Built for large teams\n            </span></SelectItem></SelectContent></Select></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-36.html",
          "target": "components/ui/select-36.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Select with description and right indicator</Label><Select default-value=\"2\"><SelectTrigger id=\"${id}\" class=\"**:data-desc:hidden\"><SelectValue placeholder=\"Choose a plan\" /></SelectTrigger><SelectContent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\"><SelectItem value=\"1\">Standard Plan\n            <span class=\"text-muted-foreground mt-1 block text-xs\" data-desc>Ideal for individuals\n            </span></SelectItem><SelectItem value=\"2\">Pro Plan\n            <span class=\"text-muted-foreground mt-1 block text-xs\" data-desc>For professional users\n            </span></SelectItem><SelectItem value=\"3\">Enterprise Plan\n            <span class=\"text-muted-foreground mt-1 block text-xs\" data-desc>Built for large teams\n            </span></SelectItem></SelectContent></Select></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-36.wxml",
          "target": "components/ui/select-36/select-36.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Select with description and right indicator</label><select default-value=\"2\"><selecttrigger id=\"{{id}}\" class=\"**:data-desc:hidden\"><selectvalue placeholder=\"Choose a plan\" /></selecttrigger><selectcontent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\"><selectitem value=\"1\">Standard Plan\n            <text class=\"text-muted-foreground mt-1 block text-xs\" data-desc>Ideal for individuals\n            </text></selectitem><selectitem value=\"2\">Pro Plan\n            <text class=\"text-muted-foreground mt-1 block text-xs\" data-desc>For professional users\n            </text></selectitem><selectitem value=\"3\">Enterprise Plan\n            <text class=\"text-muted-foreground mt-1 block text-xs\" data-desc>Built for large teams\n            </text></selectitem></selectcontent></select></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-36",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-36",
              "path": "registry/default/components/select/select-36.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-36",
              "path": "registry/default/components/select/select-36.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-36",
              "path": "registry/default/components/select/select-36.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-36",
              "path": "registry/default/components/select/select-36.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-37",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-37.tsx",
          "type": "registry:component",
          "target": "components/ui/select-37.tsx",
          "content": "import { useId } from 'react'\nimport {\n  Label,\n  Select,\n  SelectContent,\n  SelectGroup,\n  SelectItem,\n  SelectLabel,\n  SelectTrigger,\n  SelectValue,\n} from '@timui/react'\n\nconst countries = [\n  {\n    continent: 'America',\n    items: [\n      { value: '1', label: 'United States', flag: '🇺🇸' },\n      { value: '2', label: 'Canada', flag: '🇨🇦' },\n      { value: '3', label: 'Mexico', flag: '🇲🇽' },\n    ],\n  },\n  {\n    continent: 'Africa',\n    items: [\n      { value: '4', label: 'South Africa', flag: '🇿🇦' },\n      { value: '5', label: 'Nigeria', flag: '🇳🇬' },\n      { value: '6', label: 'Morocco', flag: '🇲🇦' },\n    ],\n  },\n  {\n    continent: 'Asia',\n    items: [\n      { value: '7', label: 'China', flag: '🇨🇳' },\n      { value: '8', label: 'Japan', flag: '🇯🇵' },\n      { value: '9', label: 'India', flag: '🇮🇳' },\n    ],\n  },\n  {\n    continent: 'Europe',\n    items: [\n      { value: '10', label: 'United Kingdom', flag: '🇬🇧' },\n      { value: '11', label: 'France', flag: '🇫🇷' },\n      { value: '12', label: 'Germany', flag: '🇩🇪' },\n    ],\n  },\n  {\n    continent: 'Oceania',\n    items: [\n      { value: '13', label: 'Australia', flag: '🇦🇺' },\n      { value: '14', label: 'New Zealand', flag: '🇳🇿' },\n    ],\n  },\n]\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Options with flag</Label>\n      <Select defaultValue=\"2\">\n        <SelectTrigger\n          id={id}\n          className=\"[&>span_svg]:text-muted-foreground/80 [&>span]:flex [&>span]:items-center [&>span]:gap-2 [&>span_svg]:shrink-0\"\n        >\n          <SelectValue placeholder=\"Select framework\" />\n        </SelectTrigger>\n        <SelectContent className=\"[&_*[role=option]>span>svg]:text-muted-foreground/80 [&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2 [&_*[role=option]>span]:flex [&_*[role=option]>span]:items-center [&_*[role=option]>span]:gap-2 [&_*[role=option]>span>svg]:shrink-0\">\n          {countries.map((continent) => (\n            <SelectGroup key={continent.continent}>\n              <SelectLabel className=\"ps-2\">{continent.continent}</SelectLabel>\n              {continent.items.map((item) => (\n                <SelectItem key={item.value} value={item.value}>\n                  <span className=\"text-lg leading-none\">{item.flag}</span>{' '}\n                  <span className=\"truncate\">{item.label}</span>\n                </SelectItem>\n              ))}\n            </SelectGroup>\n          ))}\n        </SelectContent>\n      </Select>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-37.vue",
          "target": "components/ui/select-37.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-37';\n\n\nconst countries = [\n  {\n    continent: 'America',\n    items: [\n      { value: '1', label: 'United States', flag: '🇺🇸' },\n      { value: '2', label: 'Canada', flag: '🇨🇦' },\n      { value: '3', label: 'Mexico', flag: '🇲🇽' },\n    ],\n  },\n  {\n    continent: 'Africa',\n    items: [\n      { value: '4', label: 'South Africa', flag: '🇿🇦' },\n      { value: '5', label: 'Nigeria', flag: '🇳🇬' },\n      { value: '6', label: 'Morocco', flag: '🇲🇦' },\n    ],\n  },\n  {\n    continent: 'Asia',\n    items: [\n      { value: '7', label: 'China', flag: '🇨🇳' },\n      { value: '8', label: 'Japan', flag: '🇯🇵' },\n      { value: '9', label: 'India', flag: '🇮🇳' },\n    ],\n  },\n  {\n    continent: 'Europe',\n    items: [\n      { value: '10', label: 'United Kingdom', flag: '🇬🇧' },\n      { value: '11', label: 'France', flag: '🇫🇷' },\n      { value: '12', label: 'Germany', flag: '🇩🇪' },\n    ],\n  },\n  {\n    continent: 'Oceania',\n    items: [\n      { value: '13', label: 'Australia', flag: '🇦🇺' },\n      { value: '14', label: 'New Zealand', flag: '🇳🇿' },\n    ],\n  },\n]\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Options with flag</Label><Select default-value=\"2\"><SelectTrigger :id=\"id\" class=\"[&>span_svg]:text-muted-foreground/80 [&>span]:flex [&>span]:items-center [&>span]:gap-2 [&>span_svg]:shrink-0\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent class=\"[&_*[role=option]>span>svg]:text-muted-foreground/80 [&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2 [&_*[role=option]>span]:flex [&_*[role=option]>span]:items-center [&_*[role=option]>span]:gap-2 [&_*[role=option]>span>svg]:shrink-0\"><SelectGroup v-for=\"(continent, index) in countries\" :key=\"continent.continent\"><SelectLabel class=\"ps-2\">{{ continent.continent }}</SelectLabel><SelectItem v-for=\"(item, index) in continent.items\" :key=\"item.value\" :value=\"item.value\"><span class=\"text-lg leading-none\">{{ item.flag }}</span>{{ ' ' }}<span class=\"truncate\">{{ item.label }}</span></SelectItem></SelectGroup></SelectContent></Select></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-37.html",
          "target": "components/ui/select-37.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Options with flag</Label><Select default-value=\"2\"><SelectTrigger id=\"${id}\" class=\"[&>span_svg]:text-muted-foreground/80 [&>span]:flex [&>span]:items-center [&>span]:gap-2 [&>span_svg]:shrink-0\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent class=\"[&_*[role=option]>span>svg]:text-muted-foreground/80 [&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2 [&_*[role=option]>span]:flex [&_*[role=option]>span]:items-center [&_*[role=option]>span]:gap-2 [&_*[role=option]>span>svg]:shrink-0\"><!-- Loop countries -->\n<SelectGroup key=\"${continent.continent}\"><SelectLabel class=\"ps-2\">${continent.continent}</SelectLabel><!-- Loop continent.items -->\n<SelectItem key=\"${item.value}\" value=\"${item.value}\"><span class=\"text-lg leading-none\">${item.flag}</span>${' '}<span class=\"truncate\">${item.label}</span></SelectItem>\n<!-- End Loop --></SelectGroup>\n<!-- End Loop --></SelectContent></Select></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-37.wxml",
          "target": "components/ui/select-37/select-37.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Options with flag</label><select default-value=\"2\"><selecttrigger id=\"{{id}}\" class=\"[&>span_svg]:text-muted-foreground/80 [&>span]:flex [&>span]:items-center [&>span]:gap-2 [&>span_svg]:shrink-0\"><selectvalue placeholder=\"Select framework\" /></selecttrigger><selectcontent class=\"[&_*[role=option]>span>svg]:text-muted-foreground/80 [&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2 [&_*[role=option]>span]:flex [&_*[role=option]>span]:items-center [&_*[role=option]>span]:gap-2 [&_*[role=option]>span>svg]:shrink-0\"><selectgroup wx:for=\"{{countries}}\" wx:for-item=\"continent\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{continent.continent}}\"><selectlabel class=\"ps-2\">{{ continent.continent }}</selectlabel><selectitem wx:for=\"{{continent.items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{item.value}}\" value=\"{{item.value}}\"><text class=\"text-lg leading-none\">{{ item.flag }}</text>{{ ' ' }}<text class=\"truncate\">{{ item.label }}</text></selectitem></selectgroup></selectcontent></select></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "flag",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-37",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-37",
              "path": "registry/default/components/select/select-37.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-37",
              "path": "registry/default/components/select/select-37.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-37",
              "path": "registry/default/components/select/select-37.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-37",
              "path": "registry/default/components/select/select-37.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-38",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-38.tsx",
          "type": "registry:component",
          "target": "components/ui/select-38.tsx",
          "content": "import { useId } from 'react'\nimport {\n  Label,\n  Select,\n  SelectContent,\n  SelectGroup,\n  SelectItem,\n  SelectLabel,\n  SelectTrigger,\n  SelectValue,\n} from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Options with avatar</Label>\n      <Select defaultValue=\"1\">\n        <SelectTrigger\n          id={id}\n          className=\"ps-2 [&>span]:flex [&>span]:items-center [&>span]:gap-2 [&>span_img]:shrink-0\"\n        >\n          <SelectValue placeholder=\"Select framework\" />\n        </SelectTrigger>\n        <SelectContent className=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2 [&_*[role=option]>span]:flex [&_*[role=option]>span]:items-center [&_*[role=option]>span]:gap-2\">\n          <SelectGroup>\n            <SelectLabel className=\"ps-2\">Impersonate user</SelectLabel>\n            <SelectItem value=\"1\">\n              <img\n                className=\"size-5 rounded\"\n                src=\"/avatar-20-01.jpg\"\n                alt=\"Frank Allison\"\n                width={20}\n                height={20}\n              />\n              <span className=\"truncate\">Jenny Hamilton</span>\n            </SelectItem>\n            <SelectItem value=\"2\">\n              <img\n                className=\"size-5 rounded\"\n                src=\"/avatar-20-02.jpg\"\n                alt=\"Xavier Guerra\"\n                width={20}\n                height={20}\n              />\n              <span className=\"truncate\">Paul Smith</span>\n            </SelectItem>\n            <SelectItem value=\"3\">\n              <img\n                className=\"size-5 rounded\"\n                src=\"/avatar-20-03.jpg\"\n                alt=\"Anne Kelley\"\n                width={20}\n                height={20}\n              />\n              <span className=\"truncate\">Luna Wyen</span>\n            </SelectItem>\n          </SelectGroup>\n        </SelectContent>\n      </Select>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-38.vue",
          "target": "components/ui/select-38.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-38';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Options with avatar</Label><Select default-value=\"1\"><SelectTrigger :id=\"id\" class=\"ps-2 [&>span]:flex [&>span]:items-center [&>span]:gap-2 [&>span_img]:shrink-0\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2 [&_*[role=option]>span]:flex [&_*[role=option]>span]:items-center [&_*[role=option]>span]:gap-2\"><SelectGroup><SelectLabel class=\"ps-2\">Impersonate user</SelectLabel><SelectItem value=\"1\"><img class=\"size-5 rounded\" src=\"/avatar-20-01.jpg\" alt=\"Frank Allison\" :width=\"20\" :height=\"20\" /><span class=\"truncate\">Jenny Hamilton</span></SelectItem><SelectItem value=\"2\"><img class=\"size-5 rounded\" src=\"/avatar-20-02.jpg\" alt=\"Xavier Guerra\" :width=\"20\" :height=\"20\" /><span class=\"truncate\">Paul Smith</span></SelectItem><SelectItem value=\"3\"><img class=\"size-5 rounded\" src=\"/avatar-20-03.jpg\" alt=\"Anne Kelley\" :width=\"20\" :height=\"20\" /><span class=\"truncate\">Luna Wyen</span></SelectItem></SelectGroup></SelectContent></Select></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-38.html",
          "target": "components/ui/select-38.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Options with avatar</Label><Select default-value=\"1\"><SelectTrigger id=\"${id}\" class=\"ps-2 [&>span]:flex [&>span]:items-center [&>span]:gap-2 [&>span_img]:shrink-0\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2 [&_*[role=option]>span]:flex [&_*[role=option]>span]:items-center [&_*[role=option]>span]:gap-2\"><SelectGroup><SelectLabel class=\"ps-2\">Impersonate user</SelectLabel><SelectItem value=\"1\"><img class=\"size-5 rounded\" src=\"/avatar-20-01.jpg\" alt=\"Frank Allison\" width=\"${20}\" height=\"${20}\" /><span class=\"truncate\">Jenny Hamilton</span></SelectItem><SelectItem value=\"2\"><img class=\"size-5 rounded\" src=\"/avatar-20-02.jpg\" alt=\"Xavier Guerra\" width=\"${20}\" height=\"${20}\" /><span class=\"truncate\">Paul Smith</span></SelectItem><SelectItem value=\"3\"><img class=\"size-5 rounded\" src=\"/avatar-20-03.jpg\" alt=\"Anne Kelley\" width=\"${20}\" height=\"${20}\" /><span class=\"truncate\">Luna Wyen</span></SelectItem></SelectGroup></SelectContent></Select></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-38.wxml",
          "target": "components/ui/select-38/select-38.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Options with avatar</label><select default-value=\"1\"><selecttrigger id=\"{{id}}\" class=\"ps-2 [&>span]:flex [&>span]:items-center [&>span]:gap-2 [&>span_img]:shrink-0\"><selectvalue placeholder=\"Select framework\" /></selecttrigger><selectcontent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2 [&_*[role=option]>span]:flex [&_*[role=option]>span]:items-center [&_*[role=option]>span]:gap-2\"><selectgroup><selectlabel class=\"ps-2\">Impersonate user</selectlabel><selectitem value=\"1\"><image class=\"size-5 rounded\" src=\"/avatar-20-01.jpg\" alt=\"Frank Allison\" width=\"{{20}}\" height=\"{{20}}\" /><text class=\"truncate\">Jenny Hamilton</text></selectitem><selectitem value=\"2\"><image class=\"size-5 rounded\" src=\"/avatar-20-02.jpg\" alt=\"Xavier Guerra\" width=\"{{20}}\" height=\"{{20}}\" /><text class=\"truncate\">Paul Smith</text></selectitem><selectitem value=\"3\"><image class=\"size-5 rounded\" src=\"/avatar-20-03.jpg\" alt=\"Anne Kelley\" width=\"{{20}}\" height=\"{{20}}\" /><text class=\"truncate\">Luna Wyen</text></selectitem></selectgroup></selectcontent></select></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "user",
          "avatar",
          "profile",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-38",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-38",
              "path": "registry/default/components/select/select-38.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-38",
              "path": "registry/default/components/select/select-38.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-38",
              "path": "registry/default/components/select/select-38.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-38",
              "path": "registry/default/components/select/select-38.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-39",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-39.tsx",
          "type": "registry:component",
          "target": "components/ui/select-39.tsx",
          "content": "import { useId } from 'react'\nimport { cn } from '@timui/core'\nimport {\n  Label,\n  Select,\n  SelectContent,\n  SelectGroup,\n  SelectItem,\n  SelectLabel,\n  SelectTrigger,\n  SelectValue,\n} from '@timui/react'\n\nconst Square = ({ className, children }: { className?: string; children: React.ReactNode }) => (\n  <span\n    data-square\n    className={cn(\n      'bg-muted text-muted-foreground flex size-5 items-center justify-center rounded text-xs font-medium',\n      className\n    )}\n    aria-hidden=\"true\"\n  >\n    {children}\n  </span>\n)\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Options with placeholder avatar</Label>\n      <Select defaultValue=\"1\">\n        <SelectTrigger\n          id={id}\n          className=\"ps-2 [&>span]:flex [&>span]:items-center [&>span]:gap-2 [&>span_[data-square]]:shrink-0\"\n        >\n          <SelectValue placeholder=\"Select framework\" />\n        </SelectTrigger>\n        <SelectContent className=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2 [&_*[role=option]>span]:flex [&_*[role=option]>span]:items-center [&_*[role=option]>span]:gap-2\">\n          <SelectGroup>\n            <SelectLabel className=\"ps-2\">Impersonate user</SelectLabel>\n            <SelectItem value=\"1\">\n              <Square className=\"bg-indigo-400/20 text-indigo-500\">F</Square>\n              <span className=\"truncate\">Frank Morris</span>\n            </SelectItem>\n            <SelectItem value=\"2\">\n              <Square className=\"bg-purple-400/20 text-purple-500\">X</Square>\n              <span className=\"truncate\">Xavier Guerra</span>\n            </SelectItem>\n            <SelectItem value=\"3\">\n              <Square className=\"bg-rose-400/20 text-rose-500\">A</Square>\n              <span className=\"truncate\">Anne Kelley</span>\n            </SelectItem>\n          </SelectGroup>\n        </SelectContent>\n      </Select>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-39.vue",
          "target": "components/ui/select-39.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn } from '@timui/core'\nimport { Label } from '@timui/vue'\nimport {\n  Select,\n  SelectContent,\n  SelectGroup,\n  SelectItem,\n  SelectLabel,\n  SelectTrigger,\n  SelectValue,\n} from '@timui/vue'\n\nconst id = 'select-39'\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\">\n    <Label :htmlFor=\"id\">Options with placeholder avatar</Label>\n    <Select default-value=\"1\">\n      <SelectTrigger :id=\"id\" class=\"ps-2 [&>span]:flex [&>span]:items-center [&>span]:gap-2 [&>span_[data-square]]:shrink-0\">\n        <SelectValue placeholder=\"Select framework\" />\n      </SelectTrigger>\n      <SelectContent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2 [&_*[role=option]>span]:flex [&_*[role=option]>span]:items-center [&_*[role=option]>span]:gap-2\">\n        <SelectGroup>\n          <SelectLabel class=\"ps-2\">Impersonate user</SelectLabel>\n          <SelectItem value=\"1\">\n            <span :class=\"cn('bg-muted text-muted-foreground flex size-5 items-center justify-center rounded text-xs font-medium', 'bg-indigo-400/20 text-indigo-500')\" data-square aria-hidden=\"true\">F</span>\n            <span class=\"truncate\">Frank Morris</span>\n          </SelectItem>\n          <SelectItem value=\"2\">\n            <span :class=\"cn('bg-muted text-muted-foreground flex size-5 items-center justify-center rounded text-xs font-medium', 'bg-purple-400/20 text-purple-500')\" data-square aria-hidden=\"true\">X</span>\n            <span class=\"truncate\">Xavier Guerra</span>\n          </SelectItem>\n          <SelectItem value=\"3\">\n            <span :class=\"cn('bg-muted text-muted-foreground flex size-5 items-center justify-center rounded text-xs font-medium', 'bg-rose-400/20 text-rose-500')\" data-square aria-hidden=\"true\">A</span>\n            <span class=\"truncate\">Anne Kelley</span>\n          </SelectItem>\n        </SelectGroup>\n      </SelectContent>\n    </Select>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-39.html",
          "target": "components/ui/select-39.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Options with placeholder avatar</Label><Select default-value=\"1\"><SelectTrigger id=\"${id}\" class=\"ps-2 [&>span]:flex [&>span]:items-center [&>span]:gap-2 [&>span_[data-square]]:shrink-0\"><SelectValue placeholder=\"Select framework\" /></SelectTrigger><SelectContent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2 [&_*[role=option]>span]:flex [&_*[role=option]>span]:items-center [&_*[role=option]>span]:gap-2\"><SelectGroup><SelectLabel class=\"ps-2\">Impersonate user</SelectLabel><SelectItem value=\"1\"><Square class=\"bg-indigo-400/20 text-indigo-500\">F</Square><span class=\"truncate\">Frank Morris</span></SelectItem><SelectItem value=\"2\"><Square class=\"bg-purple-400/20 text-purple-500\">X</Square><span class=\"truncate\">Xavier Guerra</span></SelectItem><SelectItem value=\"3\"><Square class=\"bg-rose-400/20 text-rose-500\">A</Square><span class=\"truncate\">Anne Kelley</span></SelectItem></SelectGroup></SelectContent></Select></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-39.wxml",
          "target": "components/ui/select-39/select-39.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Options with placeholder avatar</label><select default-value=\"1\"><selecttrigger id=\"{{id}}\" class=\"ps-2 [&>span]:flex [&>span]:items-center [&>span]:gap-2 [&>span_[data-square]]:shrink-0\"><selectvalue placeholder=\"Select framework\" /></selecttrigger><selectcontent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2 [&_*[role=option]>span]:flex [&_*[role=option]>span]:items-center [&_*[role=option]>span]:gap-2\"><selectgroup><selectlabel class=\"ps-2\">Impersonate user</selectlabel><selectitem value=\"1\"><square class=\"bg-indigo-400/20 text-indigo-500\">F</square><text class=\"truncate\">Frank Morris</text></selectitem><selectitem value=\"2\"><square class=\"bg-purple-400/20 text-purple-500\">X</square><text class=\"truncate\">Xavier Guerra</text></selectitem><selectitem value=\"3\"><square class=\"bg-rose-400/20 text-rose-500\">A</square><text class=\"truncate\">Anne Kelley</text></selectitem></selectgroup></selectcontent></select></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "user",
          "avatar",
          "profile",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-39",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-39",
              "path": "registry/default/components/select/select-39.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-39",
              "path": "registry/default/components/select/select-39.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-39",
              "path": "registry/default/components/select/select-39.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-39",
              "path": "registry/default/components/select/select-39.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/core",
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-40",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/select.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-40.tsx",
          "type": "registry:component",
          "target": "components/ui/select-40.tsx",
          "content": "import { useId } from 'react'\nimport { Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Options with portrait</Label>\n      <Select defaultValue=\"1\">\n        <SelectTrigger\n          id={id}\n          className=\"h-auto ps-2 text-left [&>span]:flex [&>span]:items-center [&>span]:gap-2 [&>span_img]:shrink-0\"\n        >\n          <SelectValue placeholder=\"Choose a plan\" />\n        </SelectTrigger>\n        <SelectContent className=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\">\n          <SelectItem value=\"1\">\n            <span className=\"flex items-center gap-2\">\n              <img\n                className=\"rounded-full\"\n                src=\"/avatar-40-01.jpg\"\n                alt=\"Jenny Hamilton\"\n                width={40}\n                height={40}\n              />\n              <span>\n                <span className=\"block font-medium\">Jenny Hamilton</span>\n                <span className=\"text-muted-foreground mt-0.5 block text-xs\">@jennycodes</span>\n              </span>\n            </span>\n          </SelectItem>\n          <SelectItem value=\"2\">\n            <span className=\"flex items-center gap-2\">\n              <img\n                className=\"rounded-full\"\n                src=\"/avatar-40-02.jpg\"\n                alt=\"Paul Smith\"\n                width={40}\n                height={40}\n              />\n              <span>\n                <span className=\"block font-medium\">Paul Smith</span>\n                <span className=\"text-muted-foreground mt-0.5 block text-xs\">@paulsmith</span>\n              </span>\n            </span>\n          </SelectItem>\n          <SelectItem value=\"3\">\n            <span className=\"flex items-center gap-2\">\n              <img\n                className=\"rounded-full\"\n                src=\"/avatar-40-03.jpg\"\n                alt=\"Luna Wyen\"\n                width={40}\n                height={40}\n              />\n              <span>\n                <span className=\"block font-medium\">Luna Wyen</span>\n                <span className=\"text-muted-foreground mt-0.5 block text-xs\">@wyen.luna</span>\n              </span>\n            </span>\n          </SelectItem>\n        </SelectContent>\n      </Select>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-40.vue",
          "target": "components/ui/select-40.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-40';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Options with portrait</Label><Select default-value=\"1\"><SelectTrigger :id=\"id\" class=\"h-auto ps-2 text-left [&>span]:flex [&>span]:items-center [&>span]:gap-2 [&>span_img]:shrink-0\"><SelectValue placeholder=\"Choose a plan\" /></SelectTrigger><SelectContent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\"><SelectItem value=\"1\"><span class=\"flex items-center gap-2\"><img class=\"rounded-full\" src=\"/avatar-40-01.jpg\" alt=\"Jenny Hamilton\" :width=\"40\" :height=\"40\" /><span><span class=\"block font-medium\">Jenny Hamilton</span><span class=\"text-muted-foreground mt-0.5 block text-xs\">@jennycodes</span></span></span></SelectItem><SelectItem value=\"2\"><span class=\"flex items-center gap-2\"><img class=\"rounded-full\" src=\"/avatar-40-02.jpg\" alt=\"Paul Smith\" :width=\"40\" :height=\"40\" /><span><span class=\"block font-medium\">Paul Smith</span><span class=\"text-muted-foreground mt-0.5 block text-xs\">@paulsmith</span></span></span></SelectItem><SelectItem value=\"3\"><span class=\"flex items-center gap-2\"><img class=\"rounded-full\" src=\"/avatar-40-03.jpg\" alt=\"Luna Wyen\" :width=\"40\" :height=\"40\" /><span><span class=\"block font-medium\">Luna Wyen</span><span class=\"text-muted-foreground mt-0.5 block text-xs\">@wyen.luna</span></span></span></SelectItem></SelectContent></Select></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-40.html",
          "target": "components/ui/select-40.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Options with portrait</Label><Select default-value=\"1\"><SelectTrigger id=\"${id}\" class=\"h-auto ps-2 text-left [&>span]:flex [&>span]:items-center [&>span]:gap-2 [&>span_img]:shrink-0\"><SelectValue placeholder=\"Choose a plan\" /></SelectTrigger><SelectContent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\"><SelectItem value=\"1\"><span class=\"flex items-center gap-2\"><img class=\"rounded-full\" src=\"/avatar-40-01.jpg\" alt=\"Jenny Hamilton\" width=\"${40}\" height=\"${40}\" /><span><span class=\"block font-medium\">Jenny Hamilton</span><span class=\"text-muted-foreground mt-0.5 block text-xs\">@jennycodes</span></span></span></SelectItem><SelectItem value=\"2\"><span class=\"flex items-center gap-2\"><img class=\"rounded-full\" src=\"/avatar-40-02.jpg\" alt=\"Paul Smith\" width=\"${40}\" height=\"${40}\" /><span><span class=\"block font-medium\">Paul Smith</span><span class=\"text-muted-foreground mt-0.5 block text-xs\">@paulsmith</span></span></span></SelectItem><SelectItem value=\"3\"><span class=\"flex items-center gap-2\"><img class=\"rounded-full\" src=\"/avatar-40-03.jpg\" alt=\"Luna Wyen\" width=\"${40}\" height=\"${40}\" /><span><span class=\"block font-medium\">Luna Wyen</span><span class=\"text-muted-foreground mt-0.5 block text-xs\">@wyen.luna</span></span></span></SelectItem></SelectContent></Select></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-40.wxml",
          "target": "components/ui/select-40/select-40.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Options with portrait</label><select default-value=\"1\"><selecttrigger id=\"{{id}}\" class=\"h-auto ps-2 text-left [&>span]:flex [&>span]:items-center [&>span]:gap-2 [&>span_img]:shrink-0\"><selectvalue placeholder=\"Choose a plan\" /></selecttrigger><selectcontent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\"><selectitem value=\"1\"><text class=\"flex items-center gap-2\"><image class=\"rounded-full\" src=\"/avatar-40-01.jpg\" alt=\"Jenny Hamilton\" width=\"{{40}}\" height=\"{{40}}\" /><text><text class=\"block font-medium\">Jenny Hamilton</text><text class=\"text-muted-foreground mt-0.5 block text-xs\">@jennycodes</text></text></text></selectitem><selectitem value=\"2\"><text class=\"flex items-center gap-2\"><image class=\"rounded-full\" src=\"/avatar-40-02.jpg\" alt=\"Paul Smith\" width=\"{{40}}\" height=\"{{40}}\" /><text><text class=\"block font-medium\">Paul Smith</text><text class=\"text-muted-foreground mt-0.5 block text-xs\">@paulsmith</text></text></text></selectitem><selectitem value=\"3\"><text class=\"flex items-center gap-2\"><image class=\"rounded-full\" src=\"/avatar-40-03.jpg\" alt=\"Luna Wyen\" width=\"{{40}}\" height=\"{{40}}\" /><text><text class=\"block font-medium\">Luna Wyen</text><text class=\"text-muted-foreground mt-0.5 block text-xs\">@wyen.luna</text></text></text></selectitem></selectcontent></select></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "user",
          "avatar",
          "profile",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-40",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-40",
              "path": "registry/default/components/select/select-40.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-40",
              "path": "registry/default/components/select/select-40.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-40",
              "path": "registry/default/components/select/select-40.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-40",
              "path": "registry/default/components/select/select-40.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-41",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/command.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/popover.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-41.tsx",
          "type": "registry:component",
          "target": "components/ui/select-41.tsx",
          "content": "'use client'\n\nimport { useId, useState } from 'react'\nimport { cn } from '@timui/core'\nimport {\n  Button,\n  Command,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandItem,\n  CommandList,\n  Label,\n  Popover,\n  PopoverContent,\n  PopoverTrigger,\n} from '@timui/react'\nimport { CheckIcon, ChevronDownIcon } from 'lucide-react'\n\nconst frameworks = [\n  {\n    value: 'next.js',\n    label: 'Next.js',\n  },\n  {\n    value: 'sveltekit',\n    label: 'SvelteKit',\n  },\n  {\n    value: 'nuxt.js',\n    label: 'Nuxt.js',\n  },\n  {\n    value: 'remix',\n    label: 'Remix',\n  },\n  {\n    value: 'astro',\n    label: 'Astro',\n  },\n  {\n    value: 'angular',\n    label: 'Angular',\n  },\n  {\n    value: 'vue',\n    label: 'Vue.js',\n  },\n  {\n    value: 'react',\n    label: 'React',\n  },\n  {\n    value: 'ember',\n    label: 'Ember.js',\n  },\n  {\n    value: 'gatsby',\n    label: 'Gatsby',\n  },\n  {\n    value: 'eleventy',\n    label: 'Eleventy',\n  },\n  {\n    value: 'solid',\n    label: 'SolidJS',\n  },\n  {\n    value: 'preact',\n    label: 'Preact',\n  },\n  {\n    value: 'qwik',\n    label: 'Qwik',\n  },\n  {\n    value: 'alpine',\n    label: 'Alpine.js',\n  },\n  {\n    value: 'lit',\n    label: 'Lit',\n  },\n]\n\nexport default function Component() {\n  const id = useId()\n  const [open, setOpen] = useState<boolean>(false)\n  const [value, setValue] = useState<string>('')\n\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Select with search</Label>\n      <Popover open={open} onOpenChange={setOpen}>\n        <PopoverTrigger asChild>\n          <Button\n            id={id}\n            variant=\"outline\"\n            role=\"combobox\"\n            aria-expanded={open}\n            className=\"bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]\"\n          >\n            <span className={cn('truncate', !value && 'text-muted-foreground')}>\n              {value\n                ? frameworks.find((framework) => framework.value === value)?.label\n                : 'Select framework'}\n            </span>\n            <ChevronDownIcon\n              size={16}\n              className=\"text-muted-foreground/80 shrink-0\"\n              aria-hidden=\"true\"\n            />\n          </Button>\n        </PopoverTrigger>\n        <PopoverContent\n          className=\"border-input w-full min-w-[var(--radix-popper-anchor-width)] p-0\"\n          align=\"start\"\n        >\n          <Command>\n            <CommandInput placeholder=\"Search framework...\" />\n            <CommandList>\n              <CommandEmpty>No framework found.</CommandEmpty>\n              <CommandGroup>\n                {frameworks.map((framework) => (\n                  <CommandItem\n                    key={framework.value}\n                    value={framework.value}\n                    onSelect={(currentValue) => {\n                      const val = currentValue as string\n                      setValue(val === value ? '' : val)\n                      setOpen(false)\n                    }}\n                  >\n                    {framework.label}\n                    {value === framework.value && <CheckIcon size={16} className=\"ml-auto\" />}\n                  </CommandItem>\n                ))}\n              </CommandGroup>\n            </CommandList>\n          </Command>\n        </PopoverContent>\n      </Popover>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-41.vue",
          "target": "components/ui/select-41.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { cn } from '@timui/core';\nimport { CheckIcon, ChevronDownIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { Command } from '@timui/vue';\nimport { CommandEmpty } from '@timui/vue';\nimport { CommandGroup } from '@timui/vue';\nimport { CommandInput } from '@timui/vue';\nimport { CommandItem } from '@timui/vue';\nimport { CommandList } from '@timui/vue';\nimport { Label } from '@timui/vue';\nimport { Popover, PopoverContent, PopoverTrigger } from '@timui/vue';\n\n\n\nconst open = ref<boolean>(false);\nconst value = ref<string>('');\n\n\nfunction setValue(next: typeof value.value | ((prev: typeof value.value) => typeof value.value)) {\n  value.value = typeof next === 'function'\n    ? (next as (prev: typeof value.value) => typeof value.value)(value.value)\n    : next;\n}\n\nfunction setOpen(next: typeof open.value | ((prev: typeof open.value) => typeof open.value)) {\n  open.value = typeof next === 'function'\n    ? (next as (prev: typeof open.value) => typeof open.value)(open.value)\n    : next;\n}\n\n\nconst id = 'select-41';\n\n\nconst frameworks = [\n  {\n    value: 'next.js',\n    label: 'Next.js',\n  },\n  {\n    value: 'sveltekit',\n    label: 'SvelteKit',\n  },\n  {\n    value: 'nuxt.js',\n    label: 'Nuxt.js',\n  },\n  {\n    value: 'remix',\n    label: 'Remix',\n  },\n  {\n    value: 'astro',\n    label: 'Astro',\n  },\n  {\n    value: 'angular',\n    label: 'Angular',\n  },\n  {\n    value: 'vue',\n    label: 'Vue.js',\n  },\n  {\n    value: 'react',\n    label: 'React',\n  },\n  {\n    value: 'ember',\n    label: 'Ember.js',\n  },\n  {\n    value: 'gatsby',\n    label: 'Gatsby',\n  },\n  {\n    value: 'eleventy',\n    label: 'Eleventy',\n  },\n  {\n    value: 'solid',\n    label: 'SolidJS',\n  },\n  {\n    value: 'preact',\n    label: 'Preact',\n  },\n  {\n    value: 'qwik',\n    label: 'Qwik',\n  },\n  {\n    value: 'alpine',\n    label: 'Alpine.js',\n  },\n  {\n    value: 'lit',\n    label: 'Lit',\n  },\n]\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Select with search</Label><Popover :open=\"open\" @update:open=\"setOpen\"><PopoverTrigger as-child><Button :id=\"id\" variant=\"outline\" role=\"combobox\" :aria-expanded=\"open\" class=\"bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]\"><span :class=\"cn('truncate', !value && 'text-muted-foreground')\"><template v-if=\"value\">\n{{ frameworks.find((framework) => framework.value === value)?.label }}\n</template>\n<template v-else>\n{{ 'Select framework' }}\n</template></span><ChevronDownIcon :size=\"16\" class=\"text-muted-foreground/80 shrink-0\" aria-hidden=\"true\" /></Button></PopoverTrigger><PopoverContent class=\"border-input w-full min-w-[var(--radix-popper-anchor-width)] p-0\" align=\"start\"><Command><CommandInput placeholder=\"Search framework...\" /><CommandList><CommandEmpty>No framework found.</CommandEmpty><CommandGroup><CommandItem v-for=\"(framework, index) in frameworks\" :key=\"framework.value\" :value=\"framework.value\" :onSelect=\"(currentValue) => {\n                      const val = currentValue as string\n                      setValue(val === value ? '' : val)\n                      setOpen(false)\n                    }\">{{ framework.label }}<CheckIcon v-if=\"value === framework.value\" :size=\"16\" class=\"ml-auto\" /></CommandItem></CommandGroup></CommandList></Command></PopoverContent></Popover></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-41.html",
          "target": "components/ui/select-41.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Select with search</Label><Popover open=\"${open}\" on-open-change=\"${setOpen}\"><PopoverTrigger aschild><Button id=\"${id}\" variant=\"outline\" role=\"combobox\" aria-expanded=\"${open}\" class=\"bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]\"><span class=\"${cn('truncate', !value && 'text-muted-foreground')}\"><!-- if value -->\n${frameworks.find((framework) => framework.value === value)?.label}\n<!-- else -->\n${'Select framework'}\n<!-- endif --></span><ChevronDownIcon size=\"${16}\" class=\"text-muted-foreground/80 shrink-0\" aria-hidden=\"true\" /></Button></PopoverTrigger><PopoverContent class=\"border-input w-full min-w-[var(--radix-popper-anchor-width)] p-0\" align=\"start\"><Command><CommandInput placeholder=\"Search framework...\" /><CommandList><CommandEmpty>No framework found.</CommandEmpty><CommandGroup><!-- Loop frameworks -->\n<CommandItem key=\"${framework.value}\" value=\"${framework.value}\" onselect=\"${(currentValue) => {\n                      const val = currentValue as string\n                      setValue(val === value ? '' : val)\n                      setOpen(false)\n                    }}\">${framework.label}<!-- if value === framework.value -->\n<CheckIcon size=\"${16}\" class=\"ml-auto\" />\n<!-- endif --></CommandItem>\n<!-- End Loop --></CommandGroup></CommandList></Command></PopoverContent></Popover></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-41.wxml",
          "target": "components/ui/select-41/select-41.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Select with search</label><popover open=\"{{open}}\" bindchange=\"setOpen\"><popovertrigger aschild><button id=\"{{id}}\" variant=\"outline\" role=\"combobox\" aria-expanded=\"{{open}}\" class=\"bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]\"><text class=\"{{cn('truncate', !value && 'text-muted-foreground')}}\"><block wx:if=\"{{value}}\">\n{{ frameworks.find((framework) => framework.value === value)?.label }}\n</block>\n<block wx:else>\n{{ 'Select framework' }}\n</block></text><chevrondownicon size=\"{{16}}\" class=\"text-muted-foreground/80 shrink-0\" aria-hidden=\"true\" /></button></popovertrigger><popovercontent class=\"border-input w-full min-w-[var(--radix-popper-anchor-width)] p-0\" align=\"start\"><command><commandinput placeholder=\"Search framework...\" /><commandlist><commandempty>No framework found.</commandempty><commandgroup><commanditem wx:for=\"{{frameworks}}\" wx:for-item=\"framework\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{framework.value}}\" value=\"{{framework.value}}\" onselect=\"{{(currentValue) => {\n                      const val = currentValue as string\n                      setValue(val === value ? '' : val)\n                      setOpen(false)\n                    }}}\">{{ framework.label }}<checkicon wx:if=\"{{value === framework.value}}\" size=\"{{16}}\" class=\"ml-auto\" /></commanditem></commandgroup></commandlist></command></popovercontent></popover></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "command",
          "combobox",
          "popover",
          "search",
          "autocomplete",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-41",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-41",
              "path": "registry/default/components/select/select-41.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-41",
              "path": "registry/default/components/select/select-41.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-41",
              "path": "registry/default/components/select/select-41.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-41",
              "path": "registry/default/components/select/select-41.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/core",
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-42",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/command.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/popover.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-42.tsx",
          "type": "registry:component",
          "target": "components/ui/select-42.tsx",
          "content": "'use client'\n\nimport { useId, useState } from 'react'\nimport { cn } from '@timui/core'\nimport {\n  Button,\n  Command,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandItem,\n  CommandList,\n  CommandSeparator,\n  Label,\n  Popover,\n  PopoverContent,\n  PopoverTrigger,\n} from '@timui/react'\nimport { CheckIcon, ChevronDownIcon, PlusIcon } from 'lucide-react'\n\nconst organizations = [\n  {\n    value: 'originui',\n    label: 'Timkit UI',\n  },\n  {\n    value: 'cruip',\n    label: 'Cruip',\n  },\n]\n\nexport default function Component() {\n  const id = useId()\n  const [open, setOpen] = useState<boolean>(false)\n  const [value, setValue] = useState<string>('originui')\n\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Select with search and button</Label>\n      <Popover open={open} onOpenChange={setOpen}>\n        <PopoverTrigger asChild>\n          <Button\n            id={id}\n            variant=\"outline\"\n            role=\"combobox\"\n            aria-expanded={open}\n            className=\"bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]\"\n          >\n            <span className={cn('truncate', !value && 'text-muted-foreground')}>\n              {value\n                ? organizations.find((organization) => organization.value === value)?.label\n                : 'Select organization'}\n            </span>\n            <ChevronDownIcon\n              size={16}\n              className=\"text-muted-foreground/80 shrink-0\"\n              aria-hidden=\"true\"\n            />\n          </Button>\n        </PopoverTrigger>\n        <PopoverContent\n          className=\"border-input w-full min-w-[var(--radix-popper-anchor-width)] p-0\"\n          align=\"start\"\n        >\n          <Command>\n            <CommandInput placeholder=\"Find organization\" />\n            <CommandList>\n              <CommandEmpty>No organization found.</CommandEmpty>\n              <CommandGroup>\n                {organizations.map((organization) => (\n                  <CommandItem\n                    key={organization.value}\n                    value={organization.value}\n                    onSelect={(currentValue) => {\n                      const val = currentValue as string\n                      setValue(val === value ? '' : val)\n                      setOpen(false)\n                    }}\n                  >\n                    {organization.label}\n                    {value === organization.value && <CheckIcon size={16} className=\"ml-auto\" />}\n                  </CommandItem>\n                ))}\n              </CommandGroup>\n              <CommandSeparator />\n              <CommandGroup>\n                <Button variant=\"ghost\" className=\"w-full justify-start font-normal\">\n                  <PlusIcon size={16} className=\"-ms-2 opacity-60\" aria-hidden=\"true\" />\n                  New organization\n                </Button>\n              </CommandGroup>\n            </CommandList>\n          </Command>\n        </PopoverContent>\n      </Popover>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-42.vue",
          "target": "components/ui/select-42.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { cn } from '@timui/core';\nimport { CheckIcon, ChevronDownIcon, PlusIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { Command } from '@timui/vue';\nimport { CommandEmpty } from '@timui/vue';\nimport { CommandGroup } from '@timui/vue';\nimport { CommandInput } from '@timui/vue';\nimport { CommandItem } from '@timui/vue';\nimport { CommandList } from '@timui/vue';\nimport { CommandSeparator } from '@timui/vue';\nimport { Label } from '@timui/vue';\nimport { Popover, PopoverContent, PopoverTrigger } from '@timui/vue';\n\n\n\nconst open = ref<boolean>(false);\nconst value = ref<string>('originui');\n\n\nfunction setValue(next: typeof value.value | ((prev: typeof value.value) => typeof value.value)) {\n  value.value = typeof next === 'function'\n    ? (next as (prev: typeof value.value) => typeof value.value)(value.value)\n    : next;\n}\n\nfunction setOpen(next: typeof open.value | ((prev: typeof open.value) => typeof open.value)) {\n  open.value = typeof next === 'function'\n    ? (next as (prev: typeof open.value) => typeof open.value)(open.value)\n    : next;\n}\n\n\nconst id = 'select-42';\n\n\nconst organizations = [\n  {\n    value: 'originui',\n    label: 'Timkit UI',\n  },\n  {\n    value: 'cruip',\n    label: 'Cruip',\n  },\n]\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Select with search and button</Label><Popover :open=\"open\" @update:open=\"setOpen\"><PopoverTrigger as-child><Button :id=\"id\" variant=\"outline\" role=\"combobox\" :aria-expanded=\"open\" class=\"bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]\"><span :class=\"cn('truncate', !value && 'text-muted-foreground')\"><template v-if=\"value\">\n{{ organizations.find((organization) => organization.value === value)?.label }}\n</template>\n<template v-else>\n{{ 'Select organization' }}\n</template></span><ChevronDownIcon :size=\"16\" class=\"text-muted-foreground/80 shrink-0\" aria-hidden=\"true\" /></Button></PopoverTrigger><PopoverContent class=\"border-input w-full min-w-[var(--radix-popper-anchor-width)] p-0\" align=\"start\"><Command><CommandInput placeholder=\"Find organization\" /><CommandList><CommandEmpty>No organization found.</CommandEmpty><CommandGroup><CommandItem v-for=\"(organization, index) in organizations\" :key=\"organization.value\" :value=\"organization.value\" :onSelect=\"(currentValue) => {\n                      const val = currentValue as string\n                      setValue(val === value ? '' : val)\n                      setOpen(false)\n                    }\">{{ organization.label }}<CheckIcon v-if=\"value === organization.value\" :size=\"16\" class=\"ml-auto\" /></CommandItem></CommandGroup><CommandSeparator /><CommandGroup><Button variant=\"ghost\" class=\"w-full justify-start font-normal\"><PlusIcon :size=\"16\" class=\"-ms-2 opacity-60\" aria-hidden=\"true\" />New organization\n                </Button></CommandGroup></CommandList></Command></PopoverContent></Popover></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-42.html",
          "target": "components/ui/select-42.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Select with search and button</Label><Popover open=\"${open}\" on-open-change=\"${setOpen}\"><PopoverTrigger aschild><Button id=\"${id}\" variant=\"outline\" role=\"combobox\" aria-expanded=\"${open}\" class=\"bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]\"><span class=\"${cn('truncate', !value && 'text-muted-foreground')}\"><!-- if value -->\n${organizations.find((organization) => organization.value === value)?.label}\n<!-- else -->\n${'Select organization'}\n<!-- endif --></span><ChevronDownIcon size=\"${16}\" class=\"text-muted-foreground/80 shrink-0\" aria-hidden=\"true\" /></Button></PopoverTrigger><PopoverContent class=\"border-input w-full min-w-[var(--radix-popper-anchor-width)] p-0\" align=\"start\"><Command><CommandInput placeholder=\"Find organization\" /><CommandList><CommandEmpty>No organization found.</CommandEmpty><CommandGroup><!-- Loop organizations -->\n<CommandItem key=\"${organization.value}\" value=\"${organization.value}\" onselect=\"${(currentValue) => {\n                      const val = currentValue as string\n                      setValue(val === value ? '' : val)\n                      setOpen(false)\n                    }}\">${organization.label}<!-- if value === organization.value -->\n<CheckIcon size=\"${16}\" class=\"ml-auto\" />\n<!-- endif --></CommandItem>\n<!-- End Loop --></CommandGroup><CommandSeparator /><CommandGroup><Button variant=\"ghost\" class=\"w-full justify-start font-normal\"><PlusIcon size=\"${16}\" class=\"-ms-2 opacity-60\" aria-hidden=\"true\" />New organization\n                </Button></CommandGroup></CommandList></Command></PopoverContent></Popover></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-42.wxml",
          "target": "components/ui/select-42/select-42.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Select with search and button</label><popover open=\"{{open}}\" bindchange=\"setOpen\"><popovertrigger aschild><button id=\"{{id}}\" variant=\"outline\" role=\"combobox\" aria-expanded=\"{{open}}\" class=\"bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]\"><text class=\"{{cn('truncate', !value && 'text-muted-foreground')}}\"><block wx:if=\"{{value}}\">\n{{ organizations.find((organization) => organization.value === value)?.label }}\n</block>\n<block wx:else>\n{{ 'Select organization' }}\n</block></text><chevrondownicon size=\"{{16}}\" class=\"text-muted-foreground/80 shrink-0\" aria-hidden=\"true\" /></button></popovertrigger><popovercontent class=\"border-input w-full min-w-[var(--radix-popper-anchor-width)] p-0\" align=\"start\"><command><commandinput placeholder=\"Find organization\" /><commandlist><commandempty>No organization found.</commandempty><commandgroup><commanditem wx:for=\"{{organizations}}\" wx:for-item=\"organization\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{organization.value}}\" value=\"{{organization.value}}\" onselect=\"{{(currentValue) => {\n                      const val = currentValue as string\n                      setValue(val === value ? '' : val)\n                      setOpen(false)\n                    }}}\">{{ organization.label }}<checkicon wx:if=\"{{value === organization.value}}\" size=\"{{16}}\" class=\"ml-auto\" /></commanditem></commandgroup><commandseparator /><commandgroup><button variant=\"ghost\" class=\"w-full justify-start font-normal\"><plusicon size=\"{{16}}\" class=\"-ms-2 opacity-60\" aria-hidden=\"true\" />New organization\n                </button></commandgroup></commandlist></command></popovercontent></popover></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "command",
          "combobox",
          "popover",
          "search",
          "autocomplete",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-42",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-42",
              "path": "registry/default/components/select/select-42.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-42",
              "path": "registry/default/components/select/select-42.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-42",
              "path": "registry/default/components/select/select-42.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-42",
              "path": "registry/default/components/select/select-42.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/core",
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-43",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/command.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/popover.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-43.tsx",
          "type": "registry:component",
          "target": "components/ui/select-43.tsx",
          "content": "'use client'\n\nimport { useId, useMemo, useState } from 'react'\nimport { cn } from '@timui/core'\nimport {\n  Button,\n  Command,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandItem,\n  CommandList,\n  Label,\n  Popover,\n  PopoverContent,\n  PopoverTrigger,\n} from '@timui/react'\nimport { CheckIcon, ChevronDownIcon } from 'lucide-react'\n\nexport default function Component() {\n  const id = useId()\n  const [open, setOpen] = useState<boolean>(false)\n  const [value, setValue] = useState<string>('Europe/London')\n\n  const timezones = Intl.supportedValuesOf('timeZone')\n\n  const formattedTimezones = useMemo(() => {\n    return timezones\n      .map((timezone) => {\n        const formatter = new Intl.DateTimeFormat('en', {\n          timeZone: timezone,\n          timeZoneName: 'shortOffset',\n        })\n        const parts = formatter.formatToParts(new Date())\n        const offset = parts.find((part) => part.type === 'timeZoneName')?.value || ''\n        const modifiedOffset = offset === 'GMT' ? 'GMT+0' : offset\n\n        return {\n          value: timezone,\n          label: `(${modifiedOffset}) ${timezone.replace(/_/g, ' ')}`,\n          numericOffset: parseInt(offset.replace('GMT', '').replace('+', '') || '0'),\n        }\n      })\n      .sort((a, b) => a.numericOffset - b.numericOffset)\n  }, [timezones])\n\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Timezone select with search</Label>\n      <Popover open={open} onOpenChange={setOpen}>\n        <PopoverTrigger asChild>\n          <Button\n            id={id}\n            variant=\"outline\"\n            role=\"combobox\"\n            aria-expanded={open}\n            className=\"bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]\"\n          >\n            <span className={cn('truncate', !value && 'text-muted-foreground')}>\n              {value\n                ? formattedTimezones.find((timezone) => timezone.value === value)?.label\n                : 'Select timezone'}\n            </span>\n            <ChevronDownIcon\n              size={16}\n              className=\"text-muted-foreground/80 shrink-0\"\n              aria-hidden=\"true\"\n            />\n          </Button>\n        </PopoverTrigger>\n        <PopoverContent\n          className=\"border-input w-full min-w-[var(--radix-popper-anchor-width)] p-0\"\n          align=\"start\"\n        >\n          <Command\n            filter={(value, search) => {\n              const normalizedValue = value.toLowerCase()\n              const normalizedSearch = search.toLowerCase().replace(/\\s+/g, '')\n              return normalizedValue.includes(normalizedSearch) ? 1 : 0\n            }}\n          >\n            <CommandInput placeholder=\"Search timezone...\" />\n            <CommandList>\n              <CommandEmpty>No timezone found.</CommandEmpty>\n              <CommandGroup>\n                {formattedTimezones.map(({ value: itemValue, label }) => (\n                  <CommandItem\n                    key={itemValue}\n                    value={itemValue}\n                    onSelect={(currentValue) => {\n                      const val = currentValue as string\n                      setValue(val === value ? '' : val)\n                      setOpen(false)\n                    }}\n                  >\n                    {label}\n                    {value === itemValue && <CheckIcon size={16} className=\"ml-auto\" />}\n                  </CommandItem>\n                ))}\n              </CommandGroup>\n            </CommandList>\n          </Command>\n        </PopoverContent>\n      </Popover>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-43.vue",
          "target": "components/ui/select-43.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { cn } from '@timui/core';\nimport { CheckIcon, ChevronDownIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { Command } from '@timui/vue';\nimport { CommandEmpty } from '@timui/vue';\nimport { CommandGroup } from '@timui/vue';\nimport { CommandInput } from '@timui/vue';\nimport { CommandItem } from '@timui/vue';\nimport { CommandList } from '@timui/vue';\nimport { Label } from '@timui/vue';\nimport { Popover, PopoverContent, PopoverTrigger } from '@timui/vue';\n\n\n\nconst open = ref<boolean>(false);\nconst value = ref<string>('Europe/London');\n\n\nfunction setValue(next: typeof value.value | ((prev: typeof value.value) => typeof value.value)) {\n  value.value = typeof next === 'function'\n    ? (next as (prev: typeof value.value) => typeof value.value)(value.value)\n    : next;\n}\n\nfunction setOpen(next: typeof open.value | ((prev: typeof open.value) => typeof open.value)) {\n  open.value = typeof next === 'function'\n    ? (next as (prev: typeof open.value) => typeof open.value)(open.value)\n    : next;\n}\n\n\nconst id = 'select-43';\n\n\nconst timezones = Intl.supportedValuesOf('timeZone');\nconst formattedTimezones = timezones\n  .map((timezone) => {\n    const formatter = new Intl.DateTimeFormat('en', {\n      timeZone: timezone,\n      timeZoneName: 'shortOffset',\n    });\n    const parts = formatter.formatToParts(new Date());\n    const offset = parts.find((part) => part.type === 'timeZoneName')?.value || '';\n    const modifiedOffset = offset === 'GMT' ? 'GMT+0' : offset;\n\n    return {\n      value: timezone,\n      label: `(${modifiedOffset}) ${timezone.replace(/_/g, ' ')}`,\n      numericOffset: parseInt(offset.replace('GMT', '').replace('+', '') || '0'),\n    };\n  })\n  .sort((a, b) => a.numericOffset - b.numericOffset);\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Timezone select with search</Label><Popover :open=\"open\" @update:open=\"setOpen\"><PopoverTrigger as-child><Button :id=\"id\" variant=\"outline\" role=\"combobox\" :aria-expanded=\"open\" class=\"bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]\"><span :class=\"cn('truncate', !value && 'text-muted-foreground')\"><template v-if=\"value\">\n{{ formattedTimezones.find((timezone) => timezone.value === value)?.label }}\n</template>\n<template v-else>\n{{ 'Select timezone' }}\n</template></span><ChevronDownIcon :size=\"16\" class=\"text-muted-foreground/80 shrink-0\" aria-hidden=\"true\" /></Button></PopoverTrigger><PopoverContent class=\"border-input w-full min-w-[var(--radix-popper-anchor-width)] p-0\" align=\"start\"><Command :filter=\"(value, search) => {\n              const normalizedValue = value.toLowerCase()\n              const normalizedSearch = search.toLowerCase().replace(/\\s+/g, '')\n              return normalizedValue.includes(normalizedSearch) ? 1 : 0\n            }\"><CommandInput placeholder=\"Search timezone...\" /><CommandList><CommandEmpty>No timezone found.</CommandEmpty><CommandGroup><CommandItem v-for=\"({ value: itemValue, label }, index) in formattedTimezones\" :key=\"itemValue\" :value=\"itemValue\" :onSelect=\"(currentValue) => {\n                      const val = currentValue as string\n                      setValue(val === value ? '' : val)\n                      setOpen(false)\n                    }\">{{ label }}<CheckIcon v-if=\"value === itemValue\" :size=\"16\" class=\"ml-auto\" /></CommandItem></CommandGroup></CommandList></Command></PopoverContent></Popover></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-43.html",
          "target": "components/ui/select-43.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Timezone select with search</Label><Popover open=\"${open}\" on-open-change=\"${setOpen}\"><PopoverTrigger aschild><Button id=\"${id}\" variant=\"outline\" role=\"combobox\" aria-expanded=\"${open}\" class=\"bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]\"><span class=\"${cn('truncate', !value && 'text-muted-foreground')}\"><!-- if value -->\n${formattedTimezones.find((timezone) => timezone.value === value)?.label}\n<!-- else -->\n${'Select timezone'}\n<!-- endif --></span><ChevronDownIcon size=\"${16}\" class=\"text-muted-foreground/80 shrink-0\" aria-hidden=\"true\" /></Button></PopoverTrigger><PopoverContent class=\"border-input w-full min-w-[var(--radix-popper-anchor-width)] p-0\" align=\"start\"><Command filter=\"${(value, search) => {\n              const normalizedValue = value.toLowerCase()\n              const normalizedSearch = search.toLowerCase().replace(/\\s+/g, '')\n              return normalizedValue.includes(normalizedSearch) ? 1 : 0\n            }}\"><CommandInput placeholder=\"Search timezone...\" /><CommandList><CommandEmpty>No timezone found.</CommandEmpty><CommandGroup><!-- Loop formattedTimezones -->\n<CommandItem key=\"${itemValue}\" value=\"${itemValue}\" onselect=\"${(currentValue) => {\n                      const val = currentValue as string\n                      setValue(val === value ? '' : val)\n                      setOpen(false)\n                    }}\">${label}<!-- if value === itemValue -->\n<CheckIcon size=\"${16}\" class=\"ml-auto\" />\n<!-- endif --></CommandItem>\n<!-- End Loop --></CommandGroup></CommandList></Command></PopoverContent></Popover></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-43.wxml",
          "target": "components/ui/select-43/select-43.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Timezone select with search</label><popover open=\"{{open}}\" bindchange=\"setOpen\"><popovertrigger aschild><button id=\"{{id}}\" variant=\"outline\" role=\"combobox\" aria-expanded=\"{{open}}\" class=\"bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]\"><text class=\"{{cn('truncate', !value && 'text-muted-foreground')}}\"><block wx:if=\"{{value}}\">\n{{ formattedTimezones.find((timezone) => timezone.value === value)?.label }}\n</block>\n<block wx:else>\n{{ 'Select timezone' }}\n</block></text><chevrondownicon size=\"{{16}}\" class=\"text-muted-foreground/80 shrink-0\" aria-hidden=\"true\" /></button></popovertrigger><popovercontent class=\"border-input w-full min-w-[var(--radix-popper-anchor-width)] p-0\" align=\"start\"><command filter=\"{{(value, search) => {\n              const normalizedValue = value.toLowerCase()\n              const normalizedSearch = search.toLowerCase().replace(/\\s+/g, '')\n              return normalizedValue.includes(normalizedSearch) ? 1 : 0\n            }}}\"><commandinput placeholder=\"Search timezone...\" /><commandlist><commandempty>No timezone found.</commandempty><commandgroup><commanditem wx:for=\"{{formattedTimezones}}\" wx:for-item=\"{ value: itemValue, label }\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{itemValue}}\" value=\"{{itemValue}}\" onselect=\"{{(currentValue) => {\n                      const val = currentValue as string\n                      setValue(val === value ? '' : val)\n                      setOpen(false)\n                    }}}\">{{ label }}<checkicon wx:if=\"{{value === itemValue}}\" size=\"{{16}}\" class=\"ml-auto\" /></commanditem></commandgroup></commandlist></command></popovercontent></popover></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "command",
          "combobox",
          "popover",
          "search",
          "autocomplete",
          "timezone",
          "time",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-43",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-43",
              "path": "registry/default/components/select/select-43.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-43",
              "path": "registry/default/components/select/select-43.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-43",
              "path": "registry/default/components/select/select-43.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-43",
              "path": "registry/default/components/select/select-43.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/core",
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-44",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/command.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/popover.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-44.tsx",
          "type": "registry:component",
          "target": "components/ui/select-44.tsx",
          "content": "'use client'\n\nimport { Fragment, useId, useState } from 'react'\nimport {\n  Button,\n  Command,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandItem,\n  CommandList,\n  Label,\n  Popover,\n  PopoverContent,\n  PopoverTrigger,\n} from '@timui/react'\nimport { CheckIcon, ChevronDownIcon } from 'lucide-react'\n\nconst countries = [\n  {\n    continent: 'America',\n    items: [\n      { value: 'United States', flag: '🇺🇸' },\n      { value: 'Canada', flag: '🇨🇦' },\n      { value: 'Mexico', flag: '🇲🇽' },\n    ],\n  },\n  {\n    continent: 'Africa',\n    items: [\n      { value: 'South Africa', flag: '🇿🇦' },\n      { value: 'Nigeria', flag: '🇳🇬' },\n      { value: 'Morocco', flag: '🇲🇦' },\n    ],\n  },\n  {\n    continent: 'Asia',\n    items: [\n      { value: 'China', flag: '🇨🇳' },\n      { value: 'Japan', flag: '🇯🇵' },\n      { value: 'India', flag: '🇮🇳' },\n    ],\n  },\n  {\n    continent: 'Europe',\n    items: [\n      { value: 'United Kingdom', flag: '🇬🇧' },\n      { value: 'France', flag: '🇫🇷' },\n      { value: 'Germany', flag: '🇩🇪' },\n    ],\n  },\n  {\n    continent: 'Oceania',\n    items: [\n      { value: 'Australia', flag: '🇦🇺' },\n      { value: 'New Zealand', flag: '🇳🇿' },\n    ],\n  },\n]\n\nexport default function Component() {\n  const id = useId()\n  const [open, setOpen] = useState<boolean>(false)\n  const [value, setValue] = useState<string>('')\n\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Options with flag and search</Label>\n      <Popover open={open} onOpenChange={setOpen}>\n        <PopoverTrigger asChild>\n          <Button\n            id={id}\n            variant=\"outline\"\n            role=\"combobox\"\n            aria-expanded={open}\n            className=\"bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]\"\n          >\n            {value ? (\n              <span className=\"flex min-w-0 items-center gap-2\">\n                <span className=\"text-lg leading-none\">\n                  {\n                    countries\n                      .map((group) => group.items.find((item) => item.value === value))\n                      .filter(Boolean)[0]?.flag\n                  }\n                </span>\n                <span className=\"truncate\">{value}</span>\n              </span>\n            ) : (\n              <span className=\"text-muted-foreground\">Select country</span>\n            )}\n            <ChevronDownIcon\n              size={16}\n              className=\"text-muted-foreground/80 shrink-0\"\n              aria-hidden=\"true\"\n            />\n          </Button>\n        </PopoverTrigger>\n        <PopoverContent\n          className=\"border-input w-full min-w-[var(--radix-popper-anchor-width)] p-0\"\n          align=\"start\"\n        >\n          <Command>\n            <CommandInput placeholder=\"Search country...\" />\n            <CommandList>\n              <CommandEmpty>No country found.</CommandEmpty>\n              {countries.map((group) => (\n                <Fragment key={group.continent}>\n                  <CommandGroup heading={group.continent}>\n                    {group.items.map((country) => (\n                      <CommandItem\n                        key={country.value}\n                        value={country.value}\n                        onSelect={(currentValue) => {\n                          const val = currentValue as string\n                          setValue(val === value ? '' : val)\n                          setOpen(false)\n                        }}\n                      >\n                        <span className=\"text-lg leading-none\">{country.flag}</span> {country.value}\n                        {value === country.value && <CheckIcon size={16} className=\"ml-auto\" />}\n                      </CommandItem>\n                    ))}\n                  </CommandGroup>\n                </Fragment>\n              ))}\n            </CommandList>\n          </Command>\n        </PopoverContent>\n      </Popover>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-44.vue",
          "target": "components/ui/select-44.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport { CheckIcon, ChevronDownIcon } from 'lucide-vue-next'\nimport { Button } from '@timui/vue'\nimport { Command } from '@timui/vue'\nimport { CommandEmpty } from '@timui/vue'\nimport { CommandGroup } from '@timui/vue'\nimport { CommandInput } from '@timui/vue'\nimport { CommandItem } from '@timui/vue'\nimport { CommandList } from '@timui/vue'\nimport { Label } from '@timui/vue'\nimport { Popover, PopoverContent, PopoverTrigger } from '@timui/vue'\n\nconst open = ref<boolean>(false)\nconst value = ref<string>('')\nconst id = 'select-44'\n\nconst countries = [\n  {\n    continent: 'America',\n    items: [\n      { value: 'United States', flag: '🇺🇸' },\n      { value: 'Canada', flag: '🇨🇦' },\n      { value: 'Mexico', flag: '🇲🇽' },\n    ],\n  },\n  {\n    continent: 'Africa',\n    items: [\n      { value: 'South Africa', flag: '🇿🇦' },\n      { value: 'Nigeria', flag: '🇳🇬' },\n      { value: 'Morocco', flag: '🇲🇦' },\n    ],\n  },\n  {\n    continent: 'Asia',\n    items: [\n      { value: 'China', flag: '🇨🇳' },\n      { value: 'Japan', flag: '🇯🇵' },\n      { value: 'India', flag: '🇮🇳' },\n    ],\n  },\n  {\n    continent: 'Europe',\n    items: [\n      { value: 'United Kingdom', flag: '🇬🇧' },\n      { value: 'France', flag: '🇫🇷' },\n      { value: 'Germany', flag: '🇩🇪' },\n    ],\n  },\n  {\n    continent: 'Oceania',\n    items: [\n      { value: 'Australia', flag: '🇦🇺' },\n      { value: 'New Zealand', flag: '🇳🇿' },\n    ],\n  },\n]\n\nconst selectedFlag = computed(() => {\n  return (\n    countries\n      .map((group) => group.items.find((item) => item.value === value.value))\n      .filter(Boolean)[0]?.flag ?? ''\n  )\n})\n\nconst handleSelect = (selected: string) => {\n  value.value = selected === value.value ? '' : selected\n  open.value = false\n}\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\">\n    <Label :htmlFor=\"id\">Options with flag and search</Label>\n    <Popover :open=\"open\" @update:open=\"open = $event\">\n      <PopoverTrigger as-child>\n        <Button\n          :id=\"id\"\n          variant=\"outline\"\n          role=\"combobox\"\n          :aria-expanded=\"open\"\n          class=\"bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]\"\n        >\n          <template v-if=\"value\">\n            <span class=\"flex min-w-0 items-center gap-2\">\n              <span class=\"text-lg leading-none\">{{ selectedFlag }}</span>\n              <span class=\"truncate\">{{ value }}</span>\n            </span>\n          </template>\n          <template v-else>\n            <span class=\"text-muted-foreground\">Select country</span>\n          </template>\n          <ChevronDownIcon :size=\"16\" class=\"text-muted-foreground/80 shrink-0\" aria-hidden=\"true\" />\n        </Button>\n      </PopoverTrigger>\n      <PopoverContent class=\"border-input w-full min-w-[var(--radix-popper-anchor-width)] p-0\" align=\"start\">\n        <Command>\n          <CommandInput placeholder=\"Search country...\" />\n          <CommandList>\n            <CommandEmpty>No country found.</CommandEmpty>\n            <template v-for=\"group in countries\" :key=\"group.continent\">\n              <CommandGroup :heading=\"group.continent\">\n                <CommandItem\n                  v-for=\"country in group.items\"\n                  :key=\"country.value\"\n                  :value=\"country.value\"\n                  :onSelect=\"handleSelect\"\n                >\n                  <span class=\"text-lg leading-none\">{{ country.flag }}</span> {{ country.value }}\n                  <CheckIcon v-if=\"value === country.value\" :size=\"16\" class=\"ml-auto\" />\n                </CommandItem>\n              </CommandGroup>\n            </template>\n          </CommandList>\n        </Command>\n      </PopoverContent>\n    </Popover>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-44.html",
          "target": "components/ui/select-44.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Options with flag and search</Label><Popover open=\"${open}\" on-open-change=\"${setOpen}\"><PopoverTrigger aschild><Button id=\"${id}\" variant=\"outline\" role=\"combobox\" aria-expanded=\"${open}\" class=\"bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]\"><!-- if value -->\n<span class=\"flex min-w-0 items-center gap-2\"><span class=\"text-lg leading-none\">${countries\n                      .map((group) => group.items.find((item) => item.value === value))\n                      .filter(Boolean)[0]?.flag}</span><span class=\"truncate\">${value}</span></span>\n<!-- else -->\n<span class=\"text-muted-foreground\">Select country</span>\n<!-- endif --><ChevronDownIcon size=\"${16}\" class=\"text-muted-foreground/80 shrink-0\" aria-hidden=\"true\" /></Button></PopoverTrigger><PopoverContent class=\"border-input w-full min-w-[var(--radix-popper-anchor-width)] p-0\" align=\"start\"><Command><CommandInput placeholder=\"Search country...\" /><CommandList><CommandEmpty>No country found.</CommandEmpty><!-- Loop countries -->\n<Fragment key=\"${group.continent}\"><CommandGroup heading=\"${group.continent}\"><!-- Loop group.items -->\n<CommandItem key=\"${country.value}\" value=\"${country.value}\" onselect=\"${(currentValue) => {\n                          const val = currentValue as string\n                          setValue(val === value ? '' : val)\n                          setOpen(false)\n                        }}\"><span class=\"text-lg leading-none\">${country.flag}</span>${country.value}<!-- if value === country.value -->\n<CheckIcon size=\"${16}\" class=\"ml-auto\" />\n<!-- endif --></CommandItem>\n<!-- End Loop --></CommandGroup></Fragment>\n<!-- End Loop --></CommandList></Command></PopoverContent></Popover></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-44.wxml",
          "target": "components/ui/select-44/select-44.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Options with flag and search</label><popover open=\"{{open}}\" bindchange=\"setOpen\"><popovertrigger aschild><button id=\"{{id}}\" variant=\"outline\" role=\"combobox\" aria-expanded=\"{{open}}\" class=\"bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]\"><block wx:if=\"{{value}}\">\n<text class=\"flex min-w-0 items-center gap-2\"><text class=\"text-lg leading-none\">{{ countries\n                      .map((group) => group.items.find((item) => item.value === value))\n                      .filter(Boolean)[0]?.flag }}</text><text class=\"truncate\">{{ value }}</text></text>\n</block>\n<block wx:else>\n<text class=\"text-muted-foreground\">Select country</text>\n</block><chevrondownicon size=\"{{16}}\" class=\"text-muted-foreground/80 shrink-0\" aria-hidden=\"true\" /></button></popovertrigger><popovercontent class=\"border-input w-full min-w-[var(--radix-popper-anchor-width)] p-0\" align=\"start\"><command><commandinput placeholder=\"Search country...\" /><commandlist><commandempty>No country found.</commandempty><fragment wx:for=\"{{countries}}\" wx:for-item=\"group\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{group.continent}}\"><commandgroup heading=\"{{group.continent}}\"><commanditem wx:for=\"{{group.items}}\" wx:for-item=\"country\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{country.value}}\" value=\"{{country.value}}\" onselect=\"{{(currentValue) => {\n                          const val = currentValue as string\n                          setValue(val === value ? '' : val)\n                          setOpen(false)\n                        }}}\"><text class=\"text-lg leading-none\">{{ country.flag }}</text>{{ country.value }}<checkicon wx:if=\"{{value === country.value}}\" size=\"{{16}}\" class=\"ml-auto\" /></commanditem></commandgroup></fragment></commandlist></command></popovercontent></popover></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "command",
          "combobox",
          "popover",
          "search",
          "autocomplete",
          "flag",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-44",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-44",
              "path": "registry/default/components/select/select-44.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-44",
              "path": "registry/default/components/select/select-44.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-44",
              "path": "registry/default/components/select/select-44.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-44",
              "path": "registry/default/components/select/select-44.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-45",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/command.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/popover.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-45.tsx",
          "type": "registry:component",
          "target": "components/ui/select-45.tsx",
          "content": "'use client'\n\nimport { useId, useState } from 'react'\nimport {\n  Button,\n  Command,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandItem,\n  CommandList,\n  Label,\n  Popover,\n  PopoverContent,\n  PopoverTrigger,\n} from '@timui/react'\nimport {\n  BlocksIcon,\n  BrainIcon,\n  ChevronDownIcon,\n  CpuIcon,\n  DatabaseIcon,\n  GlobeIcon,\n  LayoutIcon,\n  LineChartIcon,\n  NetworkIcon,\n  SearchIcon,\n  ServerIcon,\n} from 'lucide-react'\n\nconst items = [\n  {\n    value: 'analytics platform',\n    label: 'Analytics Platform',\n    icon: LineChartIcon,\n    number: 2451,\n  },\n  {\n    value: 'ai services',\n    label: 'AI Services',\n    icon: BrainIcon,\n    number: 1832,\n  },\n  {\n    value: 'database systems',\n    label: 'Database Systems',\n    icon: DatabaseIcon,\n    number: 1654,\n  },\n  {\n    value: 'compute resources',\n    label: 'Compute Resources',\n    icon: CpuIcon,\n    number: 943,\n  },\n  {\n    value: 'network services',\n    label: 'Network Services',\n    icon: NetworkIcon,\n    number: 832,\n  },\n  {\n    value: 'web services',\n    label: 'Web Services',\n    icon: GlobeIcon,\n    number: 654,\n  },\n  {\n    value: 'monitoring tools',\n    label: 'Monitoring Tools',\n    icon: SearchIcon,\n    number: 432,\n  },\n  {\n    value: 'server management',\n    label: 'Server Management',\n    icon: ServerIcon,\n    number: 321,\n  },\n  {\n    value: 'infrastructure',\n    label: 'Infrastructure',\n    icon: BlocksIcon,\n    number: 234,\n  },\n  {\n    value: 'frontend services',\n    label: 'Frontend Services',\n    icon: LayoutIcon,\n    number: 123,\n  },\n]\n\nexport default function Component() {\n  const id = useId()\n  const [open, setOpen] = useState<boolean>(false)\n  const [value, setValue] = useState<string>('')\n\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Options with icon and number</Label>\n      <Popover open={open} onOpenChange={setOpen}>\n        <PopoverTrigger asChild>\n          <Button\n            id={id}\n            variant=\"outline\"\n            role=\"combobox\"\n            aria-expanded={open}\n            className=\"bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]\"\n          >\n            {value ? (\n              <span className=\"flex min-w-0 items-center gap-2\">\n                {(() => {\n                  const selectedItem = items.find((item) => item.value === value)\n                  if (selectedItem) {\n                    const Icon = selectedItem.icon\n                    return <Icon className=\"text-muted-foreground size-4\" />\n                  }\n                  return null\n                })()}\n                <span className=\"truncate\">\n                  {items.find((item) => item.value === value)?.label}\n                </span>\n              </span>\n            ) : (\n              <span className=\"text-muted-foreground\">Select service category</span>\n            )}\n            <ChevronDownIcon\n              size={16}\n              className=\"text-muted-foreground/80 shrink-0\"\n              aria-hidden=\"true\"\n            />\n          </Button>\n        </PopoverTrigger>\n        <PopoverContent\n          className=\"border-input w-full min-w-[var(--radix-popper-anchor-width)] p-0\"\n          align=\"start\"\n        >\n          <Command>\n            <CommandInput placeholder=\"Search services...\" />\n            <CommandList>\n              <CommandEmpty>No service found.</CommandEmpty>\n              <CommandGroup>\n                {items.map((item) => (\n                  <CommandItem\n                    key={item.value}\n                    value={item.value}\n                    onSelect={(currentValue) => {\n                      const val = currentValue as string\n                      setValue(val === value ? '' : val)\n                      setOpen(false)\n                    }}\n                    className=\"flex items-center justify-between\"\n                  >\n                    <div className=\"flex items-center gap-2\">\n                      <item.icon className=\"text-muted-foreground size-4\" />\n                      {item.label}\n                    </div>\n                    <span className=\"text-muted-foreground text-xs\">\n                      {item.number.toLocaleString()}\n                    </span>\n                  </CommandItem>\n                ))}\n              </CommandGroup>\n            </CommandList>\n          </Command>\n        </PopoverContent>\n      </Popover>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-45.vue",
          "target": "components/ui/select-45.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport {\n  BlocksIcon,\n  BrainIcon,\n  ChevronDownIcon,\n  CpuIcon,\n  DatabaseIcon,\n  GlobeIcon,\n  LayoutIcon,\n  LineChartIcon,\n  NetworkIcon,\n  SearchIcon,\n  ServerIcon,\n} from 'lucide-vue-next'\nimport { Button } from '@timui/vue'\nimport { Command } from '@timui/vue'\nimport { CommandEmpty } from '@timui/vue'\nimport { CommandGroup } from '@timui/vue'\nimport { CommandInput } from '@timui/vue'\nimport { CommandItem } from '@timui/vue'\nimport { CommandList } from '@timui/vue'\nimport { Label } from '@timui/vue'\nimport { Popover, PopoverContent, PopoverTrigger } from '@timui/vue'\n\nconst items = [\n  { value: 'analytics platform', label: 'Analytics Platform', icon: LineChartIcon, number: 2451 },\n  { value: 'ai services', label: 'AI Services', icon: BrainIcon, number: 1832 },\n  { value: 'database systems', label: 'Database Systems', icon: DatabaseIcon, number: 1654 },\n  { value: 'compute resources', label: 'Compute Resources', icon: CpuIcon, number: 943 },\n  { value: 'network services', label: 'Network Services', icon: NetworkIcon, number: 832 },\n  { value: 'web services', label: 'Web Services', icon: GlobeIcon, number: 654 },\n  { value: 'monitoring tools', label: 'Monitoring Tools', icon: SearchIcon, number: 432 },\n  { value: 'server management', label: 'Server Management', icon: ServerIcon, number: 321 },\n  { value: 'infrastructure', label: 'Infrastructure', icon: BlocksIcon, number: 234 },\n  { value: 'frontend services', label: 'Frontend Services', icon: LayoutIcon, number: 123 },\n]\n\nconst id = 'select-45'\nconst open = ref(false)\nconst value = ref('')\n\nconst selectedItem = computed(() => items.find((item) => item.value === value.value))\n\nconst onSelect = (nextValue: string) => {\n  value.value = nextValue === value.value ? '' : nextValue\n  open.value = false\n}\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\">\n    <Label :htmlFor=\"id\">Options with icon and number</Label>\n\n    <Popover v-model:open=\"open\">\n      <PopoverTrigger as-child>\n        <Button\n          :id=\"id\"\n          variant=\"outline\"\n          role=\"combobox\"\n          :aria-expanded=\"open\"\n          class=\"bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]\"\n        >\n          <span v-if=\"selectedItem\" class=\"flex min-w-0 items-center gap-2\">\n            <component :is=\"selectedItem.icon\" class=\"text-muted-foreground size-4\" />\n            <span class=\"truncate\">{{ selectedItem.label }}</span>\n          </span>\n          <span v-else class=\"text-muted-foreground\">Select service category</span>\n\n          <ChevronDownIcon :size=\"16\" class=\"text-muted-foreground/80 shrink-0\" aria-hidden=\"true\" />\n        </Button>\n      </PopoverTrigger>\n\n      <PopoverContent class=\"border-input w-full min-w-[var(--radix-popper-anchor-width)] p-0\" align=\"start\">\n        <Command>\n          <CommandInput placeholder=\"Search services...\" />\n          <CommandList>\n            <CommandEmpty>No service found.</CommandEmpty>\n            <CommandGroup>\n              <CommandItem\n                v-for=\"item in items\"\n                :key=\"item.value\"\n                :value=\"item.value\"\n                class=\"flex items-center justify-between\"\n                @click=\"onSelect(item.value)\"\n              >\n                <div class=\"flex items-center gap-2\">\n                  <component :is=\"item.icon\" class=\"text-muted-foreground size-4\" />\n                  {{ item.label }}\n                </div>\n                <span class=\"text-muted-foreground text-xs\">{{ item.number.toLocaleString() }}</span>\n              </CommandItem>\n            </CommandGroup>\n          </CommandList>\n        </Command>\n      </PopoverContent>\n    </Popover>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-45.html",
          "target": "components/ui/select-45.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Options with icon and number</Label><Popover open=\"${open}\" on-open-change=\"${setOpen}\"><PopoverTrigger aschild><Button id=\"${id}\" variant=\"outline\" role=\"combobox\" aria-expanded=\"${open}\" class=\"bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]\"><!-- if value -->\n<span class=\"flex min-w-0 items-center gap-2\">${(() => {\n                  const selectedItem = items.find((item) => item.value === value)\n                  if (selectedItem) {\n                    const Icon = selectedItem.icon\n                    return <Icon className=\"text-muted-foreground size-4\" />\n                  }\n                  return null\n                })()}<span class=\"truncate\">${items.find((item) => item.value === value)?.label}</span></span>\n<!-- else -->\n<span class=\"text-muted-foreground\">Select service category</span>\n<!-- endif --><ChevronDownIcon size=\"${16}\" class=\"text-muted-foreground/80 shrink-0\" aria-hidden=\"true\" /></Button></PopoverTrigger><PopoverContent class=\"border-input w-full min-w-[var(--radix-popper-anchor-width)] p-0\" align=\"start\"><Command><CommandInput placeholder=\"Search services...\" /><CommandList><CommandEmpty>No service found.</CommandEmpty><CommandGroup><!-- Loop items -->\n<CommandItem key=\"${item.value}\" value=\"${item.value}\" onselect=\"${(currentValue) => {\n                      const val = currentValue as string\n                      setValue(val === value ? '' : val)\n                      setOpen(false)\n                    }}\" class=\"flex items-center justify-between\"><div class=\"flex items-center gap-2\"><item.icon class=\"text-muted-foreground size-4\" />${item.label}</div><span class=\"text-muted-foreground text-xs\">${item.number.toLocaleString()}</span></CommandItem>\n<!-- End Loop --></CommandGroup></CommandList></Command></PopoverContent></Popover></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-45.wxml",
          "target": "components/ui/select-45/select-45.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Options with icon and number</label><popover open=\"{{open}}\" bindchange=\"setOpen\"><popovertrigger aschild><button id=\"{{id}}\" variant=\"outline\" role=\"combobox\" aria-expanded=\"{{open}}\" class=\"bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]\"><block wx:if=\"{{value}}\">\n<text class=\"flex min-w-0 items-center gap-2\">{{ (() => {\n                  const selectedItem = items.find((item) => item.value === value)\n                  if (selectedItem) {\n                    const Icon = selectedItem.icon\n                    return <Icon className=\"text-muted-foreground size-4\" />\n                  }\n                  return null\n                })() }}<text class=\"truncate\">{{ items.find((item) => item.value === value)?.label }}</text></text>\n</block>\n<block wx:else>\n<text class=\"text-muted-foreground\">Select service category</text>\n</block><chevrondownicon size=\"{{16}}\" class=\"text-muted-foreground/80 shrink-0\" aria-hidden=\"true\" /></button></popovertrigger><popovercontent class=\"border-input w-full min-w-[var(--radix-popper-anchor-width)] p-0\" align=\"start\"><command><commandinput placeholder=\"Search services...\" /><commandlist><commandempty>No service found.</commandempty><commandgroup><commanditem wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{item.value}}\" value=\"{{item.value}}\" onselect=\"{{(currentValue) => {\n                      const val = currentValue as string\n                      setValue(val === value ? '' : val)\n                      setOpen(false)\n                    }}}\" class=\"flex items-center justify-between\"><view class=\"flex items-center gap-2\"><item.icon class=\"text-muted-foreground size-4\" />{{ item.label }}</view><text class=\"text-muted-foreground text-xs\">{{ item.number.toLocaleString() }}</text></commanditem></commandgroup></commandlist></command></popovercontent></popover></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "command",
          "combobox",
          "popover",
          "search",
          "autocomplete",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-45",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-45",
              "path": "registry/default/components/select/select-45.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-45",
              "path": "registry/default/components/select/select-45.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-45",
              "path": "registry/default/components/select/select-45.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-45",
              "path": "registry/default/components/select/select-45.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-46",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/multiselect.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-46.tsx",
          "type": "registry:component",
          "target": "components/ui/select-46.tsx",
          "content": "import { useId } from 'react'\nimport { Label, MultipleSelector, Option } from '@timui/react'\n\nconst frameworks: Option[] = [\n  {\n    value: 'next.js',\n    label: 'Next.js',\n  },\n  {\n    value: 'sveltekit',\n    label: 'SvelteKit',\n  },\n  {\n    value: 'nuxt.js',\n    label: 'Nuxt.js',\n    disable: true,\n  },\n  {\n    value: 'remix',\n    label: 'Remix',\n  },\n  {\n    value: 'astro',\n    label: 'Astro',\n  },\n  {\n    value: 'angular',\n    label: 'Angular',\n  },\n  {\n    value: 'vue',\n    label: 'Vue.js',\n  },\n  {\n    value: 'react',\n    label: 'React',\n  },\n  {\n    value: 'ember',\n    label: 'Ember.js',\n  },\n  {\n    value: 'gatsby',\n    label: 'Gatsby',\n  },\n  {\n    value: 'eleventy',\n    label: 'Eleventy',\n    disable: true,\n  },\n  {\n    value: 'solid',\n    label: 'SolidJS',\n  },\n  {\n    value: 'preact',\n    label: 'Preact',\n  },\n  {\n    value: 'qwik',\n    label: 'Qwik',\n  },\n  {\n    value: 'alpine',\n    label: 'Alpine.js',\n  },\n  {\n    value: 'lit',\n    label: 'Lit',\n  },\n]\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label>Multiselect</Label>\n      <MultipleSelector\n        commandProps={{\n          label: 'Select frameworks',\n        }}\n        value={frameworks.slice(0, 2)}\n        defaultOptions={frameworks}\n        placeholder=\"Select frameworks\"\n        hideClearAllButton\n        hidePlaceholderWhenSelected\n        emptyIndicator={<p className=\"text-center text-sm\">No results found</p>}\n      />\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Inspired by{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://shadcnui-expansions.typeart.cc/docs/multiple-selector\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          shadcn/ui expansions\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-46.vue",
          "target": "components/ui/select-46.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue'\nimport { MultipleSelector } from '@timui/vue'\n\nconst frameworks = [\n  { value: 'next.js', label: 'Next.js' },\n  { value: 'sveltekit', label: 'SvelteKit' },\n  { value: 'nuxt.js', label: 'Nuxt.js', disable: true },\n  { value: 'remix', label: 'Remix' },\n  { value: 'astro', label: 'Astro' },\n  { value: 'angular', label: 'Angular' },\n  { value: 'vue', label: 'Vue.js' },\n  { value: 'react', label: 'React' },\n  { value: 'ember', label: 'Ember.js' },\n  { value: 'gatsby', label: 'Gatsby' },\n  { value: 'eleventy', label: 'Eleventy', disable: true },\n  { value: 'solid', label: 'SolidJS' },\n  { value: 'preact', label: 'Preact' },\n  { value: 'qwik', label: 'Qwik' },\n  { value: 'alpine', label: 'Alpine.js' },\n  { value: 'lit', label: 'Lit' },\n]\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\">\n    <Label>Multiselect</Label>\n    <MultipleSelector\n      :command-props=\"{ label: 'Select frameworks' }\"\n      :value=\"frameworks.slice(0, 2)\"\n      :default-options=\"frameworks\"\n      placeholder=\"Select frameworks\"\n      hide-clear-all-button\n      hide-placeholder-when-selected\n      empty-indicator=\"No results found\"\n    />\n    <p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n      Inspired by\n      <a\n        class=\"hover:text-foreground underline\"\n        href=\"https://shadcnui-expansions.typeart.cc/docs/multiple-selector\"\n        target=\"_blank\"\n        rel=\"noopener nofollow\"\n      >\n        shadcn/ui expansions\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-46.html",
          "target": "components/ui/select-46.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label>Multiselect</Label><MultipleSelector commandprops=\"${{\n          label: 'Select frameworks',\n        }}\" value=\"${frameworks.slice(0, 2)}\" defaultoptions=\"${frameworks}\" placeholder=\"Select frameworks\" hideclearallbutton hideplaceholderwhenselected emptyindicator=\"${<p className=\"text-center text-sm\">No results found</p>}\" /><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Inspired by${' '}<a class=\"hover:text-foreground underline\" href=\"https://shadcnui-expansions.typeart.cc/docs/multiple-selector\" target=\"_blank\" rel=\"noopener nofollow\">shadcn/ui expansions\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-46.wxml",
          "target": "components/ui/select-46/select-46.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label>Multiselect</label><multipleselector commandprops=\"{{{\n          label: 'Select frameworks',\n        }}}\" value=\"{{frameworks.slice(0, 2)}}\" defaultoptions=\"{{frameworks}}\" placeholder=\"Select frameworks\" hideclearallbutton hideplaceholderwhenselected emptyindicator=\"{{<p className=\"text-center text-sm\">No results found</p>}}\" /><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Inspired by{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://shadcnui-expansions.typeart.cc/docs/multiple-selector\" target=\"_blank\" rel=\"noopener nofollow\">shadcn/ui expansions\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "multiselect",
          "tag",
          "input",
          "search",
          "autocomplete",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-46",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-46",
              "path": "registry/default/components/select/select-46.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-46",
              "path": "registry/default/components/select/select-46.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-46",
              "path": "registry/default/components/select/select-46.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-46",
              "path": "registry/default/components/select/select-46.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-47",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/multiselect.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-47.tsx",
          "type": "registry:component",
          "target": "components/ui/select-47.tsx",
          "content": "import { Label, MultipleSelector, Option } from '@timui/react'\n\nconst frameworks: Option[] = [\n  {\n    value: 'next.js',\n    label: 'Next.js',\n  },\n  {\n    value: 'sveltekit',\n    label: 'SvelteKit',\n  },\n  {\n    value: 'nuxt.js',\n    label: 'Nuxt.js',\n  },\n  {\n    value: 'remix',\n    label: 'Remix',\n  },\n  {\n    value: 'astro',\n    label: 'Astro',\n  },\n  {\n    value: 'angular',\n    label: 'Angular',\n  },\n  {\n    value: 'vue',\n    label: 'Vue.js',\n  },\n  {\n    value: 'react',\n    label: 'React',\n  },\n  {\n    value: 'ember',\n    label: 'Ember.js',\n  },\n  {\n    value: 'gatsby',\n    label: 'Gatsby',\n  },\n  {\n    value: 'eleventy',\n    label: 'Eleventy',\n  },\n  {\n    value: 'solid',\n    label: 'SolidJS',\n  },\n  {\n    value: 'preact',\n    label: 'Preact',\n  },\n  {\n    value: 'qwik',\n    label: 'Qwik',\n  },\n  {\n    value: 'alpine',\n    label: 'Alpine.js',\n  },\n  {\n    value: 'lit',\n    label: 'Lit',\n  },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label>Multiselect with placeholder and clear</Label>\n      <MultipleSelector\n        commandProps={{\n          label: 'Select frameworks',\n        }}\n        defaultOptions={frameworks}\n        placeholder=\"Select frameworks\"\n        emptyIndicator={<p className=\"text-center text-sm\">No results found</p>}\n      />\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Inspired by{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://shadcnui-expansions.typeart.cc/docs/multiple-selector\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          shadcn/ui expansions\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-47.vue",
          "target": "components/ui/select-47.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue'\nimport { MultipleSelector } from '@timui/vue'\n\nconst frameworks = [\n  { value: 'next.js', label: 'Next.js' },\n  { value: 'sveltekit', label: 'SvelteKit' },\n  { value: 'nuxt.js', label: 'Nuxt.js' },\n  { value: 'remix', label: 'Remix' },\n  { value: 'astro', label: 'Astro' },\n  { value: 'angular', label: 'Angular' },\n  { value: 'vue', label: 'Vue.js' },\n  { value: 'react', label: 'React' },\n  { value: 'ember', label: 'Ember.js' },\n  { value: 'gatsby', label: 'Gatsby' },\n  { value: 'eleventy', label: 'Eleventy' },\n  { value: 'solid', label: 'SolidJS' },\n  { value: 'preact', label: 'Preact' },\n  { value: 'qwik', label: 'Qwik' },\n  { value: 'alpine', label: 'Alpine.js' },\n  { value: 'lit', label: 'Lit' },\n]\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\">\n    <Label>Multiselect with placeholder and clear</Label>\n    <MultipleSelector\n      :command-props=\"{ label: 'Select frameworks' }\"\n      :default-options=\"frameworks\"\n      placeholder=\"Select frameworks\"\n      empty-indicator=\"No results found\"\n    />\n    <p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n      Inspired by\n      <a\n        class=\"hover:text-foreground underline\"\n        href=\"https://shadcnui-expansions.typeart.cc/docs/multiple-selector\"\n        target=\"_blank\"\n        rel=\"noopener nofollow\"\n      >\n        shadcn/ui expansions\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-47.html",
          "target": "components/ui/select-47.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label>Multiselect with placeholder and clear</Label><MultipleSelector commandprops=\"${{\n          label: 'Select frameworks',\n        }}\" defaultoptions=\"${frameworks}\" placeholder=\"Select frameworks\" emptyindicator=\"${<p className=\"text-center text-sm\">No results found</p>}\" /><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Inspired by${' '}<a class=\"hover:text-foreground underline\" href=\"https://shadcnui-expansions.typeart.cc/docs/multiple-selector\" target=\"_blank\" rel=\"noopener nofollow\">shadcn/ui expansions\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-47.wxml",
          "target": "components/ui/select-47/select-47.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label>Multiselect with placeholder and clear</label><multipleselector commandprops=\"{{{\n          label: 'Select frameworks',\n        }}}\" defaultoptions=\"{{frameworks}}\" placeholder=\"Select frameworks\" emptyindicator=\"{{<p className=\"text-center text-sm\">No results found</p>}}\" /><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Inspired by{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://shadcnui-expansions.typeart.cc/docs/multiple-selector\" target=\"_blank\" rel=\"noopener nofollow\">shadcn/ui expansions\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "multiselect",
          "tag",
          "input",
          "search",
          "autocomplete",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-47",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-47",
              "path": "registry/default/components/select/select-47.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-47",
              "path": "registry/default/components/select/select-47.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-47",
              "path": "registry/default/components/select/select-47.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-47",
              "path": "registry/default/components/select/select-47.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-48",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/select-native.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-48.tsx",
          "type": "registry:component",
          "target": "components/ui/select-48.tsx",
          "content": "import { useId } from 'react'\nimport { Label, SelectNative } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Multiple select (native)</Label>\n      <div className=\"border-input overflow-hidden rounded-md border\">\n        <SelectNative id={id} multiple className=\"rounded-none border-none\">\n          <option value=\"1\">React</option>\n          <option value=\"2\">Next.js</option>\n          <option value=\"3\">Astro</option>\n          <option value=\"4\">Gatsby</option>\n          <option value=\"5\">Vue</option>\n          <option value=\"6\">Angular</option>\n        </SelectNative>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-48.vue",
          "target": "components/ui/select-48.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { SelectNative } from '@timui/vue';\n\n\n\n\n\nconst id = 'select-48';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Multiple select (native)</Label><div class=\"border-input overflow-hidden rounded-md border\"><SelectNative :id=\"id\" multiple class=\"rounded-none border-none\"><option value=\"1\">React</option><option value=\"2\">Next.js</option><option value=\"3\">Astro</option><option value=\"4\">Gatsby</option><option value=\"5\">Vue</option><option value=\"6\">Angular</option></SelectNative></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-48.html",
          "target": "components/ui/select-48.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Multiple select (native)</Label><div class=\"border-input overflow-hidden rounded-md border\"><SelectNative id=\"${id}\" multiple class=\"rounded-none border-none\"><option value=\"1\">React</option><option value=\"2\">Next.js</option><option value=\"3\">Astro</option><option value=\"4\">Gatsby</option><option value=\"5\">Vue</option><option value=\"6\">Angular</option></SelectNative></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-48.wxml",
          "target": "components/ui/select-48/select-48.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Multiple select (native)</label><view class=\"border-input overflow-hidden rounded-md border\"><selectnative id=\"{{id}}\" multiple class=\"rounded-none border-none\"><option value=\"1\">React</option><option value=\"2\">Next.js</option><option value=\"3\">Astro</option><option value=\"4\">Gatsby</option><option value=\"5\">Vue</option><option value=\"6\">Angular</option></selectnative></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "multiselect",
          "native select"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-48",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-48",
              "path": "registry/default/components/select/select-48.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-48",
              "path": "registry/default/components/select/select-48.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-48",
              "path": "registry/default/components/select/select-48.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-48",
              "path": "registry/default/components/select/select-48.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-49",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-49.tsx",
          "type": "registry:component",
          "target": "components/ui/select-49.tsx",
          "content": "'use client'\n\nimport { Label, ListBox, ListBoxItem } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label>Listbox with single option</Label>\n      <div className=\"border-input overflow-hidden rounded-md border\">\n        <ListBox\n          className=\"bg-background space-y-1 p-1 text-sm shadow-xs transition-[color,box-shadow]\"\n          aria-label=\"Select framework\"\n          selectionMode=\"single\"\n          defaultSelectedKeys={['svelte']}\n        >\n          <ListBoxItem\n            id=\"react\"\n            className=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n          >\n            React\n          </ListBoxItem>\n          <ListBoxItem\n            id=\"vue\"\n            className=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n          >\n            Vue\n          </ListBoxItem>\n          <ListBoxItem\n            id=\"angular\"\n            className=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n            isDisabled\n          >\n            Angular\n          </ListBoxItem>\n          <ListBoxItem\n            id=\"svelte\"\n            className=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n          >\n            Svelte\n          </ListBoxItem>\n        </ListBox>\n      </div>\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Built with{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://zagjs.com/\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          Zag.js\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-49.vue",
          "target": "components/ui/select-49.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue'\nimport { ListBox } from '@timui/vue'\nimport { ListBoxItem } from '@timui/vue'\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\">\n    <Label>Listbox with single option</Label>\n    <div class=\"border-input overflow-hidden rounded-md border\">\n      <ListBox\n        class=\"bg-background space-y-1 p-1 text-sm shadow-xs transition-[color,box-shadow]\"\n        aria-label=\"Select framework\"\n        selectionMode=\"single\"\n        defaultValue=\"svelte\"\n      >\n        <ListBoxItem\n          id=\"react\"\n          class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n        >\n          React\n        </ListBoxItem>\n        <ListBoxItem\n          id=\"vue\"\n          class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n        >\n          Vue\n        </ListBoxItem>\n        <ListBoxItem\n          id=\"angular\"\n          :isDisabled=\"true\"\n          class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n        >\n          Angular\n        </ListBoxItem>\n        <ListBoxItem\n          id=\"svelte\"\n          class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n        >\n          Svelte\n        </ListBoxItem>\n      </ListBox>\n    </div>\n    <p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n      Built with\n      <a\n        class=\"hover:text-foreground underline\"\n        href=\"https://zagjs.com/\"\n        target=\"_blank\"\n        rel=\"noopener nofollow\"\n      >\n        Zag.js\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-49.html",
          "target": "components/ui/select-49.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label>Listbox with single option</Label><div class=\"border-input overflow-hidden rounded-md border\"><ListBox class=\"bg-background space-y-1 p-1 text-sm shadow-xs transition-[color,box-shadow]\" aria-label=\"Select framework\" selectionmode=\"single\" defaultselectedkeys=\"${['svelte']}\"><ListBoxItem id=\"react\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\">React\n          </ListBoxItem><ListBoxItem id=\"vue\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\">Vue\n          </ListBoxItem><ListBoxItem id=\"angular\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\" isdisabled>Angular\n          </ListBoxItem><ListBoxItem id=\"svelte\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\">Svelte\n          </ListBoxItem></ListBox></div><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with${' '}<a class=\"hover:text-foreground underline\" href=\"https://react-spectrum.adobe.com/react-aria/ListBox.html\" target=\"_blank\" rel=\"noopener nofollow\">React Aria\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-49.wxml",
          "target": "components/ui/select-49/select-49.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label>Listbox with single option</label><view class=\"border-input overflow-hidden rounded-md border\"><listbox class=\"bg-background space-y-1 p-1 text-sm shadow-xs transition-[color,box-shadow]\" aria-label=\"Select framework\" selectionmode=\"single\" defaultselectedkeys=\"{{['svelte']}}\"><listboxitem id=\"react\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\">React\n          </listboxitem><listboxitem id=\"vue\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\">Vue\n          </listboxitem><listboxitem id=\"angular\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\" isdisabled>Angular\n          </listboxitem><listboxitem id=\"svelte\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\">Svelte\n          </listboxitem></listbox></view><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://react-spectrum.adobe.com/react-aria/ListBox.html\" target=\"_blank\" rel=\"noopener nofollow\">React Aria\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "multiselect",
          "react aria"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-49",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-49",
              "path": "registry/default/components/select/select-49.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-49",
              "path": "registry/default/components/select/select-49.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-49",
              "path": "registry/default/components/select/select-49.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-49",
              "path": "registry/default/components/select/select-49.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-50",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-50.tsx",
          "type": "registry:component",
          "target": "components/ui/select-50.tsx",
          "content": "'use client'\n\nimport { Label, ListBox, ListBoxItem } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label>Listbox with multiple options</Label>\n      <div className=\"border-input overflow-hidden rounded-md border\">\n        <ListBox\n          className=\"bg-background max-h-72 min-h-20 space-y-1 overflow-auto p-1 text-sm shadow-xs transition-[color,box-shadow]\"\n          aria-label=\"Select framework\"\n          selectionMode=\"multiple\"\n          defaultSelectedKeys={['react', 'vue']}\n        >\n          <ListBoxItem\n            id=\"react\"\n            className=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n          >\n            React\n          </ListBoxItem>\n          <ListBoxItem\n            id=\"vue\"\n            className=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n          >\n            Vue\n          </ListBoxItem>\n          <ListBoxItem\n            id=\"angular\"\n            className=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n          >\n            Angular\n          </ListBoxItem>\n          <ListBoxItem\n            id=\"svelte\"\n            className=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n          >\n            Svelte\n          </ListBoxItem>\n        </ListBox>\n      </div>\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Built with{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://zagjs.com/\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          Zag.js\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-50.vue",
          "target": "components/ui/select-50.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue'\nimport { ListBox } from '@timui/vue'\nimport { ListBoxItem } from '@timui/vue'\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\">\n    <Label>Listbox with multiple options</Label>\n    <div class=\"border-input overflow-hidden rounded-md border\">\n      <ListBox\n        class=\"bg-background max-h-72 min-h-20 space-y-1 overflow-auto p-1 text-sm shadow-xs transition-[color,box-shadow]\"\n        aria-label=\"Select framework\"\n        selectionMode=\"multiple\"\n        :defaultValue=\"['react', 'vue']\"\n      >\n        <ListBoxItem\n          id=\"react\"\n          class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n        >\n          React\n        </ListBoxItem>\n        <ListBoxItem\n          id=\"vue\"\n          class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n        >\n          Vue\n        </ListBoxItem>\n        <ListBoxItem\n          id=\"angular\"\n          class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n        >\n          Angular\n        </ListBoxItem>\n        <ListBoxItem\n          id=\"svelte\"\n          class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n        >\n          Svelte\n        </ListBoxItem>\n      </ListBox>\n    </div>\n    <p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n      Built with\n      <a\n        class=\"hover:text-foreground underline\"\n        href=\"https://zagjs.com/\"\n        target=\"_blank\"\n        rel=\"noopener nofollow\"\n      >\n        Zag.js\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-50.html",
          "target": "components/ui/select-50.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label>Listbox with multiple options</Label><div class=\"border-input overflow-hidden rounded-md border\"><ListBox class=\"bg-background max-h-72 min-h-20 space-y-1 overflow-auto p-1 text-sm shadow-xs transition-[color,box-shadow]\" aria-label=\"Select framework\" selectionmode=\"multiple\" defaultselectedkeys=\"${['react', 'vue']}\"><ListBoxItem id=\"react\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\">React\n          </ListBoxItem><ListBoxItem id=\"vue\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\">Vue\n          </ListBoxItem><ListBoxItem id=\"angular\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\">Angular\n          </ListBoxItem><ListBoxItem id=\"svelte\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\">Svelte\n          </ListBoxItem></ListBox></div><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with${' '}<a class=\"hover:text-foreground underline\" href=\"https://react-spectrum.adobe.com/react-aria/ListBox.html\" target=\"_blank\" rel=\"noopener nofollow\">React Aria\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-50.wxml",
          "target": "components/ui/select-50/select-50.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label>Listbox with multiple options</label><view class=\"border-input overflow-hidden rounded-md border\"><listbox class=\"bg-background max-h-72 min-h-20 space-y-1 overflow-auto p-1 text-sm shadow-xs transition-[color,box-shadow]\" aria-label=\"Select framework\" selectionmode=\"multiple\" defaultselectedkeys=\"{{['react', 'vue']}}\"><listboxitem id=\"react\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\">React\n          </listboxitem><listboxitem id=\"vue\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\">Vue\n          </listboxitem><listboxitem id=\"angular\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\">Angular\n          </listboxitem><listboxitem id=\"svelte\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\">Svelte\n          </listboxitem></listbox></view><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://react-spectrum.adobe.com/react-aria/ListBox.html\" target=\"_blank\" rel=\"noopener nofollow\">React Aria\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "multiselect",
          "react aria"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-50",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-50",
              "path": "registry/default/components/select/select-50.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-50",
              "path": "registry/default/components/select/select-50.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-50",
              "path": "registry/default/components/select/select-50.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-50",
              "path": "registry/default/components/select/select-50.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "select-51",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/select/select-51.tsx",
          "type": "registry:component",
          "target": "components/ui/select-51.tsx",
          "content": "'use client'\n\nimport { Header, Label, ListBox, ListBoxItem, ListBoxSection, Separator } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label>Listbox with option groups</Label>\n      <div className=\"border-input overflow-hidden rounded-md border\">\n        <ListBox\n          className=\"bg-background max-h-72 min-h-20 space-y-2 overflow-auto p-1 text-sm shadow-xs transition-[color,box-shadow]\"\n          aria-label=\"Select some foods\"\n          selectionMode=\"multiple\"\n          defaultSelectedKeys={['lettuce', 'tuna']}\n        >\n          <ListBoxSection className=\"space-y-1\">\n            <Header className=\"text-muted-foreground px-2 py-1.5 text-xs font-medium\">\n              Veggies\n            </Header>\n            <ListBoxItem\n              id=\"lettuce\"\n              className=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n            >\n              Lettuce\n            </ListBoxItem>\n            <ListBoxItem\n              id=\"tomato\"\n              className=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n            >\n              Tomato\n            </ListBoxItem>\n            <ListBoxItem\n              id=\"onion\"\n              className=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n            >\n              Onion\n            </ListBoxItem>\n          </ListBoxSection>\n          <Separator className=\"bg-border -mx-1 my-2 h-px\" />\n          <ListBoxSection className=\"space-y-1\">\n            <Header className=\"text-muted-foreground px-2 py-1.5 text-xs font-medium\">\n              Protein\n            </Header>\n            <ListBoxItem\n              id=\"ham\"\n              className=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n            >\n              Ham\n            </ListBoxItem>\n            <ListBoxItem\n              id=\"tuna\"\n              className=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n            >\n              Tuna\n            </ListBoxItem>\n            <ListBoxItem\n              id=\"tofu\"\n              className=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n            >\n              Tofu\n            </ListBoxItem>\n          </ListBoxSection>\n          <Separator className=\"bg-border -mx-1 my-2 h-px\" />\n          <ListBoxSection className=\"space-y-1\">\n            <Header className=\"text-muted-foreground px-2 py-1.5 text-xs font-medium\">\n              Condiments\n            </Header>\n            <ListBoxItem\n              id=\"mayo\"\n              className=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n            >\n              Mayonaise\n            </ListBoxItem>\n            <ListBoxItem\n              id=\"mustard\"\n              className=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n            >\n              Mustard\n            </ListBoxItem>\n            <ListBoxItem\n              id=\"ranch\"\n              className=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n            >\n              Ranch\n            </ListBoxItem>\n          </ListBoxSection>\n        </ListBox>\n      </div>\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Built with{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://zagjs.com/\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          Zag.js\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/select/select-51.vue",
          "target": "components/ui/select-51.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Header } from '@timui/vue'\nimport { Label } from '@timui/vue'\nimport { ListBox } from '@timui/vue'\nimport { ListBoxItem } from '@timui/vue'\nimport { ListBoxSection } from '@timui/vue'\nimport { Separator } from '@timui/vue'\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\">\n    <Label>Listbox with option groups</Label>\n    <div class=\"border-input overflow-hidden rounded-md border\">\n      <ListBox\n        class=\"bg-background max-h-72 min-h-20 space-y-2 overflow-auto p-1 text-sm shadow-xs transition-[color,box-shadow]\"\n        aria-label=\"Select some foods\"\n        selectionMode=\"multiple\"\n        :defaultValue=\"['lettuce', 'tuna']\"\n      >\n        <ListBoxSection class=\"space-y-1\">\n          <Header class=\"text-muted-foreground px-2 py-1.5 text-xs font-medium\">Veggies</Header>\n          <ListBoxItem\n            id=\"lettuce\"\n            class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n          >\n            Lettuce\n          </ListBoxItem>\n          <ListBoxItem\n            id=\"tomato\"\n            class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n          >\n            Tomato\n          </ListBoxItem>\n          <ListBoxItem\n            id=\"onion\"\n            class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n          >\n            Onion\n          </ListBoxItem>\n        </ListBoxSection>\n\n        <Separator class=\"bg-border -mx-1 my-2 h-px\" />\n\n        <ListBoxSection class=\"space-y-1\">\n          <Header class=\"text-muted-foreground px-2 py-1.5 text-xs font-medium\">Protein</Header>\n          <ListBoxItem\n            id=\"ham\"\n            class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n          >\n            Ham\n          </ListBoxItem>\n          <ListBoxItem\n            id=\"tuna\"\n            class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n          >\n            Tuna\n          </ListBoxItem>\n          <ListBoxItem\n            id=\"tofu\"\n            class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n          >\n            Tofu\n          </ListBoxItem>\n        </ListBoxSection>\n\n        <Separator class=\"bg-border -mx-1 my-2 h-px\" />\n\n        <ListBoxSection class=\"space-y-1\">\n          <Header class=\"text-muted-foreground px-2 py-1.5 text-xs font-medium\">Condiments</Header>\n          <ListBoxItem\n            id=\"mayo\"\n            class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n          >\n            Mayonaise\n          </ListBoxItem>\n          <ListBoxItem\n            id=\"mustard\"\n            class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n          >\n            Mustard\n          </ListBoxItem>\n          <ListBoxItem\n            id=\"ranch\"\n            class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\"\n          >\n            Ranch\n          </ListBoxItem>\n        </ListBoxSection>\n      </ListBox>\n    </div>\n\n    <p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n      Built with\n      <a\n        class=\"hover:text-foreground underline\"\n        href=\"https://zagjs.com/\"\n        target=\"_blank\"\n        rel=\"noopener nofollow\"\n      >\n        Zag.js\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/select/select-51.html",
          "target": "components/ui/select-51.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label>Listbox with option groups</Label><div class=\"border-input overflow-hidden rounded-md border\"><ListBox class=\"bg-background max-h-72 min-h-20 space-y-2 overflow-auto p-1 text-sm shadow-xs transition-[color,box-shadow]\" aria-label=\"Select some foods\" selectionmode=\"multiple\" defaultselectedkeys=\"${['lettuce', 'tuna']}\"><ListBoxSection class=\"space-y-1\"><Header class=\"text-muted-foreground px-2 py-1.5 text-xs font-medium\">Veggies\n            </Header><ListBoxItem id=\"lettuce\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\">Lettuce\n            </ListBoxItem><ListBoxItem id=\"tomato\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\">Tomato\n            </ListBoxItem><ListBoxItem id=\"onion\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\">Onion\n            </ListBoxItem></ListBoxSection><Separator class=\"bg-border -mx-1 my-2 h-px\" /><ListBoxSection class=\"space-y-1\"><Header class=\"text-muted-foreground px-2 py-1.5 text-xs font-medium\">Protein\n            </Header><ListBoxItem id=\"ham\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\">Ham\n            </ListBoxItem><ListBoxItem id=\"tuna\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\">Tuna\n            </ListBoxItem><ListBoxItem id=\"tofu\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\">Tofu\n            </ListBoxItem></ListBoxSection><Separator class=\"bg-border -mx-1 my-2 h-px\" /><ListBoxSection class=\"space-y-1\"><Header class=\"text-muted-foreground px-2 py-1.5 text-xs font-medium\">Condiments\n            </Header><ListBoxItem id=\"mayo\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\">Mayonaise\n            </ListBoxItem><ListBoxItem id=\"mustard\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\">Mustard\n            </ListBoxItem><ListBoxItem id=\"ranch\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\">Ranch\n            </ListBoxItem></ListBoxSection></ListBox></div><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with${' '}<a class=\"hover:text-foreground underline\" href=\"https://react-spectrum.adobe.com/react-aria/ListBox.html\" target=\"_blank\" rel=\"noopener nofollow\">React Aria\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/select/select-51.wxml",
          "target": "components/ui/select-51/select-51.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label>Listbox with option groups</label><view class=\"border-input overflow-hidden rounded-md border\"><listbox class=\"bg-background max-h-72 min-h-20 space-y-2 overflow-auto p-1 text-sm shadow-xs transition-[color,box-shadow]\" aria-label=\"Select some foods\" selectionmode=\"multiple\" defaultselectedkeys=\"{{['lettuce', 'tuna']}}\"><listboxsection class=\"space-y-1\"><header class=\"text-muted-foreground px-2 py-1.5 text-xs font-medium\">Veggies\n            </header><listboxitem id=\"lettuce\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\">Lettuce\n            </listboxitem><listboxitem id=\"tomato\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\">Tomato\n            </listboxitem><listboxitem id=\"onion\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\">Onion\n            </listboxitem></listboxsection><separator class=\"bg-border -mx-1 my-2 h-px\" /><listboxsection class=\"space-y-1\"><header class=\"text-muted-foreground px-2 py-1.5 text-xs font-medium\">Protein\n            </header><listboxitem id=\"ham\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\">Ham\n            </listboxitem><listboxitem id=\"tuna\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\">Tuna\n            </listboxitem><listboxitem id=\"tofu\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\">Tofu\n            </listboxitem></listboxsection><separator class=\"bg-border -mx-1 my-2 h-px\" /><listboxsection class=\"space-y-1\"><header class=\"text-muted-foreground px-2 py-1.5 text-xs font-medium\">Condiments\n            </header><listboxitem id=\"mayo\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\">Mayonaise\n            </listboxitem><listboxitem id=\"mustard\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\">Mustard\n            </listboxitem><listboxitem id=\"ranch\" class=\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]\">Ranch\n            </listboxitem></listboxsection></listbox></view><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://react-spectrum.adobe.com/react-aria/ListBox.html\" target=\"_blank\" rel=\"noopener nofollow\">React Aria\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "label",
          "select",
          "multiselect",
          "react aria"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "select-51",
          "group": "select",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "select-51",
              "path": "registry/default/components/select/select-51.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "select-51",
              "path": "registry/default/components/select/select-51.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "select-51",
              "path": "registry/default/components/select/select-51.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "select-51",
              "path": "registry/default/components/select/select-51.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "select",
        "title": "Select · With label"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "select"
      ]
    },
    {
      "name": "slider-01",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/slider.json"
      ],
      "files": [
        {
          "path": "registry/default/components/slider/slider-01.tsx",
          "type": "registry:component",
          "target": "components/ui/slider-01.tsx",
          "content": "import { Label, Slider } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"*:not-first:mt-4\">\n      <Label>Simple slider</Label>\n      <Slider defaultValue={[25]} aria-label=\"Simple slider\" />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/slider/slider-01.vue",
          "target": "components/ui/slider-01.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Slider } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-4\"><Label>Simple slider</Label><Slider :default-value=\"[25]\" aria-label=\"Simple slider\" /></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/slider/slider-01.html",
          "target": "components/ui/slider-01.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-4\"><Label>Simple slider</Label><Slider default-value=\"${[25]}\" aria-label=\"Simple slider\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/slider/slider-01.wxml",
          "target": "components/ui/slider-01/slider-01.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-4\"><label>Simple slider</label><slider default-value=\"{{[25]}}\" aria-label=\"Simple slider\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "slider",
          "label",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "slider-01",
          "group": "slider",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "slider-01",
              "path": "registry/default/components/slider/slider-01.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "slider-01",
              "path": "registry/default/components/slider/slider-01.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "slider-01",
              "path": "registry/default/components/slider/slider-01.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "slider-01",
              "path": "registry/default/components/slider/slider-01.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "slider",
        "title": "Slider · Simple slider"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "slider"
      ]
    },
    {
      "name": "slider-02",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/slider.json"
      ],
      "files": [
        {
          "path": "registry/default/components/slider/slider-02.tsx",
          "type": "registry:component",
          "target": "components/ui/slider-02.tsx",
          "content": "import { Label, Slider } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"*:not-first:mt-4\">\n      <Label>Disabled slider</Label>\n      <Slider defaultValue={[25]} disabled aria-label=\"Disabled slider\" />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/slider/slider-02.vue",
          "target": "components/ui/slider-02.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Slider } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-4\"><Label>Disabled slider</Label><Slider :default-value=\"[25]\" disabled aria-label=\"Disabled slider\" /></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/slider/slider-02.html",
          "target": "components/ui/slider-02.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-4\"><Label>Disabled slider</Label><Slider default-value=\"${[25]}\" disabled aria-label=\"Disabled slider\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/slider/slider-02.wxml",
          "target": "components/ui/slider-02/slider-02.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-4\"><label>Disabled slider</label><slider default-value=\"{{[25]}}\" disabled aria-label=\"Disabled slider\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "slider",
          "label",
          "disabled",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "slider-02",
          "group": "slider",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "slider-02",
              "path": "registry/default/components/slider/slider-02.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "slider-02",
              "path": "registry/default/components/slider/slider-02.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "slider-02",
              "path": "registry/default/components/slider/slider-02.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "slider-02",
              "path": "registry/default/components/slider/slider-02.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "slider",
        "title": "Slider · Disabled slider"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "slider"
      ]
    },
    {
      "name": "slider-03",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/slider.json"
      ],
      "files": [
        {
          "path": "registry/default/components/slider/slider-03.tsx",
          "type": "registry:component",
          "target": "components/ui/slider-03.tsx",
          "content": "import { Label, Slider } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"*:not-first:mt-4\">\n      <Label>Slider with square thumb</Label>\n      <Slider\n        defaultValue={[25]}\n        max={100}\n        step={10}\n        className=\"[&>:last-child>span]:rounded\"\n        aria-label=\"Slider with square thumb\"\n      />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/slider/slider-03.vue",
          "target": "components/ui/slider-03.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Slider } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-4\"><Label>Slider with square thumb</Label><Slider :default-value=\"[25]\" :max=\"100\" :step=\"10\" class=\"[&>:last-child>span]:rounded\" aria-label=\"Slider with square thumb\" /></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/slider/slider-03.html",
          "target": "components/ui/slider-03.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-4\"><Label>Slider with square thumb</Label><Slider default-value=\"${[25]}\" max=\"${100}\" step=\"${10}\" class=\"[&>:last-child>span]:rounded\" aria-label=\"Slider with square thumb\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/slider/slider-03.wxml",
          "target": "components/ui/slider-03/slider-03.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-4\"><label>Slider with square thumb</label><slider default-value=\"{{[25]}}\" max=\"{{100}}\" step=\"{{10}}\" class=\"[&>:last-child>span]:rounded\" aria-label=\"Slider with square thumb\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "slider",
          "label",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "slider-03",
          "group": "slider",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "slider-03",
              "path": "registry/default/components/slider/slider-03.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "slider-03",
              "path": "registry/default/components/slider/slider-03.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "slider-03",
              "path": "registry/default/components/slider/slider-03.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "slider-03",
              "path": "registry/default/components/slider/slider-03.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "slider",
        "title": "Slider · Slider with square thumb"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "slider"
      ]
    },
    {
      "name": "slider-04",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/slider.json"
      ],
      "files": [
        {
          "path": "registry/default/components/slider/slider-04.tsx",
          "type": "registry:component",
          "target": "components/ui/slider-04.tsx",
          "content": "import { Label, Slider } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"*:not-first:mt-4\">\n      <Label>Slider with solid thumb</Label>\n      <Slider\n        defaultValue={[25]}\n        className=\"[&>:last-child>span]:bg-primary [&>:first-child>span]:opacity-70\"\n        aria-label=\"Slider with solid thumb\"\n      />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/slider/slider-04.vue",
          "target": "components/ui/slider-04.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Slider } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-4\"><Label>Slider with solid thumb</Label><Slider :default-value=\"[25]\" class=\"[&>:last-child>span]:bg-primary [&>:first-child>span]:opacity-70\" aria-label=\"Slider with solid thumb\" /></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/slider/slider-04.html",
          "target": "components/ui/slider-04.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-4\"><Label>Slider with solid thumb</Label><Slider default-value=\"${[25]}\" class=\"[&>:last-child>span]:bg-primary [&>:first-child>span]:opacity-70\" aria-label=\"Slider with solid thumb\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/slider/slider-04.wxml",
          "target": "components/ui/slider-04/slider-04.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-4\"><label>Slider with solid thumb</label><slider default-value=\"{{[25]}}\" class=\"[&>:last-child>span]:bg-primary [&>:first-child>span]:opacity-70\" aria-label=\"Slider with solid thumb\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "slider",
          "label",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "slider-04",
          "group": "slider",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "slider-04",
              "path": "registry/default/components/slider/slider-04.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "slider-04",
              "path": "registry/default/components/slider/slider-04.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "slider-04",
              "path": "registry/default/components/slider/slider-04.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "slider-04",
              "path": "registry/default/components/slider/slider-04.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "slider",
        "title": "Slider · Slider with solid thumb"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "slider"
      ]
    },
    {
      "name": "slider-05",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/slider.json"
      ],
      "files": [
        {
          "path": "registry/default/components/slider/slider-05.tsx",
          "type": "registry:component",
          "target": "components/ui/slider-05.tsx",
          "content": "import { Label, Slider } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"*:not-first:mt-4\">\n      <Label>Slider with tiny thumb</Label>\n      <Slider\n        defaultValue={[25]}\n        className=\"[&>:last-child>span]:border-background [&>:last-child>span]:bg-primary **:data-[slot=slider-thumb]:shadow-none [&>:last-child>span]:h-6 [&>:last-child>span]:w-2.5 [&>:last-child>span]:border-[3px] [&>:last-child>span]:ring-offset-0\"\n        aria-label=\"Slider with tiny thumb\"\n      />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/slider/slider-05.vue",
          "target": "components/ui/slider-05.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Slider } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-4\"><Label>Slider with tiny thumb</Label><Slider :default-value=\"[25]\" class=\"[&>:last-child>span]:border-background [&>:last-child>span]:bg-primary **:data-[slot=slider-thumb]:shadow-none [&>:last-child>span]:h-6 [&>:last-child>span]:w-2.5 [&>:last-child>span]:border-[3px] [&>:last-child>span]:ring-offset-0\" aria-label=\"Slider with tiny thumb\" /></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/slider/slider-05.html",
          "target": "components/ui/slider-05.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-4\"><Label>Slider with tiny thumb</Label><Slider default-value=\"${[25]}\" class=\"[&>:last-child>span]:border-background [&>:last-child>span]:bg-primary **:data-[slot=slider-thumb]:shadow-none [&>:last-child>span]:h-6 [&>:last-child>span]:w-2.5 [&>:last-child>span]:border-[3px] [&>:last-child>span]:ring-offset-0\" aria-label=\"Slider with tiny thumb\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/slider/slider-05.wxml",
          "target": "components/ui/slider-05/slider-05.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-4\"><label>Slider with tiny thumb</label><slider default-value=\"{{[25]}}\" class=\"[&>:last-child>span]:border-background [&>:last-child>span]:bg-primary **:data-[slot=slider-thumb]:shadow-none [&>:last-child>span]:h-6 [&>:last-child>span]:w-2.5 [&>:last-child>span]:border-[3px] [&>:last-child>span]:ring-offset-0\" aria-label=\"Slider with tiny thumb\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "slider",
          "label",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "slider-05",
          "group": "slider",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "slider-05",
              "path": "registry/default/components/slider/slider-05.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "slider-05",
              "path": "registry/default/components/slider/slider-05.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "slider-05",
              "path": "registry/default/components/slider/slider-05.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "slider-05",
              "path": "registry/default/components/slider/slider-05.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "slider",
        "title": "Slider · Slider with tiny thumb"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "slider"
      ]
    },
    {
      "name": "slider-06",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/slider.json"
      ],
      "files": [
        {
          "path": "registry/default/components/slider/slider-06.tsx",
          "type": "registry:component",
          "target": "components/ui/slider-06.tsx",
          "content": "import { Label, Slider } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"*:not-first:mt-4\">\n      <Label>Slider with reference labels</Label>\n      <div>\n        <Slider defaultValue={[15]} min={5} max={35} aria-label=\"Slider with reference labels\" />\n        <span\n          className=\"text-muted-foreground mt-4 flex w-full items-center justify-between gap-1 text-xs font-medium\"\n          aria-hidden=\"true\"\n        >\n          <span>5 GB</span>\n          <span>20 GB</span>\n          <span>35 GB</span>\n        </span>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/slider/slider-06.vue",
          "target": "components/ui/slider-06.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Slider } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-4\"><Label>Slider with reference labels</Label><div><Slider :default-value=\"[15]\" :min=\"5\" :max=\"35\" aria-label=\"Slider with reference labels\" /><span class=\"text-muted-foreground mt-4 flex w-full items-center justify-between gap-1 text-xs font-medium\" aria-hidden=\"true\"><span>5 GB</span><span>20 GB</span><span>35 GB</span></span></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/slider/slider-06.html",
          "target": "components/ui/slider-06.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-4\"><Label>Slider with reference labels</Label><div><Slider default-value=\"${[15]}\" min=\"${5}\" max=\"${35}\" aria-label=\"Slider with reference labels\" /><span class=\"text-muted-foreground mt-4 flex w-full items-center justify-between gap-1 text-xs font-medium\" aria-hidden=\"true\"><span>5 GB</span><span>20 GB</span><span>35 GB</span></span></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/slider/slider-06.wxml",
          "target": "components/ui/slider-06/slider-06.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-4\"><label>Slider with reference labels</label><view><slider default-value=\"{{[15]}}\" min=\"{{5}}\" max=\"{{35}}\" aria-label=\"Slider with reference labels\" /><text class=\"text-muted-foreground mt-4 flex w-full items-center justify-between gap-1 text-xs font-medium\" aria-hidden=\"true\"><text>5 GB</text><text>20 GB</text><text>35 GB</text></text></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "slider",
          "label",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "slider-06",
          "group": "slider",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "slider-06",
              "path": "registry/default/components/slider/slider-06.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "slider-06",
              "path": "registry/default/components/slider/slider-06.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "slider-06",
              "path": "registry/default/components/slider/slider-06.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "slider-06",
              "path": "registry/default/components/slider/slider-06.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "slider",
        "title": "Slider · Slider with reference labels"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "slider"
      ]
    },
    {
      "name": "slider-07",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/slider.json"
      ],
      "files": [
        {
          "path": "registry/default/components/slider/slider-07.tsx",
          "type": "registry:component",
          "target": "components/ui/slider-07.tsx",
          "content": "import { cn } from '@timui/core'\nimport { Label, Slider } from '@timui/react'\n\nexport default function Component() {\n  const max = 12\n  const skipInterval = 2 // Set to 1 to allow no text skipping\n  const ticks = [...Array(max + 1)].map((_, i) => i)\n\n  return (\n    <div className=\"*:not-first:mt-4\">\n      <Label>Slider with ticks</Label>\n      <div>\n        <Slider defaultValue={[5]} max={max} aria-label=\"Slider with ticks\" />\n        <span\n          className=\"text-muted-foreground mt-3 flex w-full items-center justify-between gap-1 px-2.5 text-xs font-medium\"\n          aria-hidden=\"true\"\n        >\n          {ticks.map((_, i) => (\n            <span key={i} className=\"flex w-0 flex-col items-center justify-center gap-2\">\n              <span\n                className={cn('bg-muted-foreground/70 h-1 w-px', i % skipInterval !== 0 && 'h-0.5')}\n              />\n              <span className={cn(i % skipInterval !== 0 && 'opacity-0')}>{i}</span>\n            </span>\n          ))}\n        </span>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/slider/slider-07.vue",
          "target": "components/ui/slider-07.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn } from '@timui/core';\nimport { Label } from '@timui/vue';\nimport { Slider } from '@timui/vue';\n\n\n\n\n\nconst ticks = [...Array(max + 1)].map((_, i) => i)\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-4\"><Label>Slider with ticks</Label><div><Slider :default-value=\"[5]\" :max=\"max\" aria-label=\"Slider with ticks\" /><span class=\"text-muted-foreground mt-3 flex w-full items-center justify-between gap-1 px-2.5 text-xs font-medium\" aria-hidden=\"true\"><span v-for=\"(_, i) in ticks\" :key=\"i\" class=\"flex w-0 flex-col items-center justify-center gap-2\"><span :class=\"cn('bg-muted-foreground/70 h-1 w-px', i % skipInterval !== 0 && 'h-0.5')\" /><span :class=\"cn(i % skipInterval !== 0 && 'opacity-0')\">{{ i }}</span></span></span></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/slider/slider-07.html",
          "target": "components/ui/slider-07.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-4\"><Label>Slider with ticks</Label><div><Slider default-value=\"${[5]}\" max=\"${max}\" aria-label=\"Slider with ticks\" /><span class=\"text-muted-foreground mt-3 flex w-full items-center justify-between gap-1 px-2.5 text-xs font-medium\" aria-hidden=\"true\"><!-- Loop ticks -->\n<span key=\"${i}\" class=\"flex w-0 flex-col items-center justify-center gap-2\"><span class=\"${cn('bg-muted-foreground/70 h-1 w-px', i % skipInterval !== 0 && 'h-0.5')}\" /><span class=\"${cn(i % skipInterval !== 0 && 'opacity-0')}\">${i}</span></span>\n<!-- End Loop --></span></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/slider/slider-07.wxml",
          "target": "components/ui/slider-07/slider-07.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-4\"><label>Slider with ticks</label><view><slider default-value=\"{{[5]}}\" max=\"{{max}}\" aria-label=\"Slider with ticks\" /><text class=\"text-muted-foreground mt-3 flex w-full items-center justify-between gap-1 px-2.5 text-xs font-medium\" aria-hidden=\"true\"><text wx:for=\"{{ticks}}\" wx:for-item=\"_\" wx:for-index=\"i\" wx:key=\"i\" key=\"{{i}}\" class=\"flex w-0 flex-col items-center justify-center gap-2\"><span class=\"{{cn('bg-muted-foreground/70 h-1 w-px', i % skipInterval !== 0 && 'h-0.5')}}\" /><text class=\"{{cn(i % skipInterval !== 0 && 'opacity-0')}}\">{{ i }}</text></text></text></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "slider",
          "label",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "slider-07",
          "group": "slider",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "slider-07",
              "path": "registry/default/components/slider/slider-07.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "slider-07",
              "path": "registry/default/components/slider/slider-07.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "slider-07",
              "path": "registry/default/components/slider/slider-07.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "slider-07",
              "path": "registry/default/components/slider/slider-07.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "slider",
        "title": "Slider · Slider with ticks"
      },
      "dependencies": [
        "@timui/core",
        "@timui/react"
      ],
      "categories": [
        "slider"
      ]
    },
    {
      "name": "slider-08",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/slider.json"
      ],
      "files": [
        {
          "path": "registry/default/components/slider/slider-08.tsx",
          "type": "registry:component",
          "target": "components/ui/slider-08.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Label, Slider } from '@timui/react'\n\nexport default function Component() {\n  const [value, setValue] = useState([25])\n\n  return (\n    <div className=\"space-y-4\">\n      <div className=\"flex items-center justify-between gap-2\">\n        <Label className=\"leading-6\">Slider with output</Label>\n        <output className=\"text-sm font-medium tabular-nums\">{value[0]}</output>\n      </div>\n      <Slider value={value} onValueChange={setValue} aria-label=\"Slider with output\" />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/slider/slider-08.vue",
          "target": "components/ui/slider-08.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Label } from '@timui/vue';\nimport { Slider } from '@timui/vue';\n\n\n\nconst value = ref([25]);\n\n\nfunction setValue(next: typeof value.value | ((prev: typeof value.value) => typeof value.value)) {\n  value.value = typeof next === 'function'\n    ? (next as (prev: typeof value.value) => typeof value.value)(value.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <div class=\"space-y-4\"><div class=\"flex items-center justify-between gap-2\"><Label class=\"leading-6\">Slider with output</Label><output class=\"text-sm font-medium tabular-nums\">{{ value[0] }}</output></div><Slider :value=\"value\" @update:modelValue=\"setValue\" aria-label=\"Slider with output\" /></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/slider/slider-08.html",
          "target": "components/ui/slider-08.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-4\"><div class=\"flex items-center justify-between gap-2\"><Label class=\"leading-6\">Slider with output</Label><output class=\"text-sm font-medium tabular-nums\">${value[0]}</output></div><Slider value=\"${value}\" on-value-change=\"${setValue}\" aria-label=\"Slider with output\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/slider/slider-08.wxml",
          "target": "components/ui/slider-08/slider-08.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-4\"><view class=\"flex items-center justify-between gap-2\"><label class=\"leading-6\">Slider with output</label><output class=\"text-sm font-medium tabular-nums\">{{ value[0] }}</output></view><slider value=\"{{value}}\" bindchange=\"setValue\" aria-label=\"Slider with output\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "slider",
          "label",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "slider-08",
          "group": "slider",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "slider-08",
              "path": "registry/default/components/slider/slider-08.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "slider-08",
              "path": "registry/default/components/slider/slider-08.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "slider-08",
              "path": "registry/default/components/slider/slider-08.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "slider-08",
              "path": "registry/default/components/slider/slider-08.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "slider",
        "title": "Slider · Slider with output"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "slider"
      ]
    },
    {
      "name": "slider-09",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/slider.json"
      ],
      "files": [
        {
          "path": "registry/default/components/slider/slider-09.tsx",
          "type": "registry:component",
          "target": "components/ui/slider-09.tsx",
          "content": "import { Label, Slider } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"*:not-first:mt-4\">\n      <Label>Slider with labels</Label>\n      <div>\n        <span\n          className=\"text-muted-foreground mb-3 flex w-full items-center justify-between gap-2 text-xs font-medium\"\n          aria-hidden=\"true\"\n        >\n          <span>Low</span>\n          <span>High</span>\n        </span>\n        <Slider defaultValue={[50]} step={10} aria-label=\"Slider with labels\" />\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/slider/slider-09.vue",
          "target": "components/ui/slider-09.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Slider } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-4\"><Label>Slider with labels</Label><div><span class=\"text-muted-foreground mb-3 flex w-full items-center justify-between gap-2 text-xs font-medium\" aria-hidden=\"true\"><span>Low</span><span>High</span></span><Slider :default-value=\"[50]\" :step=\"10\" aria-label=\"Slider with labels\" /></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/slider/slider-09.html",
          "target": "components/ui/slider-09.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-4\"><Label>Slider with labels</Label><div><span class=\"text-muted-foreground mb-3 flex w-full items-center justify-between gap-2 text-xs font-medium\" aria-hidden=\"true\"><span>Low</span><span>High</span></span><Slider default-value=\"${[50]}\" step=\"${10}\" aria-label=\"Slider with labels\" /></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/slider/slider-09.wxml",
          "target": "components/ui/slider-09/slider-09.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-4\"><label>Slider with labels</label><view><text class=\"text-muted-foreground mb-3 flex w-full items-center justify-between gap-2 text-xs font-medium\" aria-hidden=\"true\"><text>Low</text><text>High</text></text><slider default-value=\"{{[50]}}\" step=\"{{10}}\" aria-label=\"Slider with labels\" /></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "slider",
          "label",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "slider-09",
          "group": "slider",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "slider-09",
              "path": "registry/default/components/slider/slider-09.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "slider-09",
              "path": "registry/default/components/slider/slider-09.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "slider-09",
              "path": "registry/default/components/slider/slider-09.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "slider-09",
              "path": "registry/default/components/slider/slider-09.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "slider",
        "title": "Slider · Slider with labels"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "slider"
      ]
    },
    {
      "name": "slider-10",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/slider.json"
      ],
      "files": [
        {
          "path": "registry/default/components/slider/slider-10.tsx",
          "type": "registry:component",
          "target": "components/ui/slider-10.tsx",
          "content": "import { Label, Slider } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"*:not-first:mt-4\">\n      <Label>Slider with labels and tooltip</Label>\n      <div>\n        <span\n          className=\"text-muted-foreground mb-3 flex w-full items-center justify-between gap-2 text-xs font-medium\"\n          aria-hidden=\"true\"\n        >\n          <span>Low</span>\n          <span>High</span>\n        </span>\n        <Slider\n          defaultValue={[50]}\n          step={10}\n          showTooltip={true}\n          aria-label=\"Slider with labels and tooltip\"\n        />\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/slider/slider-10.vue",
          "target": "components/ui/slider-10.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Slider } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-4\"><Label>Slider with labels and tooltip</Label><div><span class=\"text-muted-foreground mb-3 flex w-full items-center justify-between gap-2 text-xs font-medium\" aria-hidden=\"true\"><span>Low</span><span>High</span></span><Slider :default-value=\"[50]\" :step=\"10\" :showTooltip=\"true\" aria-label=\"Slider with labels and tooltip\" /></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/slider/slider-10.html",
          "target": "components/ui/slider-10.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-4\"><Label>Slider with labels and tooltip</Label><div><span class=\"text-muted-foreground mb-3 flex w-full items-center justify-between gap-2 text-xs font-medium\" aria-hidden=\"true\"><span>Low</span><span>High</span></span><Slider default-value=\"${[50]}\" step=\"${10}\" showtooltip=\"${true}\" aria-label=\"Slider with labels and tooltip\" /></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/slider/slider-10.wxml",
          "target": "components/ui/slider-10/slider-10.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-4\"><label>Slider with labels and tooltip</label><view><text class=\"text-muted-foreground mb-3 flex w-full items-center justify-between gap-2 text-xs font-medium\" aria-hidden=\"true\"><text>Low</text><text>High</text></text><slider default-value=\"{{[50]}}\" step=\"{{10}}\" showtooltip=\"{{true}}\" aria-label=\"Slider with labels and tooltip\" /></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "slider",
          "label",
          "tooltip",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "slider-10",
          "group": "slider",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "slider-10",
              "path": "registry/default/components/slider/slider-10.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "slider-10",
              "path": "registry/default/components/slider/slider-10.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "slider-10",
              "path": "registry/default/components/slider/slider-10.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "slider-10",
              "path": "registry/default/components/slider/slider-10.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "slider",
        "title": "Slider · Slider with labels and tooltip"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "slider"
      ]
    },
    {
      "name": "slider-11",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/slider.json"
      ],
      "files": [
        {
          "path": "registry/default/components/slider/slider-11.tsx",
          "type": "registry:component",
          "target": "components/ui/slider-11.tsx",
          "content": "import { Label, Slider } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"*:not-first:mt-4\">\n      <Label>Dual range slider</Label>\n      <Slider defaultValue={[25, 75]} step={10} aria-label=\"Dual range slider\" />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/slider/slider-11.vue",
          "target": "components/ui/slider-11.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Slider } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-4\"><Label>Dual range slider</Label><Slider :default-value=\"[25, 75]\" :step=\"10\" aria-label=\"Dual range slider\" /></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/slider/slider-11.html",
          "target": "components/ui/slider-11.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-4\"><Label>Dual range slider</Label><Slider default-value=\"${[25, 75]}\" step=\"${10}\" aria-label=\"Dual range slider\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/slider/slider-11.wxml",
          "target": "components/ui/slider-11/slider-11.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-4\"><label>Dual range slider</label><slider default-value=\"{{[25, 75]}}\" step=\"{{10}}\" aria-label=\"Dual range slider\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "slider",
          "range slider",
          "label",
          "range",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "slider-11",
          "group": "slider",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "slider-11",
              "path": "registry/default/components/slider/slider-11.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "slider-11",
              "path": "registry/default/components/slider/slider-11.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "slider-11",
              "path": "registry/default/components/slider/slider-11.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "slider-11",
              "path": "registry/default/components/slider/slider-11.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "slider",
        "title": "Slider · Dual range slider"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "slider"
      ]
    },
    {
      "name": "slider-12",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/slider.json"
      ],
      "files": [
        {
          "path": "registry/default/components/slider/slider-12.tsx",
          "type": "registry:component",
          "target": "components/ui/slider-12.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Label, Slider } from '@timui/react'\n\nexport default function Component() {\n  const [value, setValue] = useState([25, 75])\n\n  return (\n    <div className=\"space-y-4\">\n      <div className=\"flex items-center justify-between gap-2\">\n        <Label className=\"leading-6\">Dual range slider with output</Label>\n        <output className=\"text-sm font-medium tabular-nums\">\n          {value[0]} - {value[1]}\n        </output>\n      </div>\n      <Slider value={value} onValueChange={setValue} aria-label=\"Dual range slider with output\" />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/slider/slider-12.vue",
          "target": "components/ui/slider-12.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Label } from '@timui/vue';\nimport { Slider } from '@timui/vue';\n\n\n\nconst value = ref([25, 75]);\n\n\nfunction setValue(next: typeof value.value | ((prev: typeof value.value) => typeof value.value)) {\n  value.value = typeof next === 'function'\n    ? (next as (prev: typeof value.value) => typeof value.value)(value.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <div class=\"space-y-4\"><div class=\"flex items-center justify-between gap-2\"><Label class=\"leading-6\">Dual range slider with output</Label><output class=\"text-sm font-medium tabular-nums\">{{ value[0] }}- {{ value[1] }}</output></div><Slider :value=\"value\" @update:modelValue=\"setValue\" aria-label=\"Dual range slider with output\" /></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/slider/slider-12.html",
          "target": "components/ui/slider-12.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-4\"><div class=\"flex items-center justify-between gap-2\"><Label class=\"leading-6\">Dual range slider with output</Label><output class=\"text-sm font-medium tabular-nums\">${value[0]}- ${value[1]}</output></div><Slider value=\"${value}\" on-value-change=\"${setValue}\" aria-label=\"Dual range slider with output\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/slider/slider-12.wxml",
          "target": "components/ui/slider-12/slider-12.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-4\"><view class=\"flex items-center justify-between gap-2\"><label class=\"leading-6\">Dual range slider with output</label><output class=\"text-sm font-medium tabular-nums\">{{ value[0] }}- {{ value[1] }}</output></view><slider value=\"{{value}}\" bindchange=\"setValue\" aria-label=\"Dual range slider with output\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "slider",
          "range slider",
          "label",
          "range",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "slider-12",
          "group": "slider",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "slider-12",
              "path": "registry/default/components/slider/slider-12.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "slider-12",
              "path": "registry/default/components/slider/slider-12.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "slider-12",
              "path": "registry/default/components/slider/slider-12.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "slider-12",
              "path": "registry/default/components/slider/slider-12.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "slider",
        "title": "Slider · Dual range slider with output"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "slider"
      ]
    },
    {
      "name": "slider-13",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/slider.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/slider/slider-13.tsx",
          "type": "registry:component",
          "target": "components/ui/slider-13.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Label, Slider } from '@timui/react'\nimport { Volume2Icon, VolumeXIcon } from 'lucide-react'\n\nexport default function Component() {\n  const [value, setValue] = useState([25])\n\n  return (\n    <div className=\"space-y-3\">\n      <div className=\"flex items-center justify-between gap-2\">\n        <Label className=\"leading-6\">Volume</Label>\n        <output className=\"text-sm font-medium tabular-nums\">{value[0]}</output>\n      </div>\n      <div className=\"flex items-center gap-2\">\n        <VolumeXIcon className=\"shrink-0 opacity-60\" size={16} aria-hidden=\"true\" />\n        <Slider value={value} onValueChange={setValue} aria-label=\"Volume slider\" />\n        <Volume2Icon className=\"shrink-0 opacity-60\" size={16} aria-hidden=\"true\" />\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/slider/slider-13.vue",
          "target": "components/ui/slider-13.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Volume2Icon, VolumeXIcon } from 'lucide-vue-next';\nimport { Label } from '@timui/vue';\nimport { Slider } from '@timui/vue';\n\n\n\nconst value = ref([25]);\n\n\nfunction setValue(next: typeof value.value | ((prev: typeof value.value) => typeof value.value)) {\n  value.value = typeof next === 'function'\n    ? (next as (prev: typeof value.value) => typeof value.value)(value.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <div class=\"space-y-3\"><div class=\"flex items-center justify-between gap-2\"><Label class=\"leading-6\">Volume</Label><output class=\"text-sm font-medium tabular-nums\">{{ value[0] }}</output></div><div class=\"flex items-center gap-2\"><VolumeXIcon class=\"shrink-0 opacity-60\" :size=\"16\" aria-hidden=\"true\" /><Slider :value=\"value\" @update:modelValue=\"setValue\" aria-label=\"Volume slider\" /><Volume2Icon class=\"shrink-0 opacity-60\" :size=\"16\" aria-hidden=\"true\" /></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/slider/slider-13.html",
          "target": "components/ui/slider-13.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-3\"><div class=\"flex items-center justify-between gap-2\"><Label class=\"leading-6\">Volume</Label><output class=\"text-sm font-medium tabular-nums\">${value[0]}</output></div><div class=\"flex items-center gap-2\"><VolumeXIcon class=\"shrink-0 opacity-60\" size=\"${16}\" aria-hidden=\"true\" /><Slider value=\"${value}\" on-value-change=\"${setValue}\" aria-label=\"Volume slider\" /><Volume2Icon class=\"shrink-0 opacity-60\" size=\"${16}\" aria-hidden=\"true\" /></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/slider/slider-13.wxml",
          "target": "components/ui/slider-13/slider-13.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-3\"><view class=\"flex items-center justify-between gap-2\"><label class=\"leading-6\">Volume</label><output class=\"text-sm font-medium tabular-nums\">{{ value[0] }}</output></view><view class=\"flex items-center gap-2\"><volumexicon class=\"shrink-0 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" /><slider value=\"{{value}}\" bindchange=\"setValue\" aria-label=\"Volume slider\" /><volume2icon class=\"shrink-0 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" /></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "slider",
          "label",
          "volume",
          "controls",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "slider-13",
          "group": "slider",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "slider-13",
              "path": "registry/default/components/slider/slider-13.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "slider-13",
              "path": "registry/default/components/slider/slider-13.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "slider-13",
              "path": "registry/default/components/slider/slider-13.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "slider-13",
              "path": "registry/default/components/slider/slider-13.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "slider",
        "title": "Slider · Volume slider"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "slider"
      ]
    },
    {
      "name": "slider-14",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/slider.json"
      ],
      "files": [
        {
          "path": "registry/default/components/slider/slider-14.tsx",
          "type": "registry:component",
          "target": "components/ui/slider-14.tsx",
          "content": "'use client'\n\nimport { Label, Slider } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"*:not-first:mt-4\">\n      <Label>Slider with multiple thumbs</Label>\n      <Slider\n        defaultValue={[25, 50, 100]}\n        aria-label=\"Slider with multiple thumbs\"\n        showTooltip\n        tooltipContent={(value) => `${value}%`}\n      />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/slider/slider-14.vue",
          "target": "components/ui/slider-14.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Slider } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-4\"><Label>Slider with multiple thumbs</Label><Slider :default-value=\"[25, 50, 100]\" aria-label=\"Slider with multiple thumbs\" showTooltip :tooltipContent=\"(value) => `${value}%`\" /></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/slider/slider-14.html",
          "target": "components/ui/slider-14.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-4\"><Label>Slider with multiple thumbs</Label><Slider default-value=\"${[25, 50, 100]}\" aria-label=\"Slider with multiple thumbs\" showtooltip tooltipcontent=\"${(value) => `${value}%`}\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/slider/slider-14.wxml",
          "target": "components/ui/slider-14/slider-14.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-4\"><label>Slider with multiple thumbs</label><slider default-value=\"{{[25, 50, 100]}}\" aria-label=\"Slider with multiple thumbs\" showtooltip tooltipcontent=\"{{(value) => `${value}%`}}\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "slider",
          "range slider",
          "label",
          "range",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "slider-14",
          "group": "slider",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "slider-14",
              "path": "registry/default/components/slider/slider-14.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "slider-14",
              "path": "registry/default/components/slider/slider-14.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "slider-14",
              "path": "registry/default/components/slider/slider-14.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "slider-14",
              "path": "registry/default/components/slider/slider-14.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "slider",
        "title": "Slider · Slider with multiple thumbs"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "slider"
      ]
    },
    {
      "name": "slider-15",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/slider.json",
        "https://ui.timkit.cn/r/tooltip.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/slider/slider-15.tsx",
          "type": "registry:component",
          "target": "components/ui/slider-15.tsx",
          "content": "'use client'\n\nimport { cn } from '@timui/core'\nimport {\n  Button,\n  Input,\n  Label,\n  Slider,\n  Tooltip,\n  TooltipContent,\n  TooltipProvider,\n  TooltipTrigger,\n} from '@timui/react'\nimport { RotateCcwIcon } from 'lucide-react'\n\nimport { useSliderWithInput } from '@/registry/default/hooks/use-slider-with-input'\n\nexport default function Component() {\n  const minValue = 0\n  const maxValue = 2\n  const initialValue = [1.25]\n  const defaultValue = [1]\n\n  const {\n    sliderValue,\n    inputValues,\n    validateAndUpdateValue,\n    handleInputChange,\n    handleSliderChange,\n    resetToDefault,\n    showReset,\n  } = useSliderWithInput({ minValue, maxValue, initialValue, defaultValue })\n\n  return (\n    <div className=\"space-y-3\">\n      <div className=\"flex items-center justify-between gap-2\">\n        <Label>Temperature</Label>\n        <div className=\"flex items-center gap-1\">\n          <TooltipProvider delayDuration={0}>\n            <Tooltip>\n              <TooltipTrigger asChild>\n                <Button\n                  size=\"icon\"\n                  variant=\"ghost\"\n                  className={cn(\n                    'size-7 transition-opacity',\n                    showReset ? 'opacity-100' : 'opacity-0'\n                  )}\n                  aria-label=\"Reset\"\n                  onClick={resetToDefault}\n                >\n                  <RotateCcwIcon size={16} aria-hidden=\"true\" />\n                </Button>\n              </TooltipTrigger>\n              <TooltipContent className=\"px-2 py-1 text-xs\">Reset to default</TooltipContent>\n            </Tooltip>\n          </TooltipProvider>\n          <Input\n            className=\"h-7 w-12 px-2 py-0\"\n            type=\"text\"\n            inputMode=\"decimal\"\n            value={inputValues[0]}\n            onChange={(e) => handleInputChange(e, 0)}\n            onBlur={() => validateAndUpdateValue(inputValues[0] ?? '', 0)}\n            onKeyDown={(e) => {\n              if (e.key === 'Enter') {\n                validateAndUpdateValue(inputValues[0] ?? '', 0)\n              }\n            }}\n            aria-label=\"Enter value\"\n          />\n        </div>\n      </div>\n      <div className=\"flex items-center gap-4\">\n        <Slider\n          className=\"grow\"\n          value={sliderValue}\n          onValueChange={handleSliderChange}\n          min={minValue}\n          max={maxValue}\n          step={0.01}\n          aria-label=\"Temperature\"\n        />\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/hooks/use-slider-with-input.ts",
          "type": "registry:hook",
          "target": "components/ui/slider-15/use-slider-with-input.ts",
          "content": "'use client'\n\nimport { useCallback, useState } from 'react'\n\ntype UseSliderWithInputProps = {\n  minValue?: number\n  maxValue?: number\n  initialValue?: number[]\n  defaultValue?: number[]\n}\n\nexport function useSliderWithInput({\n  minValue = 0,\n  maxValue = 100,\n  initialValue = [minValue],\n  defaultValue = [minValue],\n}: UseSliderWithInputProps) {\n  const [sliderValue, setSliderValue] = useState(initialValue)\n  const [inputValues, setInputValues] = useState(initialValue.map((v) => v.toString()))\n\n  const showReset =\n    sliderValue.length === defaultValue.length &&\n    !sliderValue.every((value, index) => value === defaultValue[index])\n\n  const validateAndUpdateValue = useCallback(\n    (rawValue: string, index: number) => {\n      if (rawValue === '' || rawValue === '-') {\n        const newInputValues = [...inputValues]\n        newInputValues[index] = '0'\n        setInputValues(newInputValues)\n\n        const newSliderValues = [...sliderValue]\n        newSliderValues[index] = 0\n        setSliderValue(newSliderValues)\n        return\n      }\n\n      const numValue = parseFloat(rawValue)\n\n      if (isNaN(numValue)) {\n        const newInputValues = [...inputValues]\n        newInputValues[index] = sliderValue[index]!.toString()\n        setInputValues(newInputValues)\n        return\n      }\n\n      let clampedValue = Math.min(maxValue, Math.max(minValue, numValue))\n\n      if (sliderValue.length > 1) {\n        if (index === 0) {\n          clampedValue = Math.min(clampedValue, sliderValue[1]!)\n        } else {\n          clampedValue = Math.max(clampedValue, sliderValue[0]!)\n        }\n      }\n\n      const newSliderValues = [...sliderValue]\n      newSliderValues[index] = clampedValue\n      setSliderValue(newSliderValues)\n\n      const newInputValues = [...inputValues]\n      newInputValues[index] = clampedValue.toString()\n      setInputValues(newInputValues)\n    },\n    [sliderValue, inputValues, minValue, maxValue]\n  )\n\n  const handleInputChange = useCallback(\n    (e: React.ChangeEvent<HTMLInputElement>, index: number) => {\n      const newValue = e.target.value\n      if (newValue === '' || /^-?\\d*\\.?\\d*$/.test(newValue)) {\n        const newInputValues = [...inputValues]\n        newInputValues[index] = newValue\n        setInputValues(newInputValues)\n      }\n    },\n    [inputValues]\n  )\n\n  const handleSliderChange = useCallback((newValue: number[]) => {\n    setSliderValue(newValue)\n    setInputValues(newValue.map((v) => v.toString()))\n  }, [])\n\n  const resetToDefault = useCallback(() => {\n    setSliderValue(defaultValue)\n    setInputValues(defaultValue.map((v) => v.toString()))\n  }, [defaultValue])\n\n  return {\n    sliderValue,\n    inputValues,\n    validateAndUpdateValue,\n    handleInputChange,\n    handleSliderChange,\n    resetToDefault,\n    showReset,\n  }\n}\n"
        },
        {
          "path": "registry/default/components/slider/slider-15.vue",
          "target": "components/ui/slider-15.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn } from '@timui/core';\nimport { RotateCcwIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\nimport { Slider } from '@timui/vue';\nimport { Tooltip } from '@timui/vue';\nimport { TooltipContent } from '@timui/vue';\nimport { TooltipProvider } from '@timui/vue';\nimport { TooltipTrigger } from '@timui/vue';\nimport { useSliderWithInput } from '@/registry/default/hooks/use-slider-with-input-vue';\n\nconst minValue = 0;\nconst maxValue = 2;\nconst initialValue = [1.25];\nconst defaultValue = [1];\n\nconst {\n  sliderValue,\n  inputValues,\n  validateAndUpdateValue,\n  handleInputChange,\n  handleSliderChange,\n  resetToDefault,\n  showReset,\n} = useSliderWithInput({ minValue, maxValue, initialValue, defaultValue });\n</script>\n\n<template>\n  <div class=\"space-y-3\">\n    <div class=\"flex items-center justify-between gap-2\">\n      <Label>Temperature</Label>\n      <div class=\"flex items-center gap-1\">\n        <TooltipProvider :delayDuration=\"0\">\n          <Tooltip>\n            <TooltipTrigger as-child>\n              <Button\n                size=\"icon\"\n                variant=\"ghost\"\n                :class=\"cn('size-7 transition-opacity', showReset ? 'opacity-100' : 'opacity-0')\"\n                aria-label=\"Reset\"\n                @click=\"resetToDefault\"\n              >\n                <RotateCcwIcon :size=\"16\" aria-hidden=\"true\" />\n              </Button>\n            </TooltipTrigger>\n            <TooltipContent class=\"px-2 py-1 text-xs\">Reset to default</TooltipContent>\n          </Tooltip>\n        </TooltipProvider>\n        <Input\n          class=\"h-7 w-12 px-2 py-0\"\n          type=\"text\"\n          inputMode=\"decimal\"\n          :model-value=\"inputValues[0] ?? ''\"\n          @update:modelValue=\"(next) => handleInputChange(next, 0)\"\n          @blur=\"() => validateAndUpdateValue(inputValues[0] ?? '', 0)\"\n          @keydown.enter.prevent=\"validateAndUpdateValue(inputValues[0] ?? '', 0)\"\n          aria-label=\"Enter value\"\n        />\n      </div>\n    </div>\n    <div class=\"flex items-center gap-4\">\n      <Slider\n        class=\"grow\"\n        :value=\"sliderValue\"\n        @update:modelValue=\"handleSliderChange\"\n        :min=\"minValue\"\n        :max=\"maxValue\"\n        :step=\"0.01\"\n        aria-label=\"Temperature\"\n      />\n    </div>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/slider/slider-15.html",
          "target": "components/ui/slider-15.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-3\"><div class=\"flex items-center justify-between gap-2\"><Label>Temperature</Label><div class=\"flex items-center gap-1\"><TooltipProvider delayduration=\"${0}\"><Tooltip><TooltipTrigger aschild><Button size=\"icon\" variant=\"ghost\" class=\"${cn(\n                    'size-7 transition-opacity',\n                    showReset ? 'opacity-100' : 'opacity-0'\n                  )}\" aria-label=\"Reset\" on-click=\"${resetToDefault}\"><RotateCcwIcon size=\"${16}\" aria-hidden=\"true\" /></Button></TooltipTrigger><TooltipContent class=\"px-2 py-1 text-xs\">Reset to default</TooltipContent></Tooltip></TooltipProvider><Input class=\"h-7 w-12 px-2 py-0\" type=\"text\" inputmode=\"decimal\" value=\"${inputValues[0]}\" onchange=\"${(e) => handleInputChange(e, 0)}\" onblur=\"${() => validateAndUpdateValue(inputValues[0] ?? '', 0)}\" onkeydown=\"${(e) => {\n              if (e.key === 'Enter') {\n                validateAndUpdateValue(inputValues[0] ?? '', 0)\n              }\n            }}\" aria-label=\"Enter value\" /></div></div><div class=\"flex items-center gap-4\"><Slider class=\"grow\" value=\"${sliderValue}\" on-value-change=\"${handleSliderChange}\" min=\"${minValue}\" max=\"${maxValue}\" step=\"${0.01}\" aria-label=\"Temperature\" /></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/slider/slider-15.wxml",
          "target": "components/ui/slider-15/slider-15.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-3\"><view class=\"flex items-center justify-between gap-2\"><label>Temperature</label><view class=\"flex items-center gap-1\"><tooltipprovider delayduration=\"{{0}}\"><tooltip><tooltiptrigger aschild><button size=\"icon\" variant=\"ghost\" class=\"{{cn(\n                    'size-7 transition-opacity',\n                    showReset ? 'opacity-100' : 'opacity-0'\n                  )}}\" aria-label=\"Reset\" bindtap=\"resetToDefault\"><rotateccwicon size=\"{{16}}\" aria-hidden=\"true\" /></button></tooltiptrigger><tooltipcontent class=\"px-2 py-1 text-xs\">Reset to default</tooltipcontent></tooltip></tooltipprovider><input class=\"h-7 w-12 px-2 py-0\" type=\"text\" inputmode=\"decimal\" value=\"{{inputValues[0]}}\" onchange=\"{{(e) => handleInputChange(e, 0)}}\" onblur=\"{{() => validateAndUpdateValue(inputValues[0] ?? '', 0)}}\" onkeydown=\"{{(e) => {\n              if (e.key === 'Enter') {\n                validateAndUpdateValue(inputValues[0] ?? '', 0)\n              }\n            }}}\" aria-label=\"Enter value\" /></view></view><view class=\"flex items-center gap-4\"><slider class=\"grow\" value=\"{{sliderValue}}\" bindchange=\"handleSliderChange\" min=\"{{minValue}}\" max=\"{{maxValue}}\" step=\"{{0.01}}\" aria-label=\"Temperature\" /></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "slider",
          "label",
          "button",
          "input",
          "tooltip",
          "reset",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "slider-15",
          "group": "slider",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "slider-15",
              "path": "registry/default/components/slider/slider-15.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "slider-15",
              "path": "registry/default/components/slider/slider-15.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "slider-15",
              "path": "registry/default/components/slider/slider-15.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "slider-15",
              "path": "registry/default/components/slider/slider-15.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "slider",
        "title": "Slider · Reset"
      },
      "dependencies": [
        "@timui/core",
        "@timui/react"
      ],
      "categories": [
        "slider"
      ]
    },
    {
      "name": "slider-16",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/slider.json"
      ],
      "files": [
        {
          "path": "registry/default/components/slider/slider-16.tsx",
          "type": "registry:component",
          "target": "components/ui/slider-16.tsx",
          "content": "'use client'\n\nimport { Input, Label, Slider } from '@timui/react'\n\nimport { useSliderWithInput } from '@/registry/default/hooks/use-slider-with-input'\n\nexport default function Component() {\n  const minValue = 0\n  const maxValue = 100\n  const initialValue = [25]\n\n  const {\n    sliderValue,\n    inputValues,\n    validateAndUpdateValue,\n    handleInputChange,\n    handleSliderChange,\n  } = useSliderWithInput({ minValue, maxValue, initialValue })\n\n  return (\n    <div className=\"*:not-first:mt-3\">\n      <Label>Slider with input</Label>\n      <div className=\"flex items-center gap-4\">\n        <Slider\n          className=\"grow\"\n          value={sliderValue}\n          onValueChange={handleSliderChange}\n          min={minValue}\n          max={maxValue}\n          aria-label=\"Slider with input\"\n        />\n        <Input\n          className=\"h-8 w-12 px-2 py-1\"\n          type=\"text\"\n          inputMode=\"decimal\"\n          value={inputValues[0]}\n          onChange={(e) => handleInputChange(e, 0)}\n          onBlur={() => validateAndUpdateValue(inputValues[0], 0)}\n          onKeyDown={(e) => {\n            if (e.key === 'Enter') {\n              validateAndUpdateValue(inputValues[0], 0)\n            }\n          }}\n          aria-label=\"Enter value\"\n        />\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/hooks/use-slider-with-input.ts",
          "type": "registry:hook",
          "target": "components/ui/slider-16/use-slider-with-input.ts",
          "content": "'use client'\n\nimport { useCallback, useState } from 'react'\n\ntype UseSliderWithInputProps = {\n  minValue?: number\n  maxValue?: number\n  initialValue?: number[]\n  defaultValue?: number[]\n}\n\nexport function useSliderWithInput({\n  minValue = 0,\n  maxValue = 100,\n  initialValue = [minValue],\n  defaultValue = [minValue],\n}: UseSliderWithInputProps) {\n  const [sliderValue, setSliderValue] = useState(initialValue)\n  const [inputValues, setInputValues] = useState(initialValue.map((v) => v.toString()))\n\n  const showReset =\n    sliderValue.length === defaultValue.length &&\n    !sliderValue.every((value, index) => value === defaultValue[index])\n\n  const validateAndUpdateValue = useCallback(\n    (rawValue: string, index: number) => {\n      if (rawValue === '' || rawValue === '-') {\n        const newInputValues = [...inputValues]\n        newInputValues[index] = '0'\n        setInputValues(newInputValues)\n\n        const newSliderValues = [...sliderValue]\n        newSliderValues[index] = 0\n        setSliderValue(newSliderValues)\n        return\n      }\n\n      const numValue = parseFloat(rawValue)\n\n      if (isNaN(numValue)) {\n        const newInputValues = [...inputValues]\n        newInputValues[index] = sliderValue[index]!.toString()\n        setInputValues(newInputValues)\n        return\n      }\n\n      let clampedValue = Math.min(maxValue, Math.max(minValue, numValue))\n\n      if (sliderValue.length > 1) {\n        if (index === 0) {\n          clampedValue = Math.min(clampedValue, sliderValue[1]!)\n        } else {\n          clampedValue = Math.max(clampedValue, sliderValue[0]!)\n        }\n      }\n\n      const newSliderValues = [...sliderValue]\n      newSliderValues[index] = clampedValue\n      setSliderValue(newSliderValues)\n\n      const newInputValues = [...inputValues]\n      newInputValues[index] = clampedValue.toString()\n      setInputValues(newInputValues)\n    },\n    [sliderValue, inputValues, minValue, maxValue]\n  )\n\n  const handleInputChange = useCallback(\n    (e: React.ChangeEvent<HTMLInputElement>, index: number) => {\n      const newValue = e.target.value\n      if (newValue === '' || /^-?\\d*\\.?\\d*$/.test(newValue)) {\n        const newInputValues = [...inputValues]\n        newInputValues[index] = newValue\n        setInputValues(newInputValues)\n      }\n    },\n    [inputValues]\n  )\n\n  const handleSliderChange = useCallback((newValue: number[]) => {\n    setSliderValue(newValue)\n    setInputValues(newValue.map((v) => v.toString()))\n  }, [])\n\n  const resetToDefault = useCallback(() => {\n    setSliderValue(defaultValue)\n    setInputValues(defaultValue.map((v) => v.toString()))\n  }, [defaultValue])\n\n  return {\n    sliderValue,\n    inputValues,\n    validateAndUpdateValue,\n    handleInputChange,\n    handleSliderChange,\n    resetToDefault,\n    showReset,\n  }\n}\n"
        },
        {
          "path": "registry/default/components/slider/slider-16.vue",
          "target": "components/ui/slider-16.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\nimport { Slider } from '@timui/vue';\nimport { useSliderWithInput } from '@/registry/default/hooks/use-slider-with-input-vue';\n\nconst minValue = 0;\nconst maxValue = 100;\nconst initialValue = [25];\n\nconst {\n  sliderValue,\n  inputValues,\n  validateAndUpdateValue,\n  handleInputChange,\n  handleSliderChange,\n} = useSliderWithInput({ minValue, maxValue, initialValue });\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-3\">\n    <Label>Slider with input</Label>\n    <div class=\"flex items-center gap-4\">\n      <Slider\n        class=\"grow\"\n        :value=\"sliderValue\"\n        @update:modelValue=\"handleSliderChange\"\n        :min=\"minValue\"\n        :max=\"maxValue\"\n        aria-label=\"Slider with input\"\n      />\n      <Input\n        class=\"h-8 w-12 px-2 py-1\"\n        type=\"text\"\n        inputMode=\"decimal\"\n        :model-value=\"inputValues[0] ?? ''\"\n        @update:modelValue=\"(next) => handleInputChange(next, 0)\"\n        @blur=\"() => validateAndUpdateValue(inputValues[0] ?? '', 0)\"\n        @keydown.enter.prevent=\"validateAndUpdateValue(inputValues[0] ?? '', 0)\"\n        aria-label=\"Enter value\"\n      />\n    </div>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/slider/slider-16.html",
          "target": "components/ui/slider-16.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-3\"><Label>Slider with input</Label><div class=\"flex items-center gap-4\"><Slider class=\"grow\" value=\"${sliderValue}\" on-value-change=\"${handleSliderChange}\" min=\"${minValue}\" max=\"${maxValue}\" aria-label=\"Slider with input\" /><Input class=\"h-8 w-12 px-2 py-1\" type=\"text\" inputmode=\"decimal\" value=\"${inputValues[0]}\" onchange=\"${(e) => handleInputChange(e, 0)}\" onblur=\"${() => validateAndUpdateValue(inputValues[0], 0)}\" onkeydown=\"${(e) => {\n            if (e.key === 'Enter') {\n              validateAndUpdateValue(inputValues[0], 0)\n            }\n          }}\" aria-label=\"Enter value\" /></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/slider/slider-16.wxml",
          "target": "components/ui/slider-16/slider-16.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-3\"><label>Slider with input</label><view class=\"flex items-center gap-4\"><slider class=\"grow\" value=\"{{sliderValue}}\" bindchange=\"handleSliderChange\" min=\"{{minValue}}\" max=\"{{maxValue}}\" aria-label=\"Slider with input\" /><input class=\"h-8 w-12 px-2 py-1\" type=\"text\" inputmode=\"decimal\" value=\"{{inputValues[0]}}\" onchange=\"{{(e) => handleInputChange(e, 0)}}\" onblur=\"{{() => validateAndUpdateValue(inputValues[0], 0)}}\" onkeydown=\"{{(e) => {\n            if (e.key === 'Enter') {\n              validateAndUpdateValue(inputValues[0], 0)\n            }\n          }}}\" aria-label=\"Enter value\" /></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "slider",
          "label",
          "input",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "slider-16",
          "group": "slider",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "slider-16",
              "path": "registry/default/components/slider/slider-16.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "slider-16",
              "path": "registry/default/components/slider/slider-16.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "slider-16",
              "path": "registry/default/components/slider/slider-16.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "slider-16",
              "path": "registry/default/components/slider/slider-16.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "slider",
        "title": "Slider · Slider with input"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "slider"
      ]
    },
    {
      "name": "slider-17",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/slider.json"
      ],
      "files": [
        {
          "path": "registry/default/components/slider/slider-17.tsx",
          "type": "registry:component",
          "target": "components/ui/slider-17.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Label, Slider } from '@timui/react'\n\nexport default function Component() {\n  const [value, setValue] = useState([3])\n\n  const labels = ['Awful', 'Poor', 'Okay', 'Good', 'Amazing']\n\n  return (\n    <div className=\"space-y-3\">\n      <div className=\"flex items-center justify-between gap-2\">\n        <Label className=\"leading-6\">Rate your experience</Label>\n        <span className=\"text-sm font-medium\">{labels[value[0] - 1]}</span>\n      </div>\n      <div className=\"flex items-center gap-2\">\n        <span className=\"text-2xl\">😡</span>\n        <Slider\n          value={value}\n          onValueChange={setValue}\n          min={1}\n          max={5}\n          aria-label=\"Rate your experience\"\n        />\n        <span className=\"text-2xl\">😍</span>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/slider/slider-17.vue",
          "target": "components/ui/slider-17.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Label } from '@timui/vue';\nimport { Slider } from '@timui/vue';\n\n\n\nconst value = ref([3]);\n\n\nfunction setValue(next: typeof value.value | ((prev: typeof value.value) => typeof value.value)) {\n  value.value = typeof next === 'function'\n    ? (next as (prev: typeof value.value) => typeof value.value)(value.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <div class=\"space-y-3\"><div class=\"flex items-center justify-between gap-2\"><Label class=\"leading-6\">Rate your experience</Label><span class=\"text-sm font-medium\">{{ labels[value[0] - 1] }}</span></div><div class=\"flex items-center gap-2\"><span class=\"text-2xl\">😡</span><Slider :value=\"value\" @update:modelValue=\"setValue\" :min=\"1\" :max=\"5\" aria-label=\"Rate your experience\" /><span class=\"text-2xl\">😍</span></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/slider/slider-17.html",
          "target": "components/ui/slider-17.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-3\"><div class=\"flex items-center justify-between gap-2\"><Label class=\"leading-6\">Rate your experience</Label><span class=\"text-sm font-medium\">${labels[value[0] - 1]}</span></div><div class=\"flex items-center gap-2\"><span class=\"text-2xl\">😡</span><Slider value=\"${value}\" on-value-change=\"${setValue}\" min=\"${1}\" max=\"${5}\" aria-label=\"Rate your experience\" /><span class=\"text-2xl\">😍</span></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/slider/slider-17.wxml",
          "target": "components/ui/slider-17/slider-17.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-3\"><view class=\"flex items-center justify-between gap-2\"><label class=\"leading-6\">Rate your experience</label><text class=\"text-sm font-medium\">{{ labels[value[0] - 1] }}</text></view><view class=\"flex items-center gap-2\"><text class=\"text-2xl\">😡</text><slider value=\"{{value}}\" bindchange=\"setValue\" min=\"{{1}}\" max=\"{{5}}\" aria-label=\"Rate your experience\" /><text class=\"text-2xl\">😍</text></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "slider",
          "label",
          "vote",
          "rating",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "slider-17",
          "group": "slider",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "slider-17",
              "path": "registry/default/components/slider/slider-17.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "slider-17",
              "path": "registry/default/components/slider/slider-17.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "slider-17",
              "path": "registry/default/components/slider/slider-17.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "slider-17",
              "path": "registry/default/components/slider/slider-17.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "slider",
        "title": "Slider · Rate your experience"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "slider"
      ]
    },
    {
      "name": "slider-18",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/slider.json"
      ],
      "files": [
        {
          "path": "registry/default/components/slider/slider-18.tsx",
          "type": "registry:component",
          "target": "components/ui/slider-18.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Label, Slider } from '@timui/react'\n\nexport default function Component() {\n  const [value, setValue] = useState([3])\n\n  const emojis = ['😡', '🙁', '😐', '🙂', '😍']\n  const labels = ['Awful', 'Poor', 'Okay', 'Good', 'Amazing']\n\n  return (\n    <div className=\"*:not-first:mt-3\">\n      <Label>Rate your experience</Label>\n      <div className=\"flex items-center gap-2\">\n        <Slider\n          value={value}\n          onValueChange={setValue}\n          min={1}\n          max={5}\n          showTooltip\n          tooltipContent={(value) => labels[value - 1]}\n          aria-label=\"Rate your experience\"\n        />\n        <span className=\"text-2xl\">{emojis[value[0] - 1]}</span>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/slider/slider-18.vue",
          "target": "components/ui/slider-18.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Label } from '@timui/vue';\nimport { Slider } from '@timui/vue';\n\n\n\nconst value = ref([3]);\n\n\nfunction setValue(next: typeof value.value | ((prev: typeof value.value) => typeof value.value)) {\n  value.value = typeof next === 'function'\n    ? (next as (prev: typeof value.value) => typeof value.value)(value.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-3\"><Label>Rate your experience</Label><div class=\"flex items-center gap-2\"><Slider :value=\"value\" @update:modelValue=\"setValue\" :min=\"1\" :max=\"5\" showTooltip :tooltipContent=\"(value) => labels[value - 1]\" aria-label=\"Rate your experience\" /><span class=\"text-2xl\">{{ emojis[value[0] - 1] }}</span></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/slider/slider-18.html",
          "target": "components/ui/slider-18.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-3\"><Label>Rate your experience</Label><div class=\"flex items-center gap-2\"><Slider value=\"${value}\" on-value-change=\"${setValue}\" min=\"${1}\" max=\"${5}\" showtooltip tooltipcontent=\"${(value) => labels[value - 1]}\" aria-label=\"Rate your experience\" /><span class=\"text-2xl\">${emojis[value[0] - 1]}</span></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/slider/slider-18.wxml",
          "target": "components/ui/slider-18/slider-18.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-3\"><label>Rate your experience</label><view class=\"flex items-center gap-2\"><slider value=\"{{value}}\" bindchange=\"setValue\" min=\"{{1}}\" max=\"{{5}}\" showtooltip tooltipcontent=\"{{(value) => labels[value - 1]}}\" aria-label=\"Rate your experience\" /><text class=\"text-2xl\">{{ emojis[value[0] - 1] }}</text></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "slider",
          "label",
          "vote",
          "rating",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "slider-18",
          "group": "slider",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "slider-18",
              "path": "registry/default/components/slider/slider-18.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "slider-18",
              "path": "registry/default/components/slider/slider-18.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "slider-18",
              "path": "registry/default/components/slider/slider-18.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "slider-18",
              "path": "registry/default/components/slider/slider-18.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "slider",
        "title": "Slider · Rate your experience"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "slider"
      ]
    },
    {
      "name": "slider-19",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/slider.json"
      ],
      "files": [
        {
          "path": "registry/default/components/slider/slider-19.tsx",
          "type": "registry:component",
          "target": "components/ui/slider-19.tsx",
          "content": "'use client'\n\nimport { Input, Label, Slider } from '@timui/react'\n\nimport { useSliderWithInput } from '@/registry/default/hooks/use-slider-with-input'\n\nexport default function Component() {\n  const minValue = 0\n  const maxValue = 200\n  const initialValue = [50, 150]\n\n  const {\n    sliderValue,\n    inputValues,\n    validateAndUpdateValue,\n    handleInputChange,\n    handleSliderChange,\n  } = useSliderWithInput({ minValue, maxValue, initialValue })\n\n  return (\n    <div className=\"*:not-first:mt-3\">\n      <Label>Dual range slider with input</Label>\n      <div className=\"flex items-center gap-4\">\n        <Input\n          className=\"h-8 w-12 px-2 py-1\"\n          type=\"text\"\n          inputMode=\"decimal\"\n          value={inputValues[0]}\n          onChange={(e) => handleInputChange(e, 0)}\n          onBlur={() => validateAndUpdateValue(inputValues[0], 0)}\n          onKeyDown={(e) => {\n            if (e.key === 'Enter') {\n              validateAndUpdateValue(inputValues[0], 0)\n            }\n          }}\n          aria-label=\"Enter minimum value\"\n        />\n        <Slider\n          className=\"grow\"\n          value={sliderValue}\n          onValueChange={handleSliderChange}\n          min={minValue}\n          max={maxValue}\n          aria-label=\"Dual range slider with input\"\n        />\n        <Input\n          className=\"h-8 w-12 px-2 py-1\"\n          type=\"text\"\n          inputMode=\"decimal\"\n          value={inputValues[1]}\n          onChange={(e) => handleInputChange(e, 1)}\n          onBlur={() => validateAndUpdateValue(inputValues[1], 1)}\n          onKeyDown={(e) => {\n            if (e.key === 'Enter') {\n              validateAndUpdateValue(inputValues[1], 1)\n            }\n          }}\n          aria-label=\"Enter maximum value\"\n        />\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/hooks/use-slider-with-input.ts",
          "type": "registry:hook",
          "target": "components/ui/slider-19/use-slider-with-input.ts",
          "content": "'use client'\n\nimport { useCallback, useState } from 'react'\n\ntype UseSliderWithInputProps = {\n  minValue?: number\n  maxValue?: number\n  initialValue?: number[]\n  defaultValue?: number[]\n}\n\nexport function useSliderWithInput({\n  minValue = 0,\n  maxValue = 100,\n  initialValue = [minValue],\n  defaultValue = [minValue],\n}: UseSliderWithInputProps) {\n  const [sliderValue, setSliderValue] = useState(initialValue)\n  const [inputValues, setInputValues] = useState(initialValue.map((v) => v.toString()))\n\n  const showReset =\n    sliderValue.length === defaultValue.length &&\n    !sliderValue.every((value, index) => value === defaultValue[index])\n\n  const validateAndUpdateValue = useCallback(\n    (rawValue: string, index: number) => {\n      if (rawValue === '' || rawValue === '-') {\n        const newInputValues = [...inputValues]\n        newInputValues[index] = '0'\n        setInputValues(newInputValues)\n\n        const newSliderValues = [...sliderValue]\n        newSliderValues[index] = 0\n        setSliderValue(newSliderValues)\n        return\n      }\n\n      const numValue = parseFloat(rawValue)\n\n      if (isNaN(numValue)) {\n        const newInputValues = [...inputValues]\n        newInputValues[index] = sliderValue[index]!.toString()\n        setInputValues(newInputValues)\n        return\n      }\n\n      let clampedValue = Math.min(maxValue, Math.max(minValue, numValue))\n\n      if (sliderValue.length > 1) {\n        if (index === 0) {\n          clampedValue = Math.min(clampedValue, sliderValue[1]!)\n        } else {\n          clampedValue = Math.max(clampedValue, sliderValue[0]!)\n        }\n      }\n\n      const newSliderValues = [...sliderValue]\n      newSliderValues[index] = clampedValue\n      setSliderValue(newSliderValues)\n\n      const newInputValues = [...inputValues]\n      newInputValues[index] = clampedValue.toString()\n      setInputValues(newInputValues)\n    },\n    [sliderValue, inputValues, minValue, maxValue]\n  )\n\n  const handleInputChange = useCallback(\n    (e: React.ChangeEvent<HTMLInputElement>, index: number) => {\n      const newValue = e.target.value\n      if (newValue === '' || /^-?\\d*\\.?\\d*$/.test(newValue)) {\n        const newInputValues = [...inputValues]\n        newInputValues[index] = newValue\n        setInputValues(newInputValues)\n      }\n    },\n    [inputValues]\n  )\n\n  const handleSliderChange = useCallback((newValue: number[]) => {\n    setSliderValue(newValue)\n    setInputValues(newValue.map((v) => v.toString()))\n  }, [])\n\n  const resetToDefault = useCallback(() => {\n    setSliderValue(defaultValue)\n    setInputValues(defaultValue.map((v) => v.toString()))\n  }, [defaultValue])\n\n  return {\n    sliderValue,\n    inputValues,\n    validateAndUpdateValue,\n    handleInputChange,\n    handleSliderChange,\n    resetToDefault,\n    showReset,\n  }\n}\n"
        },
        {
          "path": "registry/default/components/slider/slider-19.vue",
          "target": "components/ui/slider-19.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\nimport { Slider } from '@timui/vue';\nimport { useSliderWithInput } from '@/registry/default/hooks/use-slider-with-input-vue';\n\nconst minValue = 0;\nconst maxValue = 200;\nconst initialValue = [50, 150];\n\nconst {\n  sliderValue,\n  inputValues,\n  validateAndUpdateValue,\n  handleInputChange,\n  handleSliderChange,\n} = useSliderWithInput({ minValue, maxValue, initialValue });\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-3\">\n    <Label>Dual range slider with input</Label>\n    <div class=\"flex items-center gap-4\">\n      <Input\n        class=\"h-8 w-12 px-2 py-1\"\n        type=\"text\"\n        inputMode=\"decimal\"\n        :model-value=\"inputValues[0] ?? ''\"\n        @update:modelValue=\"(next) => handleInputChange(next, 0)\"\n        @blur=\"() => validateAndUpdateValue(inputValues[0] ?? '', 0)\"\n        @keydown.enter.prevent=\"validateAndUpdateValue(inputValues[0] ?? '', 0)\"\n        aria-label=\"Enter minimum value\"\n      />\n      <Slider\n        class=\"grow\"\n        :value=\"sliderValue\"\n        @update:modelValue=\"handleSliderChange\"\n        :min=\"minValue\"\n        :max=\"maxValue\"\n        aria-label=\"Dual range slider with input\"\n      />\n      <Input\n        class=\"h-8 w-12 px-2 py-1\"\n        type=\"text\"\n        inputMode=\"decimal\"\n        :model-value=\"inputValues[1] ?? ''\"\n        @update:modelValue=\"(next) => handleInputChange(next, 1)\"\n        @blur=\"() => validateAndUpdateValue(inputValues[1] ?? '', 1)\"\n        @keydown.enter.prevent=\"validateAndUpdateValue(inputValues[1] ?? '', 1)\"\n        aria-label=\"Enter maximum value\"\n      />\n    </div>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/slider/slider-19.html",
          "target": "components/ui/slider-19.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-3\"><Label>Dual range slider with input</Label><div class=\"flex items-center gap-4\"><Input class=\"h-8 w-12 px-2 py-1\" type=\"text\" inputmode=\"decimal\" value=\"${inputValues[0]}\" onchange=\"${(e) => handleInputChange(e, 0)}\" onblur=\"${() => validateAndUpdateValue(inputValues[0], 0)}\" onkeydown=\"${(e) => {\n            if (e.key === 'Enter') {\n              validateAndUpdateValue(inputValues[0], 0)\n            }\n          }}\" aria-label=\"Enter minimum value\" /><Slider class=\"grow\" value=\"${sliderValue}\" on-value-change=\"${handleSliderChange}\" min=\"${minValue}\" max=\"${maxValue}\" aria-label=\"Dual range slider with input\" /><Input class=\"h-8 w-12 px-2 py-1\" type=\"text\" inputmode=\"decimal\" value=\"${inputValues[1]}\" onchange=\"${(e) => handleInputChange(e, 1)}\" onblur=\"${() => validateAndUpdateValue(inputValues[1], 1)}\" onkeydown=\"${(e) => {\n            if (e.key === 'Enter') {\n              validateAndUpdateValue(inputValues[1], 1)\n            }\n          }}\" aria-label=\"Enter maximum value\" /></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/slider/slider-19.wxml",
          "target": "components/ui/slider-19/slider-19.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-3\"><label>Dual range slider with input</label><view class=\"flex items-center gap-4\"><input class=\"h-8 w-12 px-2 py-1\" type=\"text\" inputmode=\"decimal\" value=\"{{inputValues[0]}}\" onchange=\"{{(e) => handleInputChange(e, 0)}}\" onblur=\"{{() => validateAndUpdateValue(inputValues[0], 0)}}\" onkeydown=\"{{(e) => {\n            if (e.key === 'Enter') {\n              validateAndUpdateValue(inputValues[0], 0)\n            }\n          }}}\" aria-label=\"Enter minimum value\" /><slider class=\"grow\" value=\"{{sliderValue}}\" bindchange=\"handleSliderChange\" min=\"{{minValue}}\" max=\"{{maxValue}}\" aria-label=\"Dual range slider with input\" /><input class=\"h-8 w-12 px-2 py-1\" type=\"text\" inputmode=\"decimal\" value=\"{{inputValues[1]}}\" onchange=\"{{(e) => handleInputChange(e, 1)}}\" onblur=\"{{() => validateAndUpdateValue(inputValues[1], 1)}}\" onkeydown=\"{{(e) => {\n            if (e.key === 'Enter') {\n              validateAndUpdateValue(inputValues[1], 1)\n            }\n          }}}\" aria-label=\"Enter maximum value\" /></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "slider",
          "range slider",
          "label",
          "input",
          "range",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "slider-19",
          "group": "slider",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "slider-19",
              "path": "registry/default/components/slider/slider-19.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "slider-19",
              "path": "registry/default/components/slider/slider-19.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "slider-19",
              "path": "registry/default/components/slider/slider-19.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "slider-19",
              "path": "registry/default/components/slider/slider-19.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "slider",
        "title": "Slider · Enter minimum value"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "slider"
      ]
    },
    {
      "name": "slider-20",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/slider.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/slider/slider-20.tsx",
          "type": "registry:component",
          "target": "components/ui/slider-20.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Button, Label, Slider } from '@timui/react'\nimport { MinusIcon, PlusIcon } from 'lucide-react'\n\nexport default function Component() {\n  const minValue = 0\n  const maxValue = 200\n  const steps = 5\n  const [value, setValue] = useState([100])\n\n  const decreaseValue = () => setValue((prev) => [Math.max(minValue, prev[0] - steps)])\n  const increaseValue = () => setValue((prev) => [Math.min(maxValue, prev[0] + steps)])\n\n  return (\n    <div className=\"*:not-first:mt-3\">\n      <Label className=\"tabular-nums\">{value[0]} credits/mo</Label>\n      <div className=\"flex items-center gap-4\">\n        <div>\n          <Button\n            variant=\"outline\"\n            size=\"icon\"\n            className=\"size-8\"\n            aria-label=\"Decrease value\"\n            onClick={decreaseValue}\n            disabled={value[0] === 0}\n          >\n            <MinusIcon size={16} aria-hidden=\"true\" />\n          </Button>\n        </div>\n        <Slider\n          className=\"grow\"\n          value={value}\n          onValueChange={setValue}\n          min={minValue}\n          max={maxValue}\n          step={steps}\n          aria-label=\"Dual range slider with buttons\"\n        />\n        <div>\n          <Button\n            variant=\"outline\"\n            size=\"icon\"\n            className=\"size-8\"\n            aria-label=\"Increase value\"\n            onClick={increaseValue}\n            disabled={value[0] === 200}\n          >\n            <PlusIcon size={16} aria-hidden=\"true\" />\n          </Button>\n        </div>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/slider/slider-20.vue",
          "target": "components/ui/slider-20.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { MinusIcon, PlusIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { Label } from '@timui/vue';\nimport { Slider } from '@timui/vue';\n\n\n\nconst value = ref([100]);\n\n\nfunction setValue(next: typeof value.value | ((prev: typeof value.value) => typeof value.value)) {\n  value.value = typeof next === 'function'\n    ? (next as (prev: typeof value.value) => typeof value.value)(value.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-3\"><Label class=\"tabular-nums\">{{ value[0] }}credits/mo</Label><div class=\"flex items-center gap-4\"><div><Button variant=\"outline\" size=\"icon\" class=\"size-8\" aria-label=\"Decrease value\" @click=\"decreaseValue\" :disabled=\"value[0] === 0\"><MinusIcon :size=\"16\" aria-hidden=\"true\" /></Button></div><Slider class=\"grow\" :value=\"value\" @update:modelValue=\"setValue\" :min=\"minValue\" :max=\"maxValue\" :step=\"steps\" aria-label=\"Dual range slider with buttons\" /><div><Button variant=\"outline\" size=\"icon\" class=\"size-8\" aria-label=\"Increase value\" @click=\"increaseValue\" :disabled=\"value[0] === 200\"><PlusIcon :size=\"16\" aria-hidden=\"true\" /></Button></div></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/slider/slider-20.html",
          "target": "components/ui/slider-20.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-3\"><Label class=\"tabular-nums\">${value[0]}credits/mo</Label><div class=\"flex items-center gap-4\"><div><Button variant=\"outline\" size=\"icon\" class=\"size-8\" aria-label=\"Decrease value\" on-click=\"${decreaseValue}\" disabled=\"${value[0] === 0}\"><MinusIcon size=\"${16}\" aria-hidden=\"true\" /></Button></div><Slider class=\"grow\" value=\"${value}\" on-value-change=\"${setValue}\" min=\"${minValue}\" max=\"${maxValue}\" step=\"${steps}\" aria-label=\"Dual range slider with buttons\" /><div><Button variant=\"outline\" size=\"icon\" class=\"size-8\" aria-label=\"Increase value\" on-click=\"${increaseValue}\" disabled=\"${value[0] === 200}\"><PlusIcon size=\"${16}\" aria-hidden=\"true\" /></Button></div></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/slider/slider-20.wxml",
          "target": "components/ui/slider-20/slider-20.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-3\"><label class=\"tabular-nums\">{{ value[0] }}credits/mo</label><view class=\"flex items-center gap-4\"><view><button variant=\"outline\" size=\"icon\" class=\"size-8\" aria-label=\"Decrease value\" bindtap=\"decreaseValue\" disabled=\"{{value[0] === 0}}\"><minusicon size=\"{{16}}\" aria-hidden=\"true\" /></button></view><slider class=\"grow\" value=\"{{value}}\" bindchange=\"setValue\" min=\"{{minValue}}\" max=\"{{maxValue}}\" step=\"{{steps}}\" aria-label=\"Dual range slider with buttons\" /><view><button variant=\"outline\" size=\"icon\" class=\"size-8\" aria-label=\"Increase value\" bindtap=\"increaseValue\" disabled=\"{{value[0] === 200}}\"><plusicon size=\"{{16}}\" aria-hidden=\"true\" /></button></view></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "slider",
          "label",
          "button",
          "pricing",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "slider-20",
          "group": "slider",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "slider-20",
              "path": "registry/default/components/slider/slider-20.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "slider-20",
              "path": "registry/default/components/slider/slider-20.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "slider-20",
              "path": "registry/default/components/slider/slider-20.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "slider-20",
              "path": "registry/default/components/slider/slider-20.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "slider",
        "title": "Slider · Decrease value"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "slider"
      ]
    },
    {
      "name": "slider-21",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/slider.json"
      ],
      "files": [
        {
          "path": "registry/default/components/slider/slider-21.tsx",
          "type": "registry:component",
          "target": "components/ui/slider-21.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Button, Label, Slider } from '@timui/react'\n\nexport default function Component() {\n  const min_price = 5\n  const max_price = 1240\n  const [value, setValue] = useState([min_price, max_price])\n\n  const formatPrice = (price: number) => {\n    return price === max_price ? `$${price.toLocaleString()}+` : `$${price.toLocaleString()}`\n  }\n\n  return (\n    <div className=\"*:not-first:mt-3\">\n      <Label className=\"tabular-nums\">\n        From {formatPrice(value[0])} to {formatPrice(value[1])}\n      </Label>\n      <div className=\"flex items-center gap-4\">\n        <Slider\n          value={value}\n          onValueChange={setValue}\n          min={min_price}\n          max={max_price}\n          aria-label=\"Price range slider\"\n        />\n        <Button variant=\"outline\">Go</Button>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/slider/slider-21.vue",
          "target": "components/ui/slider-21.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Button } from '@timui/vue';\nimport { Label } from '@timui/vue';\nimport { Slider } from '@timui/vue';\n\n\n\nconst value = ref([min_price, max_price]);\n\n\nfunction setValue(next: typeof value.value | ((prev: typeof value.value) => typeof value.value)) {\n  value.value = typeof next === 'function'\n    ? (next as (prev: typeof value.value) => typeof value.value)(value.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-3\"><Label class=\"tabular-nums\">From {{ formatPrice(value[0]) }}to {{ formatPrice(value[1]) }}</Label><div class=\"flex items-center gap-4\"><Slider :value=\"value\" @update:modelValue=\"setValue\" :min=\"min_price\" :max=\"max_price\" aria-label=\"Price range slider\" /><Button variant=\"outline\">Go</Button></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/slider/slider-21.html",
          "target": "components/ui/slider-21.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-3\"><Label class=\"tabular-nums\">From ${formatPrice(value[0])}to ${formatPrice(value[1])}</Label><div class=\"flex items-center gap-4\"><Slider value=\"${value}\" on-value-change=\"${setValue}\" min=\"${min_price}\" max=\"${max_price}\" aria-label=\"Price range slider\" /><Button variant=\"outline\">Go</Button></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/slider/slider-21.wxml",
          "target": "components/ui/slider-21/slider-21.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-3\"><label class=\"tabular-nums\">From {{ formatPrice(value[0]) }}to {{ formatPrice(value[1]) }}</label><view class=\"flex items-center gap-4\"><slider value=\"{{value}}\" bindchange=\"setValue\" min=\"{{min_price}}\" max=\"{{max_price}}\" aria-label=\"Price range slider\" /><button variant=\"outline\">Go</button></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "slider",
          "range slider",
          "label",
          "button",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "slider-21",
          "group": "slider",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "slider-21",
              "path": "registry/default/components/slider/slider-21.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "slider-21",
              "path": "registry/default/components/slider/slider-21.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "slider-21",
              "path": "registry/default/components/slider/slider-21.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "slider-21",
              "path": "registry/default/components/slider/slider-21.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "slider",
        "title": "Slider · Price range slider"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "slider"
      ]
    },
    {
      "name": "slider-22",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/slider.json"
      ],
      "files": [
        {
          "path": "registry/default/components/slider/slider-22.tsx",
          "type": "registry:component",
          "target": "components/ui/slider-22.tsx",
          "content": "import { Label, Slider } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"*:not-first:mt-4\">\n      <Label>Vertical slider</Label>\n      <div className=\"flex h-40 justify-center\">\n        <Slider defaultValue={[5]} max={10} orientation=\"vertical\" aria-label=\"Vertical slider\" />\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/slider/slider-22.vue",
          "target": "components/ui/slider-22.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Slider } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-4\"><Label>Vertical slider</Label><div class=\"flex h-40 justify-center\"><Slider :default-value=\"[5]\" :max=\"10\" orientation=\"vertical\" aria-label=\"Vertical slider\" /></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/slider/slider-22.html",
          "target": "components/ui/slider-22.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-4\"><Label>Vertical slider</Label><div class=\"flex h-40 justify-center\"><Slider default-value=\"${[5]}\" max=\"${10}\" orientation=\"vertical\" aria-label=\"Vertical slider\" /></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/slider/slider-22.wxml",
          "target": "components/ui/slider-22/slider-22.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-4\"><label>Vertical slider</label><view class=\"flex h-40 justify-center\"><slider default-value=\"{{[5]}}\" max=\"{{10}}\" orientation=\"vertical\" aria-label=\"Vertical slider\" /></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "slider",
          "vertical slider",
          "label",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "slider-22",
          "group": "slider",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "slider-22",
              "path": "registry/default/components/slider/slider-22.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "slider-22",
              "path": "registry/default/components/slider/slider-22.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "slider-22",
              "path": "registry/default/components/slider/slider-22.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "slider-22",
              "path": "registry/default/components/slider/slider-22.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "slider",
        "title": "Slider · Vertical slider"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "slider"
      ]
    },
    {
      "name": "slider-23",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/slider.json",
        "https://ui.timkit.cn/r/input.json"
      ],
      "files": [
        {
          "path": "registry/default/components/slider/slider-23.tsx",
          "type": "registry:component",
          "target": "components/ui/slider-23.tsx",
          "content": "'use client'\n\nimport { Input, Label, Slider } from '@timui/react'\n\nimport { useSliderWithInput } from '@/registry/default/hooks/use-slider-with-input'\n\nexport default function Component() {\n  const minValue = 0\n  const maxValue = 100\n  const initialValue = [25]\n\n  const {\n    sliderValue,\n    inputValues,\n    validateAndUpdateValue,\n    handleInputChange,\n    handleSliderChange,\n  } = useSliderWithInput({ minValue, maxValue, initialValue })\n\n  return (\n    <div className=\"*:not-first:mt-4\">\n      <Label>Vertical slider with input</Label>\n      <div className=\"flex h-40 flex-col items-center justify-center gap-4\">\n        <Slider\n          className=\"data-[orientation=vertical]:min-h-0\"\n          value={sliderValue}\n          onValueChange={handleSliderChange}\n          min={minValue}\n          max={maxValue}\n          orientation=\"vertical\"\n          aria-label=\"Slider with input\"\n        />\n        <Input\n          className=\"h-8 w-12 px-2 py-1\"\n          type=\"text\"\n          inputMode=\"decimal\"\n          value={inputValues[0]}\n          onChange={(e) => handleInputChange(e, 0)}\n          onBlur={() => validateAndUpdateValue(inputValues[0], 0)}\n          onKeyDown={(e) => {\n            if (e.key === 'Enter') {\n              validateAndUpdateValue(inputValues[0], 0)\n            }\n          }}\n          aria-label=\"Enter value\"\n        />\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/hooks/use-slider-with-input.ts",
          "type": "registry:hook",
          "target": "components/ui/slider-23/use-slider-with-input.ts",
          "content": "'use client'\n\nimport { useCallback, useState } from 'react'\n\ntype UseSliderWithInputProps = {\n  minValue?: number\n  maxValue?: number\n  initialValue?: number[]\n  defaultValue?: number[]\n}\n\nexport function useSliderWithInput({\n  minValue = 0,\n  maxValue = 100,\n  initialValue = [minValue],\n  defaultValue = [minValue],\n}: UseSliderWithInputProps) {\n  const [sliderValue, setSliderValue] = useState(initialValue)\n  const [inputValues, setInputValues] = useState(initialValue.map((v) => v.toString()))\n\n  const showReset =\n    sliderValue.length === defaultValue.length &&\n    !sliderValue.every((value, index) => value === defaultValue[index])\n\n  const validateAndUpdateValue = useCallback(\n    (rawValue: string, index: number) => {\n      if (rawValue === '' || rawValue === '-') {\n        const newInputValues = [...inputValues]\n        newInputValues[index] = '0'\n        setInputValues(newInputValues)\n\n        const newSliderValues = [...sliderValue]\n        newSliderValues[index] = 0\n        setSliderValue(newSliderValues)\n        return\n      }\n\n      const numValue = parseFloat(rawValue)\n\n      if (isNaN(numValue)) {\n        const newInputValues = [...inputValues]\n        newInputValues[index] = sliderValue[index]!.toString()\n        setInputValues(newInputValues)\n        return\n      }\n\n      let clampedValue = Math.min(maxValue, Math.max(minValue, numValue))\n\n      if (sliderValue.length > 1) {\n        if (index === 0) {\n          clampedValue = Math.min(clampedValue, sliderValue[1]!)\n        } else {\n          clampedValue = Math.max(clampedValue, sliderValue[0]!)\n        }\n      }\n\n      const newSliderValues = [...sliderValue]\n      newSliderValues[index] = clampedValue\n      setSliderValue(newSliderValues)\n\n      const newInputValues = [...inputValues]\n      newInputValues[index] = clampedValue.toString()\n      setInputValues(newInputValues)\n    },\n    [sliderValue, inputValues, minValue, maxValue]\n  )\n\n  const handleInputChange = useCallback(\n    (e: React.ChangeEvent<HTMLInputElement>, index: number) => {\n      const newValue = e.target.value\n      if (newValue === '' || /^-?\\d*\\.?\\d*$/.test(newValue)) {\n        const newInputValues = [...inputValues]\n        newInputValues[index] = newValue\n        setInputValues(newInputValues)\n      }\n    },\n    [inputValues]\n  )\n\n  const handleSliderChange = useCallback((newValue: number[]) => {\n    setSliderValue(newValue)\n    setInputValues(newValue.map((v) => v.toString()))\n  }, [])\n\n  const resetToDefault = useCallback(() => {\n    setSliderValue(defaultValue)\n    setInputValues(defaultValue.map((v) => v.toString()))\n  }, [defaultValue])\n\n  return {\n    sliderValue,\n    inputValues,\n    validateAndUpdateValue,\n    handleInputChange,\n    handleSliderChange,\n    resetToDefault,\n    showReset,\n  }\n}\n"
        },
        {
          "path": "registry/default/components/slider/slider-23.vue",
          "target": "components/ui/slider-23.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\nimport { Slider } from '@timui/vue';\nimport { useSliderWithInput } from '@/registry/default/hooks/use-slider-with-input-vue';\n\nconst minValue = 0;\nconst maxValue = 100;\nconst initialValue = [25];\n\nconst {\n  sliderValue,\n  inputValues,\n  validateAndUpdateValue,\n  handleInputChange,\n  handleSliderChange,\n} = useSliderWithInput({ minValue, maxValue, initialValue });\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-4\">\n    <Label>Vertical slider with input</Label>\n    <div class=\"flex h-40 flex-col items-center justify-center gap-4\">\n      <Slider\n        class=\"data-[orientation=vertical]:min-h-0\"\n        :value=\"sliderValue\"\n        @update:modelValue=\"handleSliderChange\"\n        :min=\"minValue\"\n        :max=\"maxValue\"\n        orientation=\"vertical\"\n        aria-label=\"Slider with input\"\n      />\n      <Input\n        class=\"h-8 w-12 px-2 py-1\"\n        type=\"text\"\n        inputMode=\"decimal\"\n        :model-value=\"inputValues[0] ?? ''\"\n        @update:modelValue=\"(next) => handleInputChange(next, 0)\"\n        @blur=\"() => validateAndUpdateValue(inputValues[0] ?? '', 0)\"\n        @keydown.enter.prevent=\"validateAndUpdateValue(inputValues[0] ?? '', 0)\"\n        aria-label=\"Enter value\"\n      />\n    </div>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/slider/slider-23.html",
          "target": "components/ui/slider-23.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-4\"><Label>Vertical slider with input</Label><div class=\"flex h-40 flex-col items-center justify-center gap-4\"><Slider class=\"data-[orientation=vertical]:min-h-0\" value=\"${sliderValue}\" on-value-change=\"${handleSliderChange}\" min=\"${minValue}\" max=\"${maxValue}\" orientation=\"vertical\" aria-label=\"Slider with input\" /><Input class=\"h-8 w-12 px-2 py-1\" type=\"text\" inputmode=\"decimal\" value=\"${inputValues[0]}\" onchange=\"${(e) => handleInputChange(e, 0)}\" onblur=\"${() => validateAndUpdateValue(inputValues[0], 0)}\" onkeydown=\"${(e) => {\n            if (e.key === 'Enter') {\n              validateAndUpdateValue(inputValues[0], 0)\n            }\n          }}\" aria-label=\"Enter value\" /></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/slider/slider-23.wxml",
          "target": "components/ui/slider-23/slider-23.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-4\"><label>Vertical slider with input</label><view class=\"flex h-40 flex-col items-center justify-center gap-4\"><slider class=\"data-[orientation=vertical]:min-h-0\" value=\"{{sliderValue}}\" bindchange=\"handleSliderChange\" min=\"{{minValue}}\" max=\"{{maxValue}}\" orientation=\"vertical\" aria-label=\"Slider with input\" /><input class=\"h-8 w-12 px-2 py-1\" type=\"text\" inputmode=\"decimal\" value=\"{{inputValues[0]}}\" onchange=\"{{(e) => handleInputChange(e, 0)}}\" onblur=\"{{() => validateAndUpdateValue(inputValues[0], 0)}}\" onkeydown=\"{{(e) => {\n            if (e.key === 'Enter') {\n              validateAndUpdateValue(inputValues[0], 0)\n            }\n          }}}\" aria-label=\"Enter value\" /></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "slider",
          "vertical slider",
          "label",
          "input",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "slider-23",
          "group": "slider",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "slider-23",
              "path": "registry/default/components/slider/slider-23.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "slider-23",
              "path": "registry/default/components/slider/slider-23.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "slider-23",
              "path": "registry/default/components/slider/slider-23.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "slider-23",
              "path": "registry/default/components/slider/slider-23.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "slider",
        "title": "Slider · Slider with input"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "slider"
      ]
    },
    {
      "name": "slider-24",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/slider.json"
      ],
      "files": [
        {
          "path": "registry/default/components/slider/slider-24.tsx",
          "type": "registry:component",
          "target": "components/ui/slider-24.tsx",
          "content": "import { Label, Slider } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"*:not-first:mt-4\">\n      <Label>Vertical dual range slider and tooltip</Label>\n      <div className=\"flex h-40 justify-center\">\n        <Slider\n          defaultValue={[2, 7]}\n          max={10}\n          orientation=\"vertical\"\n          aria-label=\"Vertical slider\"\n          showTooltip\n        />\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/slider/slider-24.vue",
          "target": "components/ui/slider-24.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Slider } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-4\"><Label>Vertical dual range slider and tooltip</Label><div class=\"flex h-40 justify-center\"><Slider :default-value=\"[2, 7]\" :max=\"10\" orientation=\"vertical\" aria-label=\"Vertical slider\" showTooltip /></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/slider/slider-24.html",
          "target": "components/ui/slider-24.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-4\"><Label>Vertical dual range slider and tooltip</Label><div class=\"flex h-40 justify-center\"><Slider default-value=\"${[2, 7]}\" max=\"${10}\" orientation=\"vertical\" aria-label=\"Vertical slider\" showtooltip /></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/slider/slider-24.wxml",
          "target": "components/ui/slider-24/slider-24.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-4\"><label>Vertical dual range slider and tooltip</label><view class=\"flex h-40 justify-center\"><slider default-value=\"{{[2, 7]}}\" max=\"{{10}}\" orientation=\"vertical\" aria-label=\"Vertical slider\" showtooltip /></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "slider",
          "vertical slider",
          "range slider",
          "label",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "slider-24",
          "group": "slider",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "slider-24",
              "path": "registry/default/components/slider/slider-24.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "slider-24",
              "path": "registry/default/components/slider/slider-24.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "slider-24",
              "path": "registry/default/components/slider/slider-24.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "slider-24",
              "path": "registry/default/components/slider/slider-24.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "slider",
        "title": "Slider · Vertical slider"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "slider"
      ]
    },
    {
      "name": "slider-25",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/slider.json",
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/slider/slider-25.tsx",
          "type": "registry:component",
          "target": "components/ui/slider-25.tsx",
          "content": "'use client'\n\nimport React, { useRef } from 'react'\nimport { Button, Input, Label, Slider } from '@timui/react'\nimport { RotateCcwIcon } from 'lucide-react'\n\nimport { useSliderWithInput } from '@/registry/default/hooks/use-slider-with-input'\n\nexport default function Component() {\n  // Create refs to store reset functions\n  const resetFunctionsRef = useRef<(() => void)[]>([])\n\n  // Function to reset all sliders to default\n  const resetAll = () => {\n    resetFunctionsRef.current.forEach((resetFn) => resetFn())\n  }\n\n  // Function to register reset functions\n  const registerResetFunction = (resetFn: () => void, index: number) => {\n    resetFunctionsRef.current[index] = resetFn\n  }\n\n  return (\n    <div className=\"space-y-4\">\n      <legend className=\"text-foreground text-sm font-medium\">Object position</legend>\n      <div className=\"space-y-2\">\n        <SliderWithInput\n          minValue={-10}\n          maxValue={10}\n          initialValue={[-2]}\n          defaultValue={[0]}\n          label=\"X\"\n          onRegisterReset={(resetFn) => registerResetFunction(resetFn, 0)}\n        />\n        <SliderWithInput\n          minValue={-10}\n          maxValue={10}\n          initialValue={[4]}\n          defaultValue={[0]}\n          label=\"Y\"\n          onRegisterReset={(resetFn) => registerResetFunction(resetFn, 1)}\n        />\n        <SliderWithInput\n          minValue={-10}\n          maxValue={10}\n          initialValue={[2]}\n          defaultValue={[0]}\n          label=\"Z\"\n          onRegisterReset={(resetFn) => registerResetFunction(resetFn, 2)}\n        />\n      </div>\n      <Button className=\"w-full\" variant=\"outline\" onClick={resetAll}>\n        <RotateCcwIcon className=\"-ms-1 opacity-60\" size={16} aria-hidden=\"true\" />\n        Reset\n      </Button>\n    </div>\n  )\n}\n\nfunction SliderWithInput({\n  minValue,\n  maxValue,\n  initialValue,\n  defaultValue,\n  label,\n  onRegisterReset,\n}: {\n  minValue: number\n  maxValue: number\n  initialValue: number[]\n  defaultValue: number[]\n  label: string\n  onRegisterReset: (resetFn: () => void) => void\n}) {\n  const {\n    sliderValue,\n    inputValues,\n    validateAndUpdateValue,\n    handleInputChange,\n    handleSliderChange,\n    resetToDefault,\n  } = useSliderWithInput({ minValue, maxValue, initialValue, defaultValue })\n\n  // Register the reset function when the component mounts\n  React.useEffect(() => {\n    onRegisterReset(resetToDefault)\n  }, [onRegisterReset, resetToDefault])\n\n  return (\n    <div className=\"flex items-center gap-2\">\n      <Label className=\"text-muted-foreground text-xs\">{label}</Label>\n      <Slider\n        className=\"grow [&>:last-child>span]:rounded\"\n        value={sliderValue}\n        onValueChange={handleSliderChange}\n        min={minValue}\n        max={maxValue}\n        aria-label={label}\n      />\n      <Input\n        className=\"h-8 w-12 px-2 py-1\"\n        type=\"text\"\n        inputMode=\"decimal\"\n        value={inputValues[0]}\n        onChange={(e) => handleInputChange(e, 0)}\n        onBlur={() => validateAndUpdateValue(inputValues[0], 0)}\n        onKeyDown={(e) => {\n          if (e.key === 'Enter') {\n            validateAndUpdateValue(inputValues[0], 0)\n          }\n        }}\n        aria-label=\"Enter value\"\n      />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/hooks/use-slider-with-input.ts",
          "type": "registry:hook",
          "target": "components/ui/slider-25/use-slider-with-input.ts",
          "content": "'use client'\n\nimport { useCallback, useState } from 'react'\n\ntype UseSliderWithInputProps = {\n  minValue?: number\n  maxValue?: number\n  initialValue?: number[]\n  defaultValue?: number[]\n}\n\nexport function useSliderWithInput({\n  minValue = 0,\n  maxValue = 100,\n  initialValue = [minValue],\n  defaultValue = [minValue],\n}: UseSliderWithInputProps) {\n  const [sliderValue, setSliderValue] = useState(initialValue)\n  const [inputValues, setInputValues] = useState(initialValue.map((v) => v.toString()))\n\n  const showReset =\n    sliderValue.length === defaultValue.length &&\n    !sliderValue.every((value, index) => value === defaultValue[index])\n\n  const validateAndUpdateValue = useCallback(\n    (rawValue: string, index: number) => {\n      if (rawValue === '' || rawValue === '-') {\n        const newInputValues = [...inputValues]\n        newInputValues[index] = '0'\n        setInputValues(newInputValues)\n\n        const newSliderValues = [...sliderValue]\n        newSliderValues[index] = 0\n        setSliderValue(newSliderValues)\n        return\n      }\n\n      const numValue = parseFloat(rawValue)\n\n      if (isNaN(numValue)) {\n        const newInputValues = [...inputValues]\n        newInputValues[index] = sliderValue[index]!.toString()\n        setInputValues(newInputValues)\n        return\n      }\n\n      let clampedValue = Math.min(maxValue, Math.max(minValue, numValue))\n\n      if (sliderValue.length > 1) {\n        if (index === 0) {\n          clampedValue = Math.min(clampedValue, sliderValue[1]!)\n        } else {\n          clampedValue = Math.max(clampedValue, sliderValue[0]!)\n        }\n      }\n\n      const newSliderValues = [...sliderValue]\n      newSliderValues[index] = clampedValue\n      setSliderValue(newSliderValues)\n\n      const newInputValues = [...inputValues]\n      newInputValues[index] = clampedValue.toString()\n      setInputValues(newInputValues)\n    },\n    [sliderValue, inputValues, minValue, maxValue]\n  )\n\n  const handleInputChange = useCallback(\n    (e: React.ChangeEvent<HTMLInputElement>, index: number) => {\n      const newValue = e.target.value\n      if (newValue === '' || /^-?\\d*\\.?\\d*$/.test(newValue)) {\n        const newInputValues = [...inputValues]\n        newInputValues[index] = newValue\n        setInputValues(newInputValues)\n      }\n    },\n    [inputValues]\n  )\n\n  const handleSliderChange = useCallback((newValue: number[]) => {\n    setSliderValue(newValue)\n    setInputValues(newValue.map((v) => v.toString()))\n  }, [])\n\n  const resetToDefault = useCallback(() => {\n    setSliderValue(defaultValue)\n    setInputValues(defaultValue.map((v) => v.toString()))\n  }, [defaultValue])\n\n  return {\n    sliderValue,\n    inputValues,\n    validateAndUpdateValue,\n    handleInputChange,\n    handleSliderChange,\n    resetToDefault,\n    showReset,\n  }\n}\n"
        },
        {
          "path": "registry/default/components/slider/slider-25.vue",
          "target": "components/ui/slider-25.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { RotateCcwIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\nimport { Slider } from '@timui/vue';\nimport { useSliderWithInput } from '@/registry/default/hooks/use-slider-with-input-vue';\n\nconst minValue = -10;\nconst maxValue = 10;\nconst defaultValue = [0];\n\nconst {\n  sliderValue: xSliderValue,\n  inputValues: xInputValues,\n  validateAndUpdateValue: validateX,\n  handleInputChange: handleXInput,\n  handleSliderChange: handleXSlider,\n  resetToDefault: resetX,\n} = useSliderWithInput({ minValue, maxValue, initialValue: [-2], defaultValue });\n\nconst {\n  sliderValue: ySliderValue,\n  inputValues: yInputValues,\n  validateAndUpdateValue: validateY,\n  handleInputChange: handleYInput,\n  handleSliderChange: handleYSlider,\n  resetToDefault: resetY,\n} = useSliderWithInput({ minValue, maxValue, initialValue: [4], defaultValue });\n\nconst {\n  sliderValue: zSliderValue,\n  inputValues: zInputValues,\n  validateAndUpdateValue: validateZ,\n  handleInputChange: handleZInput,\n  handleSliderChange: handleZSlider,\n  resetToDefault: resetZ,\n} = useSliderWithInput({ minValue, maxValue, initialValue: [2], defaultValue });\n\nfunction resetAll() {\n  resetX();\n  resetY();\n  resetZ();\n}\n</script>\n\n<template>\n  <div class=\"space-y-4\">\n    <legend class=\"text-foreground text-sm font-medium\">Object position</legend>\n\n    <div class=\"space-y-2\">\n      <div class=\"flex items-center gap-2\">\n        <Label class=\"text-muted-foreground text-xs\">X</Label>\n        <Slider\n          class=\"grow [&>:last-child>span]:rounded\"\n          :value=\"xSliderValue\"\n          @update:modelValue=\"handleXSlider\"\n          :min=\"minValue\"\n          :max=\"maxValue\"\n          aria-label=\"X\"\n        />\n        <Input\n          class=\"h-8 w-12 px-2 py-1\"\n          type=\"text\"\n          inputMode=\"decimal\"\n          :model-value=\"xInputValues[0] ?? ''\"\n          @update:modelValue=\"(next) => handleXInput(next, 0)\"\n          @blur=\"() => validateX(xInputValues[0] ?? '', 0)\"\n          @keydown.enter.prevent=\"validateX(xInputValues[0] ?? '', 0)\"\n          aria-label=\"Enter X value\"\n        />\n      </div>\n\n      <div class=\"flex items-center gap-2\">\n        <Label class=\"text-muted-foreground text-xs\">Y</Label>\n        <Slider\n          class=\"grow [&>:last-child>span]:rounded\"\n          :value=\"ySliderValue\"\n          @update:modelValue=\"handleYSlider\"\n          :min=\"minValue\"\n          :max=\"maxValue\"\n          aria-label=\"Y\"\n        />\n        <Input\n          class=\"h-8 w-12 px-2 py-1\"\n          type=\"text\"\n          inputMode=\"decimal\"\n          :model-value=\"yInputValues[0] ?? ''\"\n          @update:modelValue=\"(next) => handleYInput(next, 0)\"\n          @blur=\"() => validateY(yInputValues[0] ?? '', 0)\"\n          @keydown.enter.prevent=\"validateY(yInputValues[0] ?? '', 0)\"\n          aria-label=\"Enter Y value\"\n        />\n      </div>\n\n      <div class=\"flex items-center gap-2\">\n        <Label class=\"text-muted-foreground text-xs\">Z</Label>\n        <Slider\n          class=\"grow [&>:last-child>span]:rounded\"\n          :value=\"zSliderValue\"\n          @update:modelValue=\"handleZSlider\"\n          :min=\"minValue\"\n          :max=\"maxValue\"\n          aria-label=\"Z\"\n        />\n        <Input\n          class=\"h-8 w-12 px-2 py-1\"\n          type=\"text\"\n          inputMode=\"decimal\"\n          :model-value=\"zInputValues[0] ?? ''\"\n          @update:modelValue=\"(next) => handleZInput(next, 0)\"\n          @blur=\"() => validateZ(zInputValues[0] ?? '', 0)\"\n          @keydown.enter.prevent=\"validateZ(zInputValues[0] ?? '', 0)\"\n          aria-label=\"Enter Z value\"\n        />\n      </div>\n    </div>\n\n    <Button class=\"w-full\" variant=\"outline\" @click=\"resetAll\">\n      <RotateCcwIcon class=\"-ms-1 opacity-60\" :size=\"16\" aria-hidden=\"true\" />\n      Reset\n    </Button>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/slider/slider-25.html",
          "target": "components/ui/slider-25.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-4\"><legend class=\"text-foreground text-sm font-medium\">Object position</legend><div class=\"space-y-2\"><SliderWithInput minvalue=\"${-10}\" maxvalue=\"${10}\" initialvalue=\"${[-2]}\" default-value=\"${[0]}\" label=\"X\" onregisterreset=\"${(resetFn) => registerResetFunction(resetFn, 0)}\" /><SliderWithInput minvalue=\"${-10}\" maxvalue=\"${10}\" initialvalue=\"${[4]}\" default-value=\"${[0]}\" label=\"Y\" onregisterreset=\"${(resetFn) => registerResetFunction(resetFn, 1)}\" /><SliderWithInput minvalue=\"${-10}\" maxvalue=\"${10}\" initialvalue=\"${[2]}\" default-value=\"${[0]}\" label=\"Z\" onregisterreset=\"${(resetFn) => registerResetFunction(resetFn, 2)}\" /></div><Button class=\"w-full\" variant=\"outline\" on-click=\"${resetAll}\"><RotateCcwIcon class=\"-ms-1 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Reset\n      </Button></div>\n</template>"
        },
        {
          "path": "registry/default/components/slider/slider-25.wxml",
          "target": "components/ui/slider-25/slider-25.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-4\"><legend class=\"text-foreground text-sm font-medium\">Object position</legend><view class=\"space-y-2\"><sliderwithinput minvalue=\"{{-10}}\" maxvalue=\"{{10}}\" initialvalue=\"{{[-2]}}\" default-value=\"{{[0]}}\" label=\"X\" onregisterreset=\"{{(resetFn) => registerResetFunction(resetFn, 0)}}\" /><sliderwithinput minvalue=\"{{-10}}\" maxvalue=\"{{10}}\" initialvalue=\"{{[4]}}\" default-value=\"{{[0]}}\" label=\"Y\" onregisterreset=\"{{(resetFn) => registerResetFunction(resetFn, 1)}}\" /><sliderwithinput minvalue=\"{{-10}}\" maxvalue=\"{{10}}\" initialvalue=\"{{[2]}}\" default-value=\"{{[0]}}\" label=\"Z\" onregisterreset=\"{{(resetFn) => registerResetFunction(resetFn, 2)}}\" /></view><button class=\"w-full\" variant=\"outline\" bindtap=\"resetAll\"><rotateccwicon class=\"-ms-1 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Reset\n      </button></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "slider",
          "label",
          "input",
          "button",
          "reset",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "slider-25",
          "group": "slider",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "slider-25",
              "path": "registry/default/components/slider/slider-25.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "slider-25",
              "path": "registry/default/components/slider/slider-25.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "slider-25",
              "path": "registry/default/components/slider/slider-25.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "slider-25",
              "path": "registry/default/components/slider/slider-25.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "slider",
        "title": "Slider · Enter value"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "slider"
      ]
    },
    {
      "name": "slider-26",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/slider.json",
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/button.json"
      ],
      "files": [
        {
          "path": "registry/default/components/slider/slider-26.tsx",
          "type": "registry:component",
          "target": "components/ui/slider-26.tsx",
          "content": "'use client'\n\nimport { useId } from 'react'\nimport { Button, Input, Label, Slider } from '@timui/react'\n\nimport { useSliderWithInput } from '@/registry/default/hooks/use-slider-with-input'\n\nconst items = [\n  { id: 1, price: 80 },\n  { id: 2, price: 95 },\n  { id: 3, price: 110 },\n  { id: 4, price: 125 },\n  { id: 5, price: 130 },\n  { id: 6, price: 140 },\n  { id: 7, price: 145 },\n  { id: 8, price: 150 },\n  { id: 9, price: 155 },\n  { id: 10, price: 165 },\n  { id: 11, price: 175 },\n  { id: 12, price: 185 },\n  { id: 13, price: 195 },\n  { id: 14, price: 205 },\n  { id: 15, price: 215 },\n  { id: 16, price: 225 },\n  { id: 17, price: 235 },\n  { id: 18, price: 245 },\n  { id: 19, price: 255 },\n  { id: 20, price: 260 },\n  { id: 21, price: 265 },\n  { id: 22, price: 270 },\n  { id: 23, price: 275 },\n  { id: 24, price: 280 },\n  { id: 25, price: 285 },\n  { id: 26, price: 290 },\n  { id: 27, price: 290 },\n  { id: 28, price: 295 },\n  { id: 29, price: 295 },\n  { id: 30, price: 295 },\n  { id: 31, price: 298 },\n  { id: 32, price: 299 },\n  { id: 33, price: 300 },\n  { id: 34, price: 305 },\n  { id: 35, price: 310 },\n  { id: 36, price: 315 },\n  { id: 37, price: 320 },\n  { id: 38, price: 325 },\n  { id: 39, price: 330 },\n  { id: 40, price: 335 },\n  { id: 41, price: 340 },\n  { id: 42, price: 345 },\n  { id: 43, price: 350 },\n  { id: 44, price: 355 },\n  { id: 45, price: 360 },\n  { id: 46, price: 365 },\n  { id: 47, price: 365 },\n  { id: 48, price: 375 },\n  { id: 49, price: 380 },\n  { id: 50, price: 385 },\n  { id: 51, price: 390 },\n  { id: 52, price: 395 },\n  { id: 53, price: 400 },\n  { id: 54, price: 405 },\n  { id: 55, price: 410 },\n  { id: 56, price: 415 },\n  { id: 57, price: 420 },\n  { id: 58, price: 425 },\n  { id: 59, price: 430 },\n  { id: 60, price: 435 },\n  { id: 61, price: 440 },\n  { id: 62, price: 445 },\n  { id: 63, price: 450 },\n  { id: 64, price: 455 },\n  { id: 65, price: 460 },\n  { id: 66, price: 465 },\n  { id: 67, price: 470 },\n  { id: 68, price: 475 },\n  { id: 69, price: 480 },\n  { id: 70, price: 485 },\n  { id: 71, price: 490 },\n  { id: 72, price: 495 },\n  { id: 73, price: 495 },\n  { id: 74, price: 498 },\n  { id: 75, price: 499 },\n  { id: 76, price: 500 },\n  { id: 77, price: 500 },\n  { id: 78, price: 500 },\n  { id: 79, price: 515 },\n  { id: 80, price: 530 },\n  { id: 81, price: 545 },\n  { id: 82, price: 560 },\n  { id: 83, price: 575 },\n  { id: 84, price: 590 },\n  { id: 85, price: 605 },\n  { id: 86, price: 620 },\n  { id: 87, price: 635 },\n  { id: 88, price: 650 },\n  { id: 89, price: 655 },\n  { id: 90, price: 660 },\n  { id: 91, price: 665 },\n  { id: 92, price: 670 },\n  { id: 93, price: 675 },\n  { id: 94, price: 680 },\n  { id: 95, price: 685 },\n  { id: 96, price: 690 },\n  { id: 97, price: 695 },\n  { id: 98, price: 700 },\n  { id: 99, price: 700 },\n  { id: 100, price: 700 },\n  { id: 101, price: 700 },\n  { id: 102, price: 700 },\n  { id: 103, price: 700 },\n  { id: 104, price: 725 },\n  { id: 105, price: 750 },\n  { id: 106, price: 775 },\n  { id: 107, price: 800 },\n  { id: 108, price: 815 },\n  { id: 109, price: 830 },\n  { id: 110, price: 845 },\n  { id: 111, price: 845 },\n  { id: 112, price: 845 },\n  { id: 113, price: 870 },\n  { id: 114, price: 875 },\n  { id: 115, price: 880 },\n  { id: 116, price: 885 },\n  { id: 117, price: 890 },\n  { id: 118, price: 895 },\n  { id: 119, price: 898 },\n  { id: 120, price: 900 },\n]\n\nexport default function Component() {\n  const id = useId()\n\n  // Define the number of ticks\n  const tick_count = 40\n  // Find the min and max values across all items\n  const minValue = Math.min(...items.map((item) => item.price))\n  const maxValue = Math.max(...items.map((item) => item.price))\n\n  const {\n    sliderValue,\n    inputValues,\n    validateAndUpdateValue,\n    handleInputChange,\n    handleSliderChange,\n  } = useSliderWithInput({ minValue, maxValue, initialValue: [200, 780] }) // set initialValue: [minValue, maxValue] to show all items by default\n\n  // Calculate the price step based on the min and max prices\n  const priceStep = (maxValue - minValue) / tick_count\n\n  // Calculate item counts for each price range\n  const itemCounts = Array(tick_count)\n    .fill(0)\n    .map((_, tick) => {\n      const rangeMin = minValue + tick * priceStep\n      const rangeMax = minValue + (tick + 1) * priceStep\n      return items.filter((item) => item.price >= rangeMin && item.price < rangeMax).length\n    })\n\n  // Find maximum count for scaling\n  const maxCount = Math.max(...itemCounts)\n\n  const handleSliderValueChange = (values: number[]) => {\n    handleSliderChange(values)\n  }\n\n  // Function to count items in the selected range\n  const countItemsInRange = (min: number, max: number) => {\n    return items.filter((item) => item.price >= min && item.price <= max).length\n  }\n\n  const isBarInSelectedRange = (\n    index: number,\n    minValue: number,\n    priceStep: number,\n    sliderValue: number[]\n  ) => {\n    const rangeMin = minValue + index * priceStep\n    const rangeMax = minValue + (index + 1) * priceStep\n    return (\n      countItemsInRange(sliderValue[0], sliderValue[1]) > 0 &&\n      rangeMin <= sliderValue[1] &&\n      rangeMax >= sliderValue[0]\n    )\n  }\n\n  return (\n    <div className=\"*:not-first:mt-4\">\n      <Label>Price slider</Label>\n      <div>\n        {/* Histogram bars */}\n        <div className=\"flex h-12 w-full items-end px-3\" aria-hidden=\"true\">\n          {itemCounts.map((count, i) => (\n            <div\n              key={i}\n              className=\"flex flex-1 justify-center\"\n              style={{\n                height: `${(count / maxCount) * 100}%`,\n              }}\n            >\n              <span\n                data-selected={isBarInSelectedRange(i, minValue, priceStep, sliderValue)}\n                className=\"bg-primary/20 size-full\"\n              ></span>\n            </div>\n          ))}\n        </div>\n        <Slider\n          value={sliderValue}\n          onValueChange={handleSliderValueChange}\n          min={minValue}\n          max={maxValue}\n          aria-label=\"Price range\"\n        />\n      </div>\n\n      {/* Inputs */}\n      <div className=\"flex items-center justify-between gap-4\">\n        <div className=\"*:not-first:mt-1\">\n          <Label htmlFor={`${id}-min`}>Min price</Label>\n          <div className=\"relative\">\n            <Input\n              id={`${id}-min`}\n              className=\"peer w-full ps-6\"\n              type=\"text\"\n              inputMode=\"decimal\"\n              value={inputValues[0]}\n              onChange={(e) => handleInputChange(e, 0)}\n              onBlur={() => validateAndUpdateValue(inputValues[0], 0)}\n              onKeyDown={(e) => {\n                if (e.key === 'Enter') {\n                  validateAndUpdateValue(inputValues[0], 0)\n                }\n              }}\n              aria-label=\"Enter minimum price\"\n            />\n            <span className=\"text-muted-foreground pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 text-sm peer-disabled:opacity-50\">\n              $\n            </span>\n          </div>\n        </div>\n        <div className=\"*:not-first:mt-1\">\n          <Label htmlFor={`${id}-max`}>Max price</Label>\n          <div className=\"relative\">\n            <Input\n              id={`${id}-max`}\n              className=\"peer w-full ps-6\"\n              type=\"text\"\n              inputMode=\"decimal\"\n              value={inputValues[1]}\n              onChange={(e) => handleInputChange(e, 1)}\n              onBlur={() => validateAndUpdateValue(inputValues[1], 1)}\n              onKeyDown={(e) => {\n                if (e.key === 'Enter') {\n                  validateAndUpdateValue(inputValues[1], 1)\n                }\n              }}\n              aria-label=\"Enter maximum price\"\n            />\n            <span className=\"text-muted-foreground pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 text-sm peer-disabled:opacity-50\">\n              $\n            </span>\n          </div>\n        </div>\n      </div>\n\n      {/* Button */}\n      <Button className=\"w-full\" variant=\"outline\">\n        Show {countItemsInRange(sliderValue[0], sliderValue[1])} items\n      </Button>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/hooks/use-slider-with-input.ts",
          "type": "registry:hook",
          "target": "components/ui/slider-26/use-slider-with-input.ts",
          "content": "'use client'\n\nimport { useCallback, useState } from 'react'\n\ntype UseSliderWithInputProps = {\n  minValue?: number\n  maxValue?: number\n  initialValue?: number[]\n  defaultValue?: number[]\n}\n\nexport function useSliderWithInput({\n  minValue = 0,\n  maxValue = 100,\n  initialValue = [minValue],\n  defaultValue = [minValue],\n}: UseSliderWithInputProps) {\n  const [sliderValue, setSliderValue] = useState(initialValue)\n  const [inputValues, setInputValues] = useState(initialValue.map((v) => v.toString()))\n\n  const showReset =\n    sliderValue.length === defaultValue.length &&\n    !sliderValue.every((value, index) => value === defaultValue[index])\n\n  const validateAndUpdateValue = useCallback(\n    (rawValue: string, index: number) => {\n      if (rawValue === '' || rawValue === '-') {\n        const newInputValues = [...inputValues]\n        newInputValues[index] = '0'\n        setInputValues(newInputValues)\n\n        const newSliderValues = [...sliderValue]\n        newSliderValues[index] = 0\n        setSliderValue(newSliderValues)\n        return\n      }\n\n      const numValue = parseFloat(rawValue)\n\n      if (isNaN(numValue)) {\n        const newInputValues = [...inputValues]\n        newInputValues[index] = sliderValue[index]!.toString()\n        setInputValues(newInputValues)\n        return\n      }\n\n      let clampedValue = Math.min(maxValue, Math.max(minValue, numValue))\n\n      if (sliderValue.length > 1) {\n        if (index === 0) {\n          clampedValue = Math.min(clampedValue, sliderValue[1]!)\n        } else {\n          clampedValue = Math.max(clampedValue, sliderValue[0]!)\n        }\n      }\n\n      const newSliderValues = [...sliderValue]\n      newSliderValues[index] = clampedValue\n      setSliderValue(newSliderValues)\n\n      const newInputValues = [...inputValues]\n      newInputValues[index] = clampedValue.toString()\n      setInputValues(newInputValues)\n    },\n    [sliderValue, inputValues, minValue, maxValue]\n  )\n\n  const handleInputChange = useCallback(\n    (e: React.ChangeEvent<HTMLInputElement>, index: number) => {\n      const newValue = e.target.value\n      if (newValue === '' || /^-?\\d*\\.?\\d*$/.test(newValue)) {\n        const newInputValues = [...inputValues]\n        newInputValues[index] = newValue\n        setInputValues(newInputValues)\n      }\n    },\n    [inputValues]\n  )\n\n  const handleSliderChange = useCallback((newValue: number[]) => {\n    setSliderValue(newValue)\n    setInputValues(newValue.map((v) => v.toString()))\n  }, [])\n\n  const resetToDefault = useCallback(() => {\n    setSliderValue(defaultValue)\n    setInputValues(defaultValue.map((v) => v.toString()))\n  }, [defaultValue])\n\n  return {\n    sliderValue,\n    inputValues,\n    validateAndUpdateValue,\n    handleInputChange,\n    handleSliderChange,\n    resetToDefault,\n    showReset,\n  }\n}\n"
        },
        {
          "path": "registry/default/components/slider/slider-26.vue",
          "target": "components/ui/slider-26.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { Button } from '@timui/vue';\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\nimport { Slider } from '@timui/vue';\nimport { useSliderWithInput } from '@/registry/default/hooks/use-slider-with-input-vue';\n\nconst id = 'slider-26';\nconst tickCount = 40;\n\nconst items = [\n  { id: 1, price: 80 },\n  { id: 2, price: 95 },\n  { id: 3, price: 110 },\n  { id: 4, price: 125 },\n  { id: 5, price: 130 },\n  { id: 6, price: 140 },\n  { id: 7, price: 145 },\n  { id: 8, price: 150 },\n  { id: 9, price: 155 },\n  { id: 10, price: 165 },\n  { id: 11, price: 175 },\n  { id: 12, price: 185 },\n  { id: 13, price: 195 },\n  { id: 14, price: 205 },\n  { id: 15, price: 215 },\n  { id: 16, price: 225 },\n  { id: 17, price: 235 },\n  { id: 18, price: 245 },\n  { id: 19, price: 255 },\n  { id: 20, price: 260 },\n  { id: 21, price: 265 },\n  { id: 22, price: 270 },\n  { id: 23, price: 275 },\n  { id: 24, price: 280 },\n  { id: 25, price: 285 },\n  { id: 26, price: 290 },\n  { id: 27, price: 290 },\n  { id: 28, price: 295 },\n  { id: 29, price: 295 },\n  { id: 30, price: 295 },\n  { id: 31, price: 298 },\n  { id: 32, price: 299 },\n  { id: 33, price: 300 },\n  { id: 34, price: 305 },\n  { id: 35, price: 310 },\n  { id: 36, price: 315 },\n  { id: 37, price: 320 },\n  { id: 38, price: 325 },\n  { id: 39, price: 330 },\n  { id: 40, price: 335 },\n  { id: 41, price: 340 },\n  { id: 42, price: 345 },\n  { id: 43, price: 350 },\n  { id: 44, price: 355 },\n  { id: 45, price: 360 },\n  { id: 46, price: 365 },\n  { id: 47, price: 365 },\n  { id: 48, price: 375 },\n  { id: 49, price: 380 },\n  { id: 50, price: 385 },\n  { id: 51, price: 390 },\n  { id: 52, price: 395 },\n  { id: 53, price: 400 },\n  { id: 54, price: 405 },\n  { id: 55, price: 410 },\n  { id: 56, price: 415 },\n  { id: 57, price: 420 },\n  { id: 58, price: 425 },\n  { id: 59, price: 430 },\n  { id: 60, price: 435 },\n  { id: 61, price: 440 },\n  { id: 62, price: 445 },\n  { id: 63, price: 450 },\n  { id: 64, price: 455 },\n  { id: 65, price: 460 },\n  { id: 66, price: 465 },\n  { id: 67, price: 470 },\n  { id: 68, price: 475 },\n  { id: 69, price: 480 },\n  { id: 70, price: 485 },\n  { id: 71, price: 490 },\n  { id: 72, price: 495 },\n  { id: 73, price: 495 },\n  { id: 74, price: 498 },\n  { id: 75, price: 499 },\n  { id: 76, price: 500 },\n  { id: 77, price: 500 },\n  { id: 78, price: 500 },\n  { id: 79, price: 515 },\n  { id: 80, price: 530 },\n  { id: 81, price: 545 },\n  { id: 82, price: 560 },\n  { id: 83, price: 575 },\n  { id: 84, price: 590 },\n  { id: 85, price: 605 },\n  { id: 86, price: 620 },\n  { id: 87, price: 635 },\n  { id: 88, price: 650 },\n  { id: 89, price: 655 },\n  { id: 90, price: 660 },\n  { id: 91, price: 665 },\n  { id: 92, price: 670 },\n  { id: 93, price: 675 },\n  { id: 94, price: 680 },\n  { id: 95, price: 685 },\n  { id: 96, price: 690 },\n  { id: 97, price: 695 },\n  { id: 98, price: 700 },\n  { id: 99, price: 700 },\n  { id: 100, price: 700 },\n  { id: 101, price: 700 },\n  { id: 102, price: 700 },\n  { id: 103, price: 700 },\n  { id: 104, price: 725 },\n  { id: 105, price: 750 },\n  { id: 106, price: 775 },\n  { id: 107, price: 800 },\n  { id: 108, price: 815 },\n  { id: 109, price: 830 },\n  { id: 110, price: 845 },\n  { id: 111, price: 845 },\n  { id: 112, price: 845 },\n  { id: 113, price: 870 },\n  { id: 114, price: 875 },\n  { id: 115, price: 880 },\n  { id: 116, price: 885 },\n  { id: 117, price: 890 },\n  { id: 118, price: 895 },\n  { id: 119, price: 898 },\n  { id: 120, price: 900 },\n];\n\nconst minValue = Math.min(...items.map((item) => item.price));\nconst maxValue = Math.max(...items.map((item) => item.price));\n\nconst {\n  sliderValue,\n  inputValues,\n  validateAndUpdateValue,\n  handleInputChange,\n  handleSliderChange,\n} = useSliderWithInput({ minValue, maxValue, initialValue: [200, 780] });\n\nconst priceStep = computed(() => (maxValue - minValue) / tickCount);\n\nconst itemCounts = computed(() =>\n  Array.from({ length: tickCount }).map((_, tick) => {\n    const rangeMin = minValue + tick * priceStep.value;\n    const rangeMax = minValue + (tick + 1) * priceStep.value;\n    return items.filter((item) => item.price >= rangeMin && item.price < rangeMax).length;\n  }),\n);\n\nconst maxCount = computed(() => Math.max(...itemCounts.value, 1));\n\nfunction handleSliderValueChange(values: number[]) {\n  handleSliderChange(values);\n}\n\nfunction countItemsInRange(min: number, max: number) {\n  return items.filter((item) => item.price >= min && item.price <= max).length;\n}\n\nfunction isBarInSelectedRange(index: number) {\n  const currentMin = sliderValue.value[0] ?? minValue;\n  const currentMax = sliderValue.value[1] ?? maxValue;\n  const rangeMin = minValue + index * priceStep.value;\n  const rangeMax = minValue + (index + 1) * priceStep.value;\n  return (\n    countItemsInRange(currentMin, currentMax) > 0 &&\n    rangeMin <= currentMax &&\n    rangeMax >= currentMin\n  );\n}\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-4\">\n    <Label>Price slider</Label>\n\n    <div>\n      <div class=\"flex h-12 w-full items-end px-3\" aria-hidden=\"true\">\n        <div\n          v-for=\"(count, i) in itemCounts\"\n          :key=\"i\"\n          class=\"flex flex-1 justify-center\"\n          :style=\"{ height: `${(count / maxCount) * 100}%` }\"\n        >\n          <span :data-selected=\"isBarInSelectedRange(i)\" class=\"bg-primary/20 size-full\"></span>\n        </div>\n      </div>\n\n      <Slider\n        :value=\"sliderValue\"\n        @update:modelValue=\"handleSliderValueChange\"\n        :min=\"minValue\"\n        :max=\"maxValue\"\n        aria-label=\"Price range\"\n      />\n    </div>\n\n    <div class=\"flex items-center justify-between gap-4\">\n      <div class=\"*:not-first:mt-1\">\n        <Label :htmlFor=\"`${id}-min`\">Min price</Label>\n        <div class=\"relative\">\n          <Input\n            :id=\"`${id}-min`\"\n            class=\"peer w-full ps-6\"\n            type=\"text\"\n            inputMode=\"decimal\"\n            :model-value=\"inputValues[0] ?? ''\"\n            @update:modelValue=\"(next) => handleInputChange(next, 0)\"\n            @blur=\"() => validateAndUpdateValue(inputValues[0] ?? '', 0)\"\n            @keydown.enter.prevent=\"validateAndUpdateValue(inputValues[0] ?? '', 0)\"\n            aria-label=\"Enter minimum price\"\n          />\n          <span class=\"text-muted-foreground pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 text-sm peer-disabled:opacity-50\">$\n          </span>\n        </div>\n      </div>\n\n      <div class=\"*:not-first:mt-1\">\n        <Label :htmlFor=\"`${id}-max`\">Max price</Label>\n        <div class=\"relative\">\n          <Input\n            :id=\"`${id}-max`\"\n            class=\"peer w-full ps-6\"\n            type=\"text\"\n            inputMode=\"decimal\"\n            :model-value=\"inputValues[1] ?? ''\"\n            @update:modelValue=\"(next) => handleInputChange(next, 1)\"\n            @blur=\"() => validateAndUpdateValue(inputValues[1] ?? '', 1)\"\n            @keydown.enter.prevent=\"validateAndUpdateValue(inputValues[1] ?? '', 1)\"\n            aria-label=\"Enter maximum price\"\n          />\n          <span class=\"text-muted-foreground pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 text-sm peer-disabled:opacity-50\">$\n          </span>\n        </div>\n      </div>\n    </div>\n\n    <Button class=\"w-full\" variant=\"outline\">\n      Show {{ countItemsInRange(sliderValue[0], sliderValue[1]) }} items\n    </Button>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/slider/slider-26.html",
          "target": "components/ui/slider-26.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-4\"><Label>Price slider</Label><div><div class=\"flex h-12 w-full items-end px-3\" aria-hidden=\"true\"><!-- Loop itemCounts -->\n<div key=\"${i}\" class=\"flex flex-1 justify-center\" style=\"${{\n                height: `${(count / maxCount) * 100}%`,\n              }}\"><span data-selected=\"${isBarInSelectedRange(i, minValue, priceStep, sliderValue)}\" class=\"bg-primary/20 size-full\"></span></div>\n<!-- End Loop --></div><Slider value=\"${sliderValue}\" on-value-change=\"${handleSliderValueChange}\" min=\"${minValue}\" max=\"${maxValue}\" aria-label=\"Price range\" /></div><div class=\"flex items-center justify-between gap-4\"><div class=\"*:not-first:mt-1\"><Label htmlfor=\"${`${id}-min`}\">Min price</Label><div class=\"relative\"><Input id=\"${`${id}-min`}\" class=\"peer w-full ps-6\" type=\"text\" inputmode=\"decimal\" value=\"${inputValues[0]}\" onchange=\"${(e) => handleInputChange(e, 0)}\" onblur=\"${() => validateAndUpdateValue(inputValues[0], 0)}\" onkeydown=\"${(e) => {\n                if (e.key === 'Enter') {\n                  validateAndUpdateValue(inputValues[0], 0)\n                }\n              }}\" aria-label=\"Enter minimum price\" /><span class=\"text-muted-foreground pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 text-sm peer-disabled:opacity-50\">$\n            </span></div></div><div class=\"*:not-first:mt-1\"><Label htmlfor=\"${`${id}-max`}\">Max price</Label><div class=\"relative\"><Input id=\"${`${id}-max`}\" class=\"peer w-full ps-6\" type=\"text\" inputmode=\"decimal\" value=\"${inputValues[1]}\" onchange=\"${(e) => handleInputChange(e, 1)}\" onblur=\"${() => validateAndUpdateValue(inputValues[1], 1)}\" onkeydown=\"${(e) => {\n                if (e.key === 'Enter') {\n                  validateAndUpdateValue(inputValues[1], 1)\n                }\n              }}\" aria-label=\"Enter maximum price\" /><span class=\"text-muted-foreground pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 text-sm peer-disabled:opacity-50\">$\n            </span></div></div></div><Button class=\"w-full\" variant=\"outline\">Show ${countItemsInRange(sliderValue[0], sliderValue[1])}items\n      </Button></div>\n</template>"
        },
        {
          "path": "registry/default/components/slider/slider-26.wxml",
          "target": "components/ui/slider-26/slider-26.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-4\"><label>Price slider</label><view><view class=\"flex h-12 w-full items-end px-3\" aria-hidden=\"true\"><view wx:for=\"{{itemCounts}}\" wx:for-item=\"count\" wx:for-index=\"i\" wx:key=\"i\" key=\"{{i}}\" class=\"flex flex-1 justify-center\" style=\"{{{\n                height: `${(count / maxCount) * 100}%`,\n              }}}\"><text data-selected=\"{{isBarInSelectedRange(i, minValue, priceStep, sliderValue)}}\" class=\"bg-primary/20 size-full\"></text></view></view><slider value=\"{{sliderValue}}\" bindchange=\"handleSliderValueChange\" min=\"{{minValue}}\" max=\"{{maxValue}}\" aria-label=\"Price range\" /></view><view class=\"flex items-center justify-between gap-4\"><view class=\"*:not-first:mt-1\"><label htmlfor=\"{{`${id}-min`}}\">Min price</label><view class=\"relative\"><input id=\"{{`${id}-min`}}\" class=\"peer w-full ps-6\" type=\"text\" inputmode=\"decimal\" value=\"{{inputValues[0]}}\" onchange=\"{{(e) => handleInputChange(e, 0)}}\" onblur=\"{{() => validateAndUpdateValue(inputValues[0], 0)}}\" onkeydown=\"{{(e) => {\n                if (e.key === 'Enter') {\n                  validateAndUpdateValue(inputValues[0], 0)\n                }\n              }}}\" aria-label=\"Enter minimum price\" /><text class=\"text-muted-foreground pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 text-sm peer-disabled:opacity-50\">$\n            </text></view></view><view class=\"*:not-first:mt-1\"><label htmlfor=\"{{`${id}-max`}}\">Max price</label><view class=\"relative\"><input id=\"{{`${id}-max`}}\" class=\"peer w-full ps-6\" type=\"text\" inputmode=\"decimal\" value=\"{{inputValues[1]}}\" onchange=\"{{(e) => handleInputChange(e, 1)}}\" onblur=\"{{() => validateAndUpdateValue(inputValues[1], 1)}}\" onkeydown=\"{{(e) => {\n                if (e.key === 'Enter') {\n                  validateAndUpdateValue(inputValues[1], 1)\n                }\n              }}}\" aria-label=\"Enter maximum price\" /><text class=\"text-muted-foreground pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 text-sm peer-disabled:opacity-50\">$\n            </text></view></view></view><button class=\"w-full\" variant=\"outline\">Show {{ countItemsInRange(sliderValue[0], sliderValue[1]) }}items\n      </button></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "slider",
          "label",
          "input",
          "button",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "slider-26",
          "group": "slider",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "slider-26",
              "path": "registry/default/components/slider/slider-26.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "slider-26",
              "path": "registry/default/components/slider/slider-26.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "slider-26",
              "path": "registry/default/components/slider/slider-26.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "slider-26",
              "path": "registry/default/components/slider/slider-26.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "slider",
        "title": "Slider · Price range"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "slider"
      ]
    },
    {
      "name": "slider-27",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/slider.json"
      ],
      "files": [
        {
          "path": "registry/default/components/slider/slider-27.tsx",
          "type": "registry:component",
          "target": "components/ui/slider-27.tsx",
          "content": "import { Label, Slider } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"space-y-4\">\n      <legend className=\"text-foreground text-sm font-medium\">Equalizer</legend>\n      <div className=\"flex h-48 justify-center gap-8\">\n        <div className=\"flex flex-col items-center gap-2\">\n          <Slider\n            defaultValue={[2]}\n            min={-5}\n            max={5}\n            orientation=\"vertical\"\n            className=\"[&>:last-child>span]:h-6 [&>:last-child>span]:w-4 [&>:last-child>span]:rounded\"\n            aria-label=\"60 Hz\"\n            showTooltip\n          />\n          <Label className=\"text-muted-foreground flex w-0 justify-center text-xs\">60</Label>\n        </div>\n        <div className=\"flex flex-col items-center gap-2\">\n          <Slider\n            defaultValue={[1]}\n            min={-5}\n            max={5}\n            orientation=\"vertical\"\n            className=\"[&>:last-child>span]:h-6 [&>:last-child>span]:w-4 [&>:last-child>span]:rounded\"\n            aria-label=\"250 Hz\"\n            showTooltip\n          />\n          <Label className=\"text-muted-foreground flex w-0 justify-center text-xs\">250</Label>\n        </div>\n        <div className=\"flex flex-col items-center gap-2\">\n          <Slider\n            defaultValue={[-1]}\n            min={-5}\n            max={5}\n            orientation=\"vertical\"\n            className=\"[&>:last-child>span]:h-6 [&>:last-child>span]:w-4 [&>:last-child>span]:rounded\"\n            aria-label=\"1k\"\n            showTooltip\n          />\n          <Label className=\"text-muted-foreground flex w-0 justify-center text-xs\">1k</Label>\n        </div>\n        <div className=\"flex flex-col items-center gap-2\">\n          <Slider\n            defaultValue={[-3]}\n            min={-5}\n            max={5}\n            orientation=\"vertical\"\n            className=\"[&>:last-child>span]:h-6 [&>:last-child>span]:w-4 [&>:last-child>span]:rounded\"\n            aria-label=\"4k\"\n            showTooltip\n          />\n          <Label className=\"text-muted-foreground flex w-0 justify-center text-xs\">4k</Label>\n        </div>\n        <div className=\"flex flex-col items-center gap-2\">\n          <Slider\n            defaultValue={[2]}\n            min={-5}\n            max={5}\n            orientation=\"vertical\"\n            className=\"[&>:last-child>span]:h-6 [&>:last-child>span]:w-4 [&>:last-child>span]:rounded\"\n            aria-label=\"16k\"\n            showTooltip\n          />\n          <Label className=\"text-muted-foreground flex w-0 justify-center text-xs\">16K</Label>\n        </div>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/slider/slider-27.vue",
          "target": "components/ui/slider-27.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Label } from '@timui/vue';\nimport { Slider } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"space-y-4\"><legend class=\"text-foreground text-sm font-medium\">Equalizer</legend><div class=\"flex h-48 justify-center gap-8\"><div class=\"flex flex-col items-center gap-2\"><Slider :default-value=\"[2]\" :min=\"-5\" :max=\"5\" orientation=\"vertical\" class=\"[&>:last-child>span]:h-6 [&>:last-child>span]:w-4 [&>:last-child>span]:rounded\" aria-label=\"60 Hz\" showTooltip /><Label class=\"text-muted-foreground flex w-0 justify-center text-xs\">60</Label></div><div class=\"flex flex-col items-center gap-2\"><Slider :default-value=\"[1]\" :min=\"-5\" :max=\"5\" orientation=\"vertical\" class=\"[&>:last-child>span]:h-6 [&>:last-child>span]:w-4 [&>:last-child>span]:rounded\" aria-label=\"250 Hz\" showTooltip /><Label class=\"text-muted-foreground flex w-0 justify-center text-xs\">250</Label></div><div class=\"flex flex-col items-center gap-2\"><Slider :default-value=\"[-1]\" :min=\"-5\" :max=\"5\" orientation=\"vertical\" class=\"[&>:last-child>span]:h-6 [&>:last-child>span]:w-4 [&>:last-child>span]:rounded\" aria-label=\"1k\" showTooltip /><Label class=\"text-muted-foreground flex w-0 justify-center text-xs\">1k</Label></div><div class=\"flex flex-col items-center gap-2\"><Slider :default-value=\"[-3]\" :min=\"-5\" :max=\"5\" orientation=\"vertical\" class=\"[&>:last-child>span]:h-6 [&>:last-child>span]:w-4 [&>:last-child>span]:rounded\" aria-label=\"4k\" showTooltip /><Label class=\"text-muted-foreground flex w-0 justify-center text-xs\">4k</Label></div><div class=\"flex flex-col items-center gap-2\"><Slider :default-value=\"[2]\" :min=\"-5\" :max=\"5\" orientation=\"vertical\" class=\"[&>:last-child>span]:h-6 [&>:last-child>span]:w-4 [&>:last-child>span]:rounded\" aria-label=\"16k\" showTooltip /><Label class=\"text-muted-foreground flex w-0 justify-center text-xs\">16K</Label></div></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/slider/slider-27.html",
          "target": "components/ui/slider-27.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-4\"><legend class=\"text-foreground text-sm font-medium\">Equalizer</legend><div class=\"flex h-48 justify-center gap-8\"><div class=\"flex flex-col items-center gap-2\"><Slider default-value=\"${[2]}\" min=\"${-5}\" max=\"${5}\" orientation=\"vertical\" class=\"[&>:last-child>span]:h-6 [&>:last-child>span]:w-4 [&>:last-child>span]:rounded\" aria-label=\"60 Hz\" showtooltip /><Label class=\"text-muted-foreground flex w-0 justify-center text-xs\">60</Label></div><div class=\"flex flex-col items-center gap-2\"><Slider default-value=\"${[1]}\" min=\"${-5}\" max=\"${5}\" orientation=\"vertical\" class=\"[&>:last-child>span]:h-6 [&>:last-child>span]:w-4 [&>:last-child>span]:rounded\" aria-label=\"250 Hz\" showtooltip /><Label class=\"text-muted-foreground flex w-0 justify-center text-xs\">250</Label></div><div class=\"flex flex-col items-center gap-2\"><Slider default-value=\"${[-1]}\" min=\"${-5}\" max=\"${5}\" orientation=\"vertical\" class=\"[&>:last-child>span]:h-6 [&>:last-child>span]:w-4 [&>:last-child>span]:rounded\" aria-label=\"1k\" showtooltip /><Label class=\"text-muted-foreground flex w-0 justify-center text-xs\">1k</Label></div><div class=\"flex flex-col items-center gap-2\"><Slider default-value=\"${[-3]}\" min=\"${-5}\" max=\"${5}\" orientation=\"vertical\" class=\"[&>:last-child>span]:h-6 [&>:last-child>span]:w-4 [&>:last-child>span]:rounded\" aria-label=\"4k\" showtooltip /><Label class=\"text-muted-foreground flex w-0 justify-center text-xs\">4k</Label></div><div class=\"flex flex-col items-center gap-2\"><Slider default-value=\"${[2]}\" min=\"${-5}\" max=\"${5}\" orientation=\"vertical\" class=\"[&>:last-child>span]:h-6 [&>:last-child>span]:w-4 [&>:last-child>span]:rounded\" aria-label=\"16k\" showtooltip /><Label class=\"text-muted-foreground flex w-0 justify-center text-xs\">16K</Label></div></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/slider/slider-27.wxml",
          "target": "components/ui/slider-27/slider-27.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-4\"><legend class=\"text-foreground text-sm font-medium\">Equalizer</legend><view class=\"flex h-48 justify-center gap-8\"><view class=\"flex flex-col items-center gap-2\"><slider default-value=\"{{[2]}}\" min=\"{{-5}}\" max=\"{{5}}\" orientation=\"vertical\" class=\"[&>:last-child>span]:h-6 [&>:last-child>span]:w-4 [&>:last-child>span]:rounded\" aria-label=\"60 Hz\" showtooltip /><label class=\"text-muted-foreground flex w-0 justify-center text-xs\">60</label></view><view class=\"flex flex-col items-center gap-2\"><slider default-value=\"{{[1]}}\" min=\"{{-5}}\" max=\"{{5}}\" orientation=\"vertical\" class=\"[&>:last-child>span]:h-6 [&>:last-child>span]:w-4 [&>:last-child>span]:rounded\" aria-label=\"250 Hz\" showtooltip /><label class=\"text-muted-foreground flex w-0 justify-center text-xs\">250</label></view><view class=\"flex flex-col items-center gap-2\"><slider default-value=\"{{[-1]}}\" min=\"{{-5}}\" max=\"{{5}}\" orientation=\"vertical\" class=\"[&>:last-child>span]:h-6 [&>:last-child>span]:w-4 [&>:last-child>span]:rounded\" aria-label=\"1k\" showtooltip /><label class=\"text-muted-foreground flex w-0 justify-center text-xs\">1k</label></view><view class=\"flex flex-col items-center gap-2\"><slider default-value=\"{{[-3]}}\" min=\"{{-5}}\" max=\"{{5}}\" orientation=\"vertical\" class=\"[&>:last-child>span]:h-6 [&>:last-child>span]:w-4 [&>:last-child>span]:rounded\" aria-label=\"4k\" showtooltip /><label class=\"text-muted-foreground flex w-0 justify-center text-xs\">4k</label></view><view class=\"flex flex-col items-center gap-2\"><slider default-value=\"{{[2]}}\" min=\"{{-5}}\" max=\"{{5}}\" orientation=\"vertical\" class=\"[&>:last-child>span]:h-6 [&>:last-child>span]:w-4 [&>:last-child>span]:rounded\" aria-label=\"16k\" showtooltip /><label class=\"text-muted-foreground flex w-0 justify-center text-xs\">16K</label></view></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "slider",
          "label",
          "equalizer",
          "radix"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "slider-27",
          "group": "slider",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "slider-27",
              "path": "registry/default/components/slider/slider-27.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "slider-27",
              "path": "registry/default/components/slider/slider-27.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "slider-27",
              "path": "registry/default/components/slider/slider-27.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "slider-27",
              "path": "registry/default/components/slider/slider-27.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "slider",
        "title": "Slider · 60 Hz"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "slider"
      ]
    },
    {
      "name": "alert-01",
      "type": "registry:component",
      "files": [
        {
          "path": "registry/default/components/alert/alert-01.tsx",
          "type": "registry:component",
          "target": "components/ui/alert-01.tsx",
          "content": "import { Alert, AlertDescription } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Alert className=\"rounded-md border px-4 py-3\">\n      <div className=\"flex gap-3\">\n        <span className=\"me-3 -mt-0.5 inline-flex text-amber-500\" aria-hidden=\"true\">\n          !\n        </span>\n        <AlertDescription className=\"text-sm text-current\">\n          Some information is missing!\n        </AlertDescription>\n      </div>\n    </Alert>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/alert/alert-01.vue",
          "target": "components/ui/alert-01.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Alert } from '@timui/vue';\nimport { AlertDescription } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Alert class=\"rounded-md border px-4 py-3\"><div class=\"flex gap-3\"><span class=\"me-3 -mt-0.5 inline-flex text-amber-500\" aria-hidden=\"true\">!\n        </span><AlertDescription class=\"text-sm text-current\">Some information is missing!\n        </AlertDescription></div></Alert>\n</template>\n"
        },
        {
          "path": "registry/default/components/alert/alert-01.html",
          "target": "components/ui/alert-01.html",
          "type": "registry:component",
          "content": "<template>\n  <Alert class=\"rounded-md border px-4 py-3\"><div class=\"flex gap-3\"><span class=\"me-3 -mt-0.5 inline-flex text-amber-500\" aria-hidden=\"true\">!\n        </span><AlertDescription class=\"text-sm text-current\">Some information is missing!\n        </AlertDescription></div></Alert>\n</template>"
        },
        {
          "path": "registry/default/components/alert/alert-01.wxml",
          "target": "components/ui/alert-01/alert-01.wxml",
          "type": "registry:component",
          "content": "<view>\n  <alert class=\"rounded-md border px-4 py-3\"><view class=\"flex gap-3\"><text class=\"me-3 -mt-0.5 inline-flex text-amber-500\" aria-hidden=\"true\">!\n        </text><alertdescription class=\"text-sm text-current\">Some information is missing!\n        </alertdescription></view></alert>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "alert",
          "warning"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "alert-01",
          "group": "alert",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "alert-01",
              "path": "registry/default/components/alert/alert-01.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "alert-01",
              "path": "registry/default/components/alert/alert-01.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "alert-01",
              "path": "registry/default/components/alert/alert-01.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "alert-01",
              "path": "registry/default/components/alert/alert-01.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "alerts",
        "title": "Alert · Warning variant"
      },
      "categories": [
        "alerts",
        "alert"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "alert-02",
      "type": "registry:component",
      "files": [
        {
          "path": "registry/default/components/alert/alert-02.tsx",
          "type": "registry:component",
          "target": "components/ui/alert-02.tsx",
          "content": "import { Alert, AlertDescription } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Alert className=\"rounded-md border border-amber-500/50 px-4 py-3 text-amber-600\">\n      <div className=\"flex gap-3\">\n        <span className=\"me-3 -mt-0.5 inline-flex opacity-60\" aria-hidden=\"true\">\n          !\n        </span>\n        <AlertDescription className=\"text-sm text-current\">\n          Some information is missing!\n        </AlertDescription>\n      </div>\n    </Alert>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/alert/alert-02.vue",
          "target": "components/ui/alert-02.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Alert } from '@timui/vue';\nimport { AlertDescription } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Alert class=\"rounded-md border border-amber-500/50 px-4 py-3 text-amber-600\"><div class=\"flex gap-3\"><span class=\"me-3 -mt-0.5 inline-flex opacity-60\" aria-hidden=\"true\">!\n        </span><AlertDescription class=\"text-sm text-current\">Some information is missing!\n        </AlertDescription></div></Alert>\n</template>\n"
        },
        {
          "path": "registry/default/components/alert/alert-02.html",
          "target": "components/ui/alert-02.html",
          "type": "registry:component",
          "content": "<template>\n  <Alert class=\"rounded-md border border-amber-500/50 px-4 py-3 text-amber-600\"><div class=\"flex gap-3\"><span class=\"me-3 -mt-0.5 inline-flex opacity-60\" aria-hidden=\"true\">!\n        </span><AlertDescription class=\"text-sm text-current\">Some information is missing!\n        </AlertDescription></div></Alert>\n</template>"
        },
        {
          "path": "registry/default/components/alert/alert-02.wxml",
          "target": "components/ui/alert-02/alert-02.wxml",
          "type": "registry:component",
          "content": "<view>\n  <alert class=\"rounded-md border border-amber-500/50 px-4 py-3 text-amber-600\"><view class=\"flex gap-3\"><text class=\"me-3 -mt-0.5 inline-flex opacity-60\" aria-hidden=\"true\">!\n        </text><alertdescription class=\"text-sm text-current\">Some information is missing!\n        </alertdescription></view></alert>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "alert",
          "warning"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "alert-02",
          "group": "alert",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "alert-02",
              "path": "registry/default/components/alert/alert-02.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "alert-02",
              "path": "registry/default/components/alert/alert-02.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "alert-02",
              "path": "registry/default/components/alert/alert-02.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "alert-02",
              "path": "registry/default/components/alert/alert-02.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "alerts",
        "title": "Alert · Warning variant"
      },
      "categories": [
        "alerts",
        "alert"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "alert-03",
      "type": "registry:component",
      "files": [
        {
          "path": "registry/default/components/alert/alert-03.tsx",
          "type": "registry:component",
          "target": "components/ui/alert-03.tsx",
          "content": "import { Alert, AlertDescription } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Alert className=\"rounded-md border px-4 py-3\">\n      <div className=\"flex gap-3\">\n        <span className=\"me-3 -mt-0.5 inline-flex text-red-500\" aria-hidden=\"true\">\n          !\n        </span>\n        <AlertDescription className=\"text-sm text-current\">An error occurred!</AlertDescription>\n      </div>\n    </Alert>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/alert/alert-03.vue",
          "target": "components/ui/alert-03.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Alert } from '@timui/vue';\nimport { AlertDescription } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Alert class=\"rounded-md border px-4 py-3\"><div class=\"flex gap-3\"><span class=\"me-3 -mt-0.5 inline-flex text-red-500\" aria-hidden=\"true\">!\n        </span><AlertDescription class=\"text-sm text-current\">An error occurred!</AlertDescription></div></Alert>\n</template>\n"
        },
        {
          "path": "registry/default/components/alert/alert-03.html",
          "target": "components/ui/alert-03.html",
          "type": "registry:component",
          "content": "<template>\n  <Alert class=\"rounded-md border px-4 py-3\"><div class=\"flex gap-3\"><span class=\"me-3 -mt-0.5 inline-flex text-red-500\" aria-hidden=\"true\">!\n        </span><AlertDescription class=\"text-sm text-current\">An error occurred!</AlertDescription></div></Alert>\n</template>"
        },
        {
          "path": "registry/default/components/alert/alert-03.wxml",
          "target": "components/ui/alert-03/alert-03.wxml",
          "type": "registry:component",
          "content": "<view>\n  <alert class=\"rounded-md border px-4 py-3\"><view class=\"flex gap-3\"><text class=\"me-3 -mt-0.5 inline-flex text-red-500\" aria-hidden=\"true\">!\n        </text><alertdescription class=\"text-sm text-current\">An error occurred!</alertdescription></view></alert>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "alert",
          "error"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "alert-03",
          "group": "alert",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "alert-03",
              "path": "registry/default/components/alert/alert-03.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "alert-03",
              "path": "registry/default/components/alert/alert-03.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "alert-03",
              "path": "registry/default/components/alert/alert-03.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "alert-03",
              "path": "registry/default/components/alert/alert-03.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "alerts",
        "title": "Alert · Destructive variant"
      },
      "categories": [
        "alerts",
        "alert"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "alert-04",
      "type": "registry:component",
      "files": [
        {
          "path": "registry/default/components/alert/alert-04.tsx",
          "type": "registry:component",
          "target": "components/ui/alert-04.tsx",
          "content": "import { Alert, AlertDescription } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Alert className=\"rounded-md border border-red-500/50 px-4 py-3 text-red-600\">\n      <div className=\"flex gap-3\">\n        <span className=\"me-3 -mt-0.5 inline-flex opacity-60\" aria-hidden=\"true\">\n          !\n        </span>\n        <AlertDescription className=\"text-sm text-current\">An error occurred!</AlertDescription>\n      </div>\n    </Alert>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/alert/alert-04.vue",
          "target": "components/ui/alert-04.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Alert } from '@timui/vue';\nimport { AlertDescription } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Alert class=\"rounded-md border border-red-500/50 px-4 py-3 text-red-600\"><div class=\"flex gap-3\"><span class=\"me-3 -mt-0.5 inline-flex opacity-60\" aria-hidden=\"true\">!\n        </span><AlertDescription class=\"text-sm text-current\">An error occurred!</AlertDescription></div></Alert>\n</template>\n"
        },
        {
          "path": "registry/default/components/alert/alert-04.html",
          "target": "components/ui/alert-04.html",
          "type": "registry:component",
          "content": "<template>\n  <Alert class=\"rounded-md border border-red-500/50 px-4 py-3 text-red-600\"><div class=\"flex gap-3\"><span class=\"me-3 -mt-0.5 inline-flex opacity-60\" aria-hidden=\"true\">!\n        </span><AlertDescription class=\"text-sm text-current\">An error occurred!</AlertDescription></div></Alert>\n</template>"
        },
        {
          "path": "registry/default/components/alert/alert-04.wxml",
          "target": "components/ui/alert-04/alert-04.wxml",
          "type": "registry:component",
          "content": "<view>\n  <alert class=\"rounded-md border border-red-500/50 px-4 py-3 text-red-600\"><view class=\"flex gap-3\"><text class=\"me-3 -mt-0.5 inline-flex opacity-60\" aria-hidden=\"true\">!\n        </text><alertdescription class=\"text-sm text-current\">An error occurred!</alertdescription></view></alert>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "alert",
          "error"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "alert-04",
          "group": "alert",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "alert-04",
              "path": "registry/default/components/alert/alert-04.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "alert-04",
              "path": "registry/default/components/alert/alert-04.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "alert-04",
              "path": "registry/default/components/alert/alert-04.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "alert-04",
              "path": "registry/default/components/alert/alert-04.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "alerts",
        "title": "Alert · Destructive variant"
      },
      "categories": [
        "alerts",
        "alert"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "alert-05",
      "type": "registry:component",
      "files": [
        {
          "path": "registry/default/components/alert/alert-05.tsx",
          "type": "registry:component",
          "target": "components/ui/alert-05.tsx",
          "content": "import { Alert, AlertDescription } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Alert className=\"rounded-md border px-4 py-3\">\n      <div className=\"flex gap-3\">\n        <span className=\"me-3 -mt-0.5 inline-flex text-emerald-500\" aria-hidden=\"true\">\n          !\n        </span>\n        <AlertDescription className=\"text-sm text-current\">\n          Completed successfully!\n        </AlertDescription>\n      </div>\n    </Alert>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/alert/alert-05.vue",
          "target": "components/ui/alert-05.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Alert } from '@timui/vue';\nimport { AlertDescription } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Alert class=\"rounded-md border px-4 py-3\"><div class=\"flex gap-3\"><span class=\"me-3 -mt-0.5 inline-flex text-emerald-500\" aria-hidden=\"true\">!\n        </span><AlertDescription class=\"text-sm text-current\">Completed successfully!\n        </AlertDescription></div></Alert>\n</template>\n"
        },
        {
          "path": "registry/default/components/alert/alert-05.html",
          "target": "components/ui/alert-05.html",
          "type": "registry:component",
          "content": "<template>\n  <Alert class=\"rounded-md border px-4 py-3\"><div class=\"flex gap-3\"><span class=\"me-3 -mt-0.5 inline-flex text-emerald-500\" aria-hidden=\"true\">!\n        </span><AlertDescription class=\"text-sm text-current\">Completed successfully!\n        </AlertDescription></div></Alert>\n</template>"
        },
        {
          "path": "registry/default/components/alert/alert-05.wxml",
          "target": "components/ui/alert-05/alert-05.wxml",
          "type": "registry:component",
          "content": "<view>\n  <alert class=\"rounded-md border px-4 py-3\"><view class=\"flex gap-3\"><text class=\"me-3 -mt-0.5 inline-flex text-emerald-500\" aria-hidden=\"true\">!\n        </text><alertdescription class=\"text-sm text-current\">Completed successfully!\n        </alertdescription></view></alert>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "alert",
          "success"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "alert-05",
          "group": "alert",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "alert-05",
              "path": "registry/default/components/alert/alert-05.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "alert-05",
              "path": "registry/default/components/alert/alert-05.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "alert-05",
              "path": "registry/default/components/alert/alert-05.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "alert-05",
              "path": "registry/default/components/alert/alert-05.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "alerts",
        "title": "Alert · Success variant"
      },
      "categories": [
        "alerts",
        "alert"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "alert-06",
      "type": "registry:component",
      "files": [
        {
          "path": "registry/default/components/alert/alert-06.tsx",
          "type": "registry:component",
          "target": "components/ui/alert-06.tsx",
          "content": "import { Alert, AlertDescription } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Alert className=\"rounded-md border border-emerald-500/50 px-4 py-3 text-emerald-600\">\n      <div className=\"flex gap-3\">\n        <span className=\"me-3 -mt-0.5 inline-flex opacity-60\" aria-hidden=\"true\">\n          !\n        </span>\n        <AlertDescription className=\"text-sm text-current\">\n          Completed successfully!\n        </AlertDescription>\n      </div>\n    </Alert>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/alert/alert-06.vue",
          "target": "components/ui/alert-06.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Alert } from '@timui/vue';\nimport { AlertDescription } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Alert class=\"rounded-md border border-emerald-500/50 px-4 py-3 text-emerald-600\"><div class=\"flex gap-3\"><span class=\"me-3 -mt-0.5 inline-flex opacity-60\" aria-hidden=\"true\">!\n        </span><AlertDescription class=\"text-sm text-current\">Completed successfully!\n        </AlertDescription></div></Alert>\n</template>\n"
        },
        {
          "path": "registry/default/components/alert/alert-06.html",
          "target": "components/ui/alert-06.html",
          "type": "registry:component",
          "content": "<template>\n  <Alert class=\"rounded-md border border-emerald-500/50 px-4 py-3 text-emerald-600\"><div class=\"flex gap-3\"><span class=\"me-3 -mt-0.5 inline-flex opacity-60\" aria-hidden=\"true\">!\n        </span><AlertDescription class=\"text-sm text-current\">Completed successfully!\n        </AlertDescription></div></Alert>\n</template>"
        },
        {
          "path": "registry/default/components/alert/alert-06.wxml",
          "target": "components/ui/alert-06/alert-06.wxml",
          "type": "registry:component",
          "content": "<view>\n  <alert class=\"rounded-md border border-emerald-500/50 px-4 py-3 text-emerald-600\"><view class=\"flex gap-3\"><text class=\"me-3 -mt-0.5 inline-flex opacity-60\" aria-hidden=\"true\">!\n        </text><alertdescription class=\"text-sm text-current\">Completed successfully!\n        </alertdescription></view></alert>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "alert",
          "success"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "alert-06",
          "group": "alert",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "alert-06",
              "path": "registry/default/components/alert/alert-06.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "alert-06",
              "path": "registry/default/components/alert/alert-06.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "alert-06",
              "path": "registry/default/components/alert/alert-06.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "alert-06",
              "path": "registry/default/components/alert/alert-06.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "alerts",
        "title": "Alert · Success variant"
      },
      "categories": [
        "alerts",
        "alert"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "alert-07",
      "type": "registry:component",
      "files": [
        {
          "path": "registry/default/components/alert/alert-07.tsx",
          "type": "registry:component",
          "target": "components/ui/alert-07.tsx",
          "content": "import { Alert, AlertDescription } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Alert className=\"rounded-md border px-4 py-3\">\n      <div className=\"flex gap-3\">\n        <span className=\"me-3 -mt-0.5 inline-flex text-blue-500\" aria-hidden=\"true\">\n          !\n        </span>\n        <AlertDescription className=\"text-sm text-current\">Just a quick note!</AlertDescription>\n      </div>\n    </Alert>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/alert/alert-07.vue",
          "target": "components/ui/alert-07.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Alert } from '@timui/vue';\nimport { AlertDescription } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Alert class=\"rounded-md border px-4 py-3\"><div class=\"flex gap-3\"><span class=\"me-3 -mt-0.5 inline-flex text-blue-500\" aria-hidden=\"true\">!\n        </span><AlertDescription class=\"text-sm text-current\">Just a quick note!</AlertDescription></div></Alert>\n</template>\n"
        },
        {
          "path": "registry/default/components/alert/alert-07.html",
          "target": "components/ui/alert-07.html",
          "type": "registry:component",
          "content": "<template>\n  <Alert class=\"rounded-md border px-4 py-3\"><div class=\"flex gap-3\"><span class=\"me-3 -mt-0.5 inline-flex text-blue-500\" aria-hidden=\"true\">!\n        </span><AlertDescription class=\"text-sm text-current\">Just a quick note!</AlertDescription></div></Alert>\n</template>"
        },
        {
          "path": "registry/default/components/alert/alert-07.wxml",
          "target": "components/ui/alert-07/alert-07.wxml",
          "type": "registry:component",
          "content": "<view>\n  <alert class=\"rounded-md border px-4 py-3\"><view class=\"flex gap-3\"><text class=\"me-3 -mt-0.5 inline-flex text-blue-500\" aria-hidden=\"true\">!\n        </text><alertdescription class=\"text-sm text-current\">Just a quick note!</alertdescription></view></alert>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "alert",
          "info"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "alert-07",
          "group": "alert",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "alert-07",
              "path": "registry/default/components/alert/alert-07.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "alert-07",
              "path": "registry/default/components/alert/alert-07.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "alert-07",
              "path": "registry/default/components/alert/alert-07.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "alert-07",
              "path": "registry/default/components/alert/alert-07.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "alerts",
        "title": "Alert · Info variant"
      },
      "categories": [
        "alerts",
        "alert"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "alert-08",
      "type": "registry:component",
      "files": [
        {
          "path": "registry/default/components/alert/alert-08.tsx",
          "type": "registry:component",
          "target": "components/ui/alert-08.tsx",
          "content": "import { Alert, AlertDescription } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Alert className=\"rounded-md border border-blue-500/50 px-4 py-3 text-blue-600\">\n      <div className=\"flex gap-3\">\n        <span className=\"me-3 -mt-0.5 inline-flex opacity-60\" aria-hidden=\"true\">\n          !\n        </span>\n        <AlertDescription className=\"text-sm text-current\">Just a quick note!</AlertDescription>\n      </div>\n    </Alert>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/alert/alert-08.vue",
          "target": "components/ui/alert-08.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Alert } from '@timui/vue';\nimport { AlertDescription } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Alert class=\"rounded-md border border-blue-500/50 px-4 py-3 text-blue-600\"><div class=\"flex gap-3\"><span class=\"me-3 -mt-0.5 inline-flex opacity-60\" aria-hidden=\"true\">!\n        </span><AlertDescription class=\"text-sm text-current\">Just a quick note!</AlertDescription></div></Alert>\n</template>\n"
        },
        {
          "path": "registry/default/components/alert/alert-08.html",
          "target": "components/ui/alert-08.html",
          "type": "registry:component",
          "content": "<template>\n  <Alert class=\"rounded-md border border-blue-500/50 px-4 py-3 text-blue-600\"><div class=\"flex gap-3\"><span class=\"me-3 -mt-0.5 inline-flex opacity-60\" aria-hidden=\"true\">!\n        </span><AlertDescription class=\"text-sm text-current\">Just a quick note!</AlertDescription></div></Alert>\n</template>"
        },
        {
          "path": "registry/default/components/alert/alert-08.wxml",
          "target": "components/ui/alert-08/alert-08.wxml",
          "type": "registry:component",
          "content": "<view>\n  <alert class=\"rounded-md border border-blue-500/50 px-4 py-3 text-blue-600\"><view class=\"flex gap-3\"><text class=\"me-3 -mt-0.5 inline-flex opacity-60\" aria-hidden=\"true\">!\n        </text><alertdescription class=\"text-sm text-current\">Just a quick note!</alertdescription></view></alert>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "alert",
          "info"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "alert-08",
          "group": "alert",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "alert-08",
              "path": "registry/default/components/alert/alert-08.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "alert-08",
              "path": "registry/default/components/alert/alert-08.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "alert-08",
              "path": "registry/default/components/alert/alert-08.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "alert-08",
              "path": "registry/default/components/alert/alert-08.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "alerts",
        "title": "Alert · Info variant"
      },
      "categories": [
        "alerts",
        "alert"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "alert-09",
      "type": "registry:component",
      "files": [
        {
          "path": "registry/default/components/alert/alert-09.tsx",
          "type": "registry:component",
          "target": "components/ui/alert-09.tsx",
          "content": "import { Alert, AlertDescription } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Alert className=\"rounded-md border px-4 py-3\">\n      <div className=\"flex gap-3\">\n        <span className=\"mt-0.5 shrink-0 text-amber-500\" aria-hidden=\"true\">\n          !\n        </span>\n        <div className=\"flex grow justify-between gap-3\">\n          <AlertDescription className=\"text-sm text-current\">\n            Some information is missing!\n          </AlertDescription>\n          <a href=\"#\" className=\"group text-sm font-medium whitespace-nowrap\">\n            Link\n            <span\n              className=\"ms-1 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\"\n              aria-hidden=\"true\"\n            >\n              -&gt;\n            </span>\n          </a>\n        </div>\n      </div>\n    </Alert>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/alert/alert-09.vue",
          "target": "components/ui/alert-09.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Alert } from '@timui/vue';\nimport { AlertDescription } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Alert class=\"rounded-md border px-4 py-3\"><div class=\"flex gap-3\"><span class=\"mt-0.5 shrink-0 text-amber-500\" aria-hidden=\"true\">!\n        </span><div class=\"flex grow justify-between gap-3\"><AlertDescription class=\"text-sm text-current\">Some information is missing!\n          </AlertDescription><a href=\"#\" class=\"group text-sm font-medium whitespace-nowrap\">Link\n            <span class=\"ms-1 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\" aria-hidden=\"true\">-&gt;\n            </span></a></div></div></Alert>\n</template>\n"
        },
        {
          "path": "registry/default/components/alert/alert-09.html",
          "target": "components/ui/alert-09.html",
          "type": "registry:component",
          "content": "<template>\n  <Alert class=\"rounded-md border px-4 py-3\"><div class=\"flex gap-3\"><span class=\"mt-0.5 shrink-0 text-amber-500\" aria-hidden=\"true\">!\n        </span><div class=\"flex grow justify-between gap-3\"><AlertDescription class=\"text-sm text-current\">Some information is missing!\n          </AlertDescription><a href=\"#\" class=\"group text-sm font-medium whitespace-nowrap\">Link\n            <span class=\"ms-1 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\" aria-hidden=\"true\">-&gt;\n            </span></a></div></div></Alert>\n</template>"
        },
        {
          "path": "registry/default/components/alert/alert-09.wxml",
          "target": "components/ui/alert-09/alert-09.wxml",
          "type": "registry:component",
          "content": "<view>\n  <alert class=\"rounded-md border px-4 py-3\"><view class=\"flex gap-3\"><text class=\"mt-0.5 shrink-0 text-amber-500\" aria-hidden=\"true\">!\n        </text><view class=\"flex grow justify-between gap-3\"><alertdescription class=\"text-sm text-current\">Some information is missing!\n          </alertdescription><a href=\"#\" class=\"group text-sm font-medium whitespace-nowrap\">Link\n            <text class=\"ms-1 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\" aria-hidden=\"true\">-&gt;\n            </text></a></view></view></alert>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "alert",
          "warning"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "alert-09",
          "group": "alert",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "alert-09",
              "path": "registry/default/components/alert/alert-09.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "alert-09",
              "path": "registry/default/components/alert/alert-09.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "alert-09",
              "path": "registry/default/components/alert/alert-09.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "alert-09",
              "path": "registry/default/components/alert/alert-09.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "alerts",
        "title": "Alert · Warning variant"
      },
      "categories": [
        "alerts",
        "alert"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "alert-10",
      "type": "registry:component",
      "files": [
        {
          "path": "registry/default/components/alert/alert-10.tsx",
          "type": "registry:component",
          "target": "components/ui/alert-10.tsx",
          "content": "import { Alert, AlertDescription } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Alert className=\"rounded-md border border-amber-500/50 px-4 py-3 text-amber-600\">\n      <div className=\"flex gap-3\">\n        <span className=\"mt-0.5 shrink-0 opacity-60\" aria-hidden=\"true\">\n          !\n        </span>\n        <div className=\"flex grow justify-between gap-3\">\n          <AlertDescription className=\"text-sm text-current\">\n            Some information is missing!\n          </AlertDescription>\n          <a href=\"#\" className=\"group text-sm font-medium whitespace-nowrap\">\n            Link\n            <span\n              className=\"ms-1 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\"\n              aria-hidden=\"true\"\n            >\n              -&gt;\n            </span>\n          </a>\n        </div>\n      </div>\n    </Alert>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/alert/alert-10.vue",
          "target": "components/ui/alert-10.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Alert } from '@timui/vue';\nimport { AlertDescription } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Alert class=\"rounded-md border border-amber-500/50 px-4 py-3 text-amber-600\"><div class=\"flex gap-3\"><span class=\"mt-0.5 shrink-0 opacity-60\" aria-hidden=\"true\">!\n        </span><div class=\"flex grow justify-between gap-3\"><AlertDescription class=\"text-sm text-current\">Some information is missing!\n          </AlertDescription><a href=\"#\" class=\"group text-sm font-medium whitespace-nowrap\">Link\n            <span class=\"ms-1 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\" aria-hidden=\"true\">-&gt;\n            </span></a></div></div></Alert>\n</template>\n"
        },
        {
          "path": "registry/default/components/alert/alert-10.html",
          "target": "components/ui/alert-10.html",
          "type": "registry:component",
          "content": "<template>\n  <Alert class=\"rounded-md border border-amber-500/50 px-4 py-3 text-amber-600\"><div class=\"flex gap-3\"><span class=\"mt-0.5 shrink-0 opacity-60\" aria-hidden=\"true\">!\n        </span><div class=\"flex grow justify-between gap-3\"><AlertDescription class=\"text-sm text-current\">Some information is missing!\n          </AlertDescription><a href=\"#\" class=\"group text-sm font-medium whitespace-nowrap\">Link\n            <span class=\"ms-1 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\" aria-hidden=\"true\">-&gt;\n            </span></a></div></div></Alert>\n</template>"
        },
        {
          "path": "registry/default/components/alert/alert-10.wxml",
          "target": "components/ui/alert-10/alert-10.wxml",
          "type": "registry:component",
          "content": "<view>\n  <alert class=\"rounded-md border border-amber-500/50 px-4 py-3 text-amber-600\"><view class=\"flex gap-3\"><text class=\"mt-0.5 shrink-0 opacity-60\" aria-hidden=\"true\">!\n        </text><view class=\"flex grow justify-between gap-3\"><alertdescription class=\"text-sm text-current\">Some information is missing!\n          </alertdescription><a href=\"#\" class=\"group text-sm font-medium whitespace-nowrap\">Link\n            <text class=\"ms-1 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\" aria-hidden=\"true\">-&gt;\n            </text></a></view></view></alert>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "alert",
          "warning"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "alert-10",
          "group": "alert",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "alert-10",
              "path": "registry/default/components/alert/alert-10.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "alert-10",
              "path": "registry/default/components/alert/alert-10.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "alert-10",
              "path": "registry/default/components/alert/alert-10.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "alert-10",
              "path": "registry/default/components/alert/alert-10.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "alerts",
        "title": "Alert · Warning variant"
      },
      "categories": [
        "alerts",
        "alert"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "alert-11",
      "type": "registry:component",
      "files": [
        {
          "path": "registry/default/components/alert/alert-11.tsx",
          "type": "registry:component",
          "target": "components/ui/alert-11.tsx",
          "content": "import { Alert, AlertDescription, AlertTitle } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Alert className=\"rounded-md border px-4 py-3\">\n      <div className=\"flex gap-3\">\n        <span className=\"mt-0.5 shrink-0 text-red-500 opacity-60\" aria-hidden=\"true\">\n          !\n        </span>\n        <div className=\"grow space-y-1\">\n          <AlertTitle className=\"text-sm font-medium text-current\">\n            Password does not meet requirements:\n          </AlertTitle>\n          <ul className=\"text-muted-foreground list-inside list-disc text-sm\">\n            <li>Minimum 8 characters</li>\n            <li>Inlcude a special character</li>\n          </ul>\n        </div>\n      </div>\n    </Alert>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/alert/alert-11.vue",
          "target": "components/ui/alert-11.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Alert } from '@timui/vue';\nimport { AlertDescription } from '@timui/vue';\nimport { AlertTitle } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Alert class=\"rounded-md border px-4 py-3\"><div class=\"flex gap-3\"><span class=\"mt-0.5 shrink-0 text-red-500 opacity-60\" aria-hidden=\"true\">!\n        </span><div class=\"grow space-y-1\"><AlertTitle class=\"text-sm font-medium text-current\">Password does not meet requirements:\n          </AlertTitle><ul class=\"text-muted-foreground list-inside list-disc text-sm\"><li>Minimum 8 characters</li><li>Inlcude a special character</li></ul></div></div></Alert>\n</template>\n"
        },
        {
          "path": "registry/default/components/alert/alert-11.html",
          "target": "components/ui/alert-11.html",
          "type": "registry:component",
          "content": "<template>\n  <Alert class=\"rounded-md border px-4 py-3\"><div class=\"flex gap-3\"><span class=\"mt-0.5 shrink-0 text-red-500 opacity-60\" aria-hidden=\"true\">!\n        </span><div class=\"grow space-y-1\"><AlertTitle class=\"text-sm font-medium text-current\">Password does not meet requirements:\n          </AlertTitle><ul class=\"text-muted-foreground list-inside list-disc text-sm\"><li>Minimum 8 characters</li><li>Inlcude a special character</li></ul></div></div></Alert>\n</template>"
        },
        {
          "path": "registry/default/components/alert/alert-11.wxml",
          "target": "components/ui/alert-11/alert-11.wxml",
          "type": "registry:component",
          "content": "<view>\n  <alert class=\"rounded-md border px-4 py-3\"><view class=\"flex gap-3\"><text class=\"mt-0.5 shrink-0 text-red-500 opacity-60\" aria-hidden=\"true\">!\n        </text><view class=\"grow space-y-1\"><alerttitle class=\"text-sm font-medium text-current\">Password does not meet requirements:\n          </alerttitle><ul class=\"text-muted-foreground list-inside list-disc text-sm\"><li>Minimum 8 characters</li><li>Inlcude a special character</li></ul></view></view></alert>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "alert",
          "error",
          "signup",
          "authentication"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "alert-11",
          "group": "alert",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "alert-11",
              "path": "registry/default/components/alert/alert-11.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "alert-11",
              "path": "registry/default/components/alert/alert-11.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "alert-11",
              "path": "registry/default/components/alert/alert-11.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "alert-11",
              "path": "registry/default/components/alert/alert-11.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "alerts",
        "title": "Alert · Destructive variant"
      },
      "categories": [
        "alerts",
        "alert"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "alert-12",
      "type": "registry:component",
      "files": [
        {
          "path": "registry/default/components/alert/alert-12.tsx",
          "type": "registry:component",
          "target": "components/ui/alert-12.tsx",
          "content": "import { Alert, AlertDescription, AlertTitle } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Alert className=\"rounded-md border border-red-500/50 px-4 py-3 text-red-600\">\n      <div className=\"flex gap-3\">\n        <span className=\"mt-0.5 shrink-0 opacity-60\" aria-hidden=\"true\">\n          !\n        </span>\n        <div className=\"grow space-y-1\">\n          <AlertTitle className=\"text-sm font-medium text-current\">\n            Password does not meet requirements:\n          </AlertTitle>\n          <ul className=\"list-inside list-disc text-sm opacity-80\">\n            <li>Minimum 8 characters</li>\n            <li>Inlcude a special character</li>\n          </ul>\n        </div>\n      </div>\n    </Alert>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/alert/alert-12.vue",
          "target": "components/ui/alert-12.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Alert } from '@timui/vue';\nimport { AlertDescription } from '@timui/vue';\nimport { AlertTitle } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Alert class=\"rounded-md border border-red-500/50 px-4 py-3 text-red-600\"><div class=\"flex gap-3\"><span class=\"mt-0.5 shrink-0 opacity-60\" aria-hidden=\"true\">!\n        </span><div class=\"grow space-y-1\"><AlertTitle class=\"text-sm font-medium text-current\">Password does not meet requirements:\n          </AlertTitle><ul class=\"list-inside list-disc text-sm opacity-80\"><li>Minimum 8 characters</li><li>Inlcude a special character</li></ul></div></div></Alert>\n</template>\n"
        },
        {
          "path": "registry/default/components/alert/alert-12.html",
          "target": "components/ui/alert-12.html",
          "type": "registry:component",
          "content": "<template>\n  <Alert class=\"rounded-md border border-red-500/50 px-4 py-3 text-red-600\"><div class=\"flex gap-3\"><span class=\"mt-0.5 shrink-0 opacity-60\" aria-hidden=\"true\">!\n        </span><div class=\"grow space-y-1\"><AlertTitle class=\"text-sm font-medium text-current\">Password does not meet requirements:\n          </AlertTitle><ul class=\"list-inside list-disc text-sm opacity-80\"><li>Minimum 8 characters</li><li>Inlcude a special character</li></ul></div></div></Alert>\n</template>"
        },
        {
          "path": "registry/default/components/alert/alert-12.wxml",
          "target": "components/ui/alert-12/alert-12.wxml",
          "type": "registry:component",
          "content": "<view>\n  <alert class=\"rounded-md border border-red-500/50 px-4 py-3 text-red-600\"><view class=\"flex gap-3\"><text class=\"mt-0.5 shrink-0 opacity-60\" aria-hidden=\"true\">!\n        </text><view class=\"grow space-y-1\"><alerttitle class=\"text-sm font-medium text-current\">Password does not meet requirements:\n          </alerttitle><ul class=\"list-inside list-disc text-sm opacity-80\"><li>Minimum 8 characters</li><li>Inlcude a special character</li></ul></view></view></alert>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "alert",
          "error",
          "signup",
          "authentication"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "alert-12",
          "group": "alert",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "alert-12",
              "path": "registry/default/components/alert/alert-12.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "alert-12",
              "path": "registry/default/components/alert/alert-12.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "alert-12",
              "path": "registry/default/components/alert/alert-12.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "alert-12",
              "path": "registry/default/components/alert/alert-12.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "alerts",
        "title": "Alert · Destructive variant"
      },
      "categories": [
        "alerts",
        "alert"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "notification-01",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/notification/notification-01.tsx",
          "type": "registry:component",
          "target": "components/ui/notification-01.tsx",
          "content": "import { Button } from '@timui/react'\nimport { TriangleAlert, XIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    // To make the notification fixed, add classes like `fixed bottom-4 right-4` to the container element.\n    <div className=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\">\n      <div className=\"flex gap-2\">\n        <p className=\"grow text-sm\">\n          <TriangleAlert\n            className=\"me-3 -mt-0.5 inline-flex text-amber-500\"\n            size={16}\n            aria-hidden=\"true\"\n          />\n          Some information is missing!\n        </p>\n        <Button\n          variant=\"ghost\"\n          className=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\"\n          aria-label=\"Close notification\"\n        >\n          <XIcon\n            size={16}\n            className=\"opacity-60 transition-opacity group-hover:opacity-100\"\n            aria-hidden=\"true\"\n          />\n        </Button>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/notification/notification-01.vue",
          "target": "components/ui/notification-01.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { TriangleAlert, XIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\"><div class=\"flex gap-2\"><p class=\"grow text-sm\"><TriangleAlert class=\"me-3 -mt-0.5 inline-flex text-amber-500\" :size=\"16\" aria-hidden=\"true\" />Some information is missing!\n        </p><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><XIcon :size=\"16\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/notification/notification-01.html",
          "target": "components/ui/notification-01.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\"><div class=\"flex gap-2\"><p class=\"grow text-sm\"><TriangleAlert class=\"me-3 -mt-0.5 inline-flex text-amber-500\" size=\"${16}\" aria-hidden=\"true\" />Some information is missing!\n        </p><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><XIcon size=\"${16}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/notification/notification-01.wxml",
          "target": "components/ui/notification-01/notification-01.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\"><view class=\"flex gap-2\"><text class=\"grow text-sm\"><trianglealert class=\"me-3 -mt-0.5 inline-flex text-amber-500\" size=\"{{16}}\" aria-hidden=\"true\" />Some information is missing!\n        </text><button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><xicon size=\"{{16}}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></button></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "notification",
          "warning"
        ],
        "colSpan": 2,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "notification-01",
          "group": "notification",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "notification-01",
              "path": "registry/default/components/notification/notification-01.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "notification-01",
              "path": "registry/default/components/notification/notification-01.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "notification-01",
              "path": "registry/default/components/notification/notification-01.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "notification-01",
              "path": "registry/default/components/notification/notification-01.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "notification",
        "title": "Notification · Dismissible"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "notification"
      ]
    },
    {
      "name": "notification-02",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/notification/notification-02.tsx",
          "type": "registry:component",
          "target": "components/ui/notification-02.tsx",
          "content": "import { Button } from '@timui/react'\nimport { CircleCheckIcon, XIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    // To make the notification fixed, add classes like `fixed bottom-4 right-4` to the container element.\n    <div className=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\">\n      <div className=\"flex gap-2\">\n        <p className=\"grow text-sm\">\n          <CircleCheckIcon\n            className=\"me-3 -mt-0.5 inline-flex text-red-500\"\n            size={16}\n            aria-hidden=\"true\"\n          />\n          An error occurred!\n        </p>\n        <Button\n          variant=\"ghost\"\n          className=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\"\n          aria-label=\"Close notification\"\n        >\n          <XIcon\n            size={16}\n            className=\"opacity-60 transition-opacity group-hover:opacity-100\"\n            aria-hidden=\"true\"\n          />\n        </Button>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/notification/notification-02.vue",
          "target": "components/ui/notification-02.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { CircleCheckIcon, XIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\"><div class=\"flex gap-2\"><p class=\"grow text-sm\"><CircleCheckIcon class=\"me-3 -mt-0.5 inline-flex text-red-500\" :size=\"16\" aria-hidden=\"true\" />An error occurred!\n        </p><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><XIcon :size=\"16\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/notification/notification-02.html",
          "target": "components/ui/notification-02.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\"><div class=\"flex gap-2\"><p class=\"grow text-sm\"><CircleCheckIcon class=\"me-3 -mt-0.5 inline-flex text-red-500\" size=\"${16}\" aria-hidden=\"true\" />An error occurred!\n        </p><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><XIcon size=\"${16}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/notification/notification-02.wxml",
          "target": "components/ui/notification-02/notification-02.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\"><view class=\"flex gap-2\"><text class=\"grow text-sm\"><circlecheckicon class=\"me-3 -mt-0.5 inline-flex text-red-500\" size=\"{{16}}\" aria-hidden=\"true\" />An error occurred!\n        </text><button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><xicon size=\"{{16}}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></button></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "notification",
          "error"
        ],
        "colSpan": 2,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "notification-02",
          "group": "notification",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "notification-02",
              "path": "registry/default/components/notification/notification-02.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "notification-02",
              "path": "registry/default/components/notification/notification-02.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "notification-02",
              "path": "registry/default/components/notification/notification-02.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "notification-02",
              "path": "registry/default/components/notification/notification-02.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "notification",
        "title": "Notification · Dismissible"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "notification"
      ]
    },
    {
      "name": "notification-03",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/notification/notification-03.tsx",
          "type": "registry:component",
          "target": "components/ui/notification-03.tsx",
          "content": "import { Button } from '@timui/react'\nimport { CircleCheckIcon, XIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    // To make the notification fixed, add classes like `fixed bottom-4 right-4` to the container element.\n    <div className=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\">\n      <div className=\"flex gap-2\">\n        <p className=\"grow text-sm\">\n          <CircleCheckIcon\n            className=\"me-3 -mt-0.5 inline-flex text-emerald-500\"\n            size={16}\n            aria-hidden=\"true\"\n          />\n          Completed successfully!\n        </p>\n        <Button\n          variant=\"ghost\"\n          className=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\"\n          aria-label=\"Close notification\"\n        >\n          <XIcon\n            size={16}\n            className=\"opacity-60 transition-opacity group-hover:opacity-100\"\n            aria-hidden=\"true\"\n          />\n        </Button>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/notification/notification-03.vue",
          "target": "components/ui/notification-03.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { CircleCheckIcon, XIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\"><div class=\"flex gap-2\"><p class=\"grow text-sm\"><CircleCheckIcon class=\"me-3 -mt-0.5 inline-flex text-emerald-500\" :size=\"16\" aria-hidden=\"true\" />Completed successfully!\n        </p><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><XIcon :size=\"16\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/notification/notification-03.html",
          "target": "components/ui/notification-03.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\"><div class=\"flex gap-2\"><p class=\"grow text-sm\"><CircleCheckIcon class=\"me-3 -mt-0.5 inline-flex text-emerald-500\" size=\"${16}\" aria-hidden=\"true\" />Completed successfully!\n        </p><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><XIcon size=\"${16}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/notification/notification-03.wxml",
          "target": "components/ui/notification-03/notification-03.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\"><view class=\"flex gap-2\"><text class=\"grow text-sm\"><circlecheckicon class=\"me-3 -mt-0.5 inline-flex text-emerald-500\" size=\"{{16}}\" aria-hidden=\"true\" />Completed successfully!\n        </text><button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><xicon size=\"{{16}}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></button></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "notification",
          "success"
        ],
        "colSpan": 2,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "notification-03",
          "group": "notification",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "notification-03",
              "path": "registry/default/components/notification/notification-03.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "notification-03",
              "path": "registry/default/components/notification/notification-03.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "notification-03",
              "path": "registry/default/components/notification/notification-03.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "notification-03",
              "path": "registry/default/components/notification/notification-03.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "notification",
        "title": "Notification · Dismissible"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "notification"
      ]
    },
    {
      "name": "notification-04",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/notification/notification-04.tsx",
          "type": "registry:component",
          "target": "components/ui/notification-04.tsx",
          "content": "import { Button } from '@timui/react'\nimport { InfoIcon, XIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    // To make the notification fixed, add classes like `fixed bottom-4 right-4` to the container element.\n    <div className=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\">\n      <div className=\"flex gap-2\">\n        <p className=\"grow text-sm\">\n          <InfoIcon\n            className=\"me-3 -mt-0.5 inline-flex text-blue-500\"\n            size={16}\n            aria-hidden=\"true\"\n          />\n          Just a quick note!\n        </p>\n        <Button\n          variant=\"ghost\"\n          className=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\"\n          aria-label=\"Close notification\"\n        >\n          <XIcon\n            size={16}\n            className=\"opacity-60 transition-opacity group-hover:opacity-100\"\n            aria-hidden=\"true\"\n          />\n        </Button>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/notification/notification-04.vue",
          "target": "components/ui/notification-04.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { InfoIcon, XIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\"><div class=\"flex gap-2\"><p class=\"grow text-sm\"><InfoIcon class=\"me-3 -mt-0.5 inline-flex text-blue-500\" :size=\"16\" aria-hidden=\"true\" />Just a quick note!\n        </p><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><XIcon :size=\"16\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/notification/notification-04.html",
          "target": "components/ui/notification-04.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\"><div class=\"flex gap-2\"><p class=\"grow text-sm\"><InfoIcon class=\"me-3 -mt-0.5 inline-flex text-blue-500\" size=\"${16}\" aria-hidden=\"true\" />Just a quick note!\n        </p><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><XIcon size=\"${16}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/notification/notification-04.wxml",
          "target": "components/ui/notification-04/notification-04.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\"><view class=\"flex gap-2\"><text class=\"grow text-sm\"><infoicon class=\"me-3 -mt-0.5 inline-flex text-blue-500\" size=\"{{16}}\" aria-hidden=\"true\" />Just a quick note!\n        </text><button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><xicon size=\"{{16}}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></button></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "notification",
          "info"
        ],
        "colSpan": 2,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "notification-04",
          "group": "notification",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "notification-04",
              "path": "registry/default/components/notification/notification-04.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "notification-04",
              "path": "registry/default/components/notification/notification-04.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "notification-04",
              "path": "registry/default/components/notification/notification-04.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "notification-04",
              "path": "registry/default/components/notification/notification-04.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "notification",
        "title": "Notification · Dismissible"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "notification"
      ]
    },
    {
      "name": "notification-05",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/notification/notification-05.tsx",
          "type": "registry:component",
          "target": "components/ui/notification-05.tsx",
          "content": "import { Button } from '@timui/react'\nimport { ArrowRightIcon, TriangleAlert, XIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    // To make the notification fixed, add classes like `fixed bottom-4 right-4` to the container element.\n    <div className=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\">\n      <div className=\"flex gap-2\">\n        <div className=\"flex grow gap-3\">\n          <TriangleAlert className=\"mt-0.5 shrink-0 text-amber-500\" size={16} aria-hidden=\"true\" />\n          <div className=\"flex grow justify-between gap-12\">\n            <p className=\"text-sm\">Some information is missing!</p>\n            <a href=\"#\" className=\"group text-sm font-medium whitespace-nowrap\">\n              Link\n              <ArrowRightIcon\n                className=\"ms-1 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\"\n                size={16}\n                aria-hidden=\"true\"\n              />\n            </a>\n          </div>\n        </div>\n        <Button\n          variant=\"ghost\"\n          className=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\"\n          aria-label=\"Close banner\"\n        >\n          <XIcon\n            size={16}\n            className=\"opacity-60 transition-opacity group-hover:opacity-100\"\n            aria-hidden=\"true\"\n          />\n        </Button>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/notification/notification-05.vue",
          "target": "components/ui/notification-05.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ArrowRightIcon, TriangleAlert, XIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\"><div class=\"flex gap-2\"><div class=\"flex grow gap-3\"><TriangleAlert class=\"mt-0.5 shrink-0 text-amber-500\" :size=\"16\" aria-hidden=\"true\" /><div class=\"flex grow justify-between gap-12\"><p class=\"text-sm\">Some information is missing!</p><a href=\"#\" class=\"group text-sm font-medium whitespace-nowrap\">Link\n              <ArrowRightIcon class=\"ms-1 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\" :size=\"16\" aria-hidden=\"true\" /></a></div></div><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close banner\"><XIcon :size=\"16\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/notification/notification-05.html",
          "target": "components/ui/notification-05.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\"><div class=\"flex gap-2\"><div class=\"flex grow gap-3\"><TriangleAlert class=\"mt-0.5 shrink-0 text-amber-500\" size=\"${16}\" aria-hidden=\"true\" /><div class=\"flex grow justify-between gap-12\"><p class=\"text-sm\">Some information is missing!</p><a href=\"#\" class=\"group text-sm font-medium whitespace-nowrap\">Link\n              <ArrowRightIcon class=\"ms-1 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\" size=\"${16}\" aria-hidden=\"true\" /></a></div></div><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close banner\"><XIcon size=\"${16}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/notification/notification-05.wxml",
          "target": "components/ui/notification-05/notification-05.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\"><view class=\"flex gap-2\"><view class=\"flex grow gap-3\"><trianglealert class=\"mt-0.5 shrink-0 text-amber-500\" size=\"{{16}}\" aria-hidden=\"true\" /><view class=\"flex grow justify-between gap-12\"><text class=\"text-sm\">Some information is missing!</text><a href=\"#\" class=\"group text-sm font-medium whitespace-nowrap\">Link\n              <arrowrighticon class=\"ms-1 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\" size=\"{{16}}\" aria-hidden=\"true\" /></a></view></view><button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close banner\"><xicon size=\"{{16}}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></button></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "notification",
          "warning"
        ],
        "colSpan": 2,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "notification-05",
          "group": "notification",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "notification-05",
              "path": "registry/default/components/notification/notification-05.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "notification-05",
              "path": "registry/default/components/notification/notification-05.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "notification-05",
              "path": "registry/default/components/notification/notification-05.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "notification-05",
              "path": "registry/default/components/notification/notification-05.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "notification",
        "title": "Notification · Dismissible"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "notification"
      ]
    },
    {
      "name": "notification-06",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/notification/notification-06.tsx",
          "type": "registry:component",
          "target": "components/ui/notification-06.tsx",
          "content": "import { Button } from '@timui/react'\nimport { ArrowRightIcon, CircleAlert, XIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    // To make the notification fixed, add classes like `fixed bottom-4 right-4` to the container element.\n    <div className=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\">\n      <div className=\"flex gap-2\">\n        <div className=\"flex grow gap-3\">\n          <CircleAlert className=\"mt-0.5 shrink-0 text-red-500\" size={16} aria-hidden=\"true\" />\n          <div className=\"flex grow justify-between gap-12\">\n            <p className=\"text-sm\">An error occurred!</p>\n            <a href=\"#\" className=\"group text-sm font-medium whitespace-nowrap\">\n              Link\n              <ArrowRightIcon\n                className=\"ms-1 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\"\n                size={16}\n                aria-hidden=\"true\"\n              />\n            </a>\n          </div>\n        </div>\n        <Button\n          variant=\"ghost\"\n          className=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\"\n          aria-label=\"Close banner\"\n        >\n          <XIcon\n            size={16}\n            className=\"opacity-60 transition-opacity group-hover:opacity-100\"\n            aria-hidden=\"true\"\n          />\n        </Button>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/notification/notification-06.vue",
          "target": "components/ui/notification-06.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ArrowRightIcon, CircleAlert, XIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\"><div class=\"flex gap-2\"><div class=\"flex grow gap-3\"><CircleAlert class=\"mt-0.5 shrink-0 text-red-500\" :size=\"16\" aria-hidden=\"true\" /><div class=\"flex grow justify-between gap-12\"><p class=\"text-sm\">An error occurred!</p><a href=\"#\" class=\"group text-sm font-medium whitespace-nowrap\">Link\n              <ArrowRightIcon class=\"ms-1 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\" :size=\"16\" aria-hidden=\"true\" /></a></div></div><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close banner\"><XIcon :size=\"16\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/notification/notification-06.html",
          "target": "components/ui/notification-06.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\"><div class=\"flex gap-2\"><div class=\"flex grow gap-3\"><CircleAlert class=\"mt-0.5 shrink-0 text-red-500\" size=\"${16}\" aria-hidden=\"true\" /><div class=\"flex grow justify-between gap-12\"><p class=\"text-sm\">An error occurred!</p><a href=\"#\" class=\"group text-sm font-medium whitespace-nowrap\">Link\n              <ArrowRightIcon class=\"ms-1 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\" size=\"${16}\" aria-hidden=\"true\" /></a></div></div><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close banner\"><XIcon size=\"${16}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/notification/notification-06.wxml",
          "target": "components/ui/notification-06/notification-06.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\"><view class=\"flex gap-2\"><view class=\"flex grow gap-3\"><circlealert class=\"mt-0.5 shrink-0 text-red-500\" size=\"{{16}}\" aria-hidden=\"true\" /><view class=\"flex grow justify-between gap-12\"><text class=\"text-sm\">An error occurred!</text><a href=\"#\" class=\"group text-sm font-medium whitespace-nowrap\">Link\n              <arrowrighticon class=\"ms-1 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\" size=\"{{16}}\" aria-hidden=\"true\" /></a></view></view><button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close banner\"><xicon size=\"{{16}}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></button></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "notification",
          "error"
        ],
        "colSpan": 2,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "notification-06",
          "group": "notification",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "notification-06",
              "path": "registry/default/components/notification/notification-06.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "notification-06",
              "path": "registry/default/components/notification/notification-06.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "notification-06",
              "path": "registry/default/components/notification/notification-06.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "notification-06",
              "path": "registry/default/components/notification/notification-06.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "notification",
        "title": "Notification · Dismissible"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "notification"
      ]
    },
    {
      "name": "notification-07",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/notification/notification-07.tsx",
          "type": "registry:component",
          "target": "components/ui/notification-07.tsx",
          "content": "import { Button } from '@timui/react'\nimport { ArrowRightIcon, CircleCheckIcon, XIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    // To make the notification fixed, add classes like `fixed bottom-4 right-4` to the container element.\n    <div className=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\">\n      <div className=\"flex gap-2\">\n        <div className=\"flex grow gap-3\">\n          <CircleCheckIcon\n            className=\"mt-0.5 shrink-0 text-emerald-500\"\n            size={16}\n            aria-hidden=\"true\"\n          />\n          <div className=\"flex grow justify-between gap-12\">\n            <p className=\"text-sm\">Completed successfully!</p>\n            <a href=\"#\" className=\"group text-sm font-medium whitespace-nowrap\">\n              Link\n              <ArrowRightIcon\n                className=\"ms-1 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\"\n                size={16}\n                aria-hidden=\"true\"\n              />\n            </a>\n          </div>\n        </div>\n        <Button\n          variant=\"ghost\"\n          className=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\"\n          aria-label=\"Close banner\"\n        >\n          <XIcon\n            size={16}\n            className=\"opacity-60 transition-opacity group-hover:opacity-100\"\n            aria-hidden=\"true\"\n          />\n        </Button>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/notification/notification-07.vue",
          "target": "components/ui/notification-07.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ArrowRightIcon, CircleCheckIcon, XIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\"><div class=\"flex gap-2\"><div class=\"flex grow gap-3\"><CircleCheckIcon class=\"mt-0.5 shrink-0 text-emerald-500\" :size=\"16\" aria-hidden=\"true\" /><div class=\"flex grow justify-between gap-12\"><p class=\"text-sm\">Completed successfully!</p><a href=\"#\" class=\"group text-sm font-medium whitespace-nowrap\">Link\n              <ArrowRightIcon class=\"ms-1 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\" :size=\"16\" aria-hidden=\"true\" /></a></div></div><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close banner\"><XIcon :size=\"16\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/notification/notification-07.html",
          "target": "components/ui/notification-07.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\"><div class=\"flex gap-2\"><div class=\"flex grow gap-3\"><CircleCheckIcon class=\"mt-0.5 shrink-0 text-emerald-500\" size=\"${16}\" aria-hidden=\"true\" /><div class=\"flex grow justify-between gap-12\"><p class=\"text-sm\">Completed successfully!</p><a href=\"#\" class=\"group text-sm font-medium whitespace-nowrap\">Link\n              <ArrowRightIcon class=\"ms-1 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\" size=\"${16}\" aria-hidden=\"true\" /></a></div></div><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close banner\"><XIcon size=\"${16}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/notification/notification-07.wxml",
          "target": "components/ui/notification-07/notification-07.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\"><view class=\"flex gap-2\"><view class=\"flex grow gap-3\"><circlecheckicon class=\"mt-0.5 shrink-0 text-emerald-500\" size=\"{{16}}\" aria-hidden=\"true\" /><view class=\"flex grow justify-between gap-12\"><text class=\"text-sm\">Completed successfully!</text><a href=\"#\" class=\"group text-sm font-medium whitespace-nowrap\">Link\n              <arrowrighticon class=\"ms-1 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\" size=\"{{16}}\" aria-hidden=\"true\" /></a></view></view><button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close banner\"><xicon size=\"{{16}}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></button></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "notification",
          "success"
        ],
        "colSpan": 2,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "notification-07",
          "group": "notification",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "notification-07",
              "path": "registry/default/components/notification/notification-07.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "notification-07",
              "path": "registry/default/components/notification/notification-07.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "notification-07",
              "path": "registry/default/components/notification/notification-07.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "notification-07",
              "path": "registry/default/components/notification/notification-07.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "notification",
        "title": "Notification · Dismissible"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "notification"
      ]
    },
    {
      "name": "notification-08",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/notification/notification-08.tsx",
          "type": "registry:component",
          "target": "components/ui/notification-08.tsx",
          "content": "import { Button } from '@timui/react'\nimport { ArrowRightIcon, InfoIcon, XIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    // To make the notification fixed, add classes like `fixed bottom-4 right-4` to the container element.\n    <div className=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\">\n      <div className=\"flex gap-2\">\n        <div className=\"flex grow gap-3\">\n          <InfoIcon className=\"mt-0.5 shrink-0 text-blue-500\" size={16} aria-hidden=\"true\" />\n          <div className=\"flex grow justify-between gap-12\">\n            <p className=\"text-sm\">Just a quick note!</p>\n            <a href=\"#\" className=\"group text-sm font-medium whitespace-nowrap\">\n              Link\n              <ArrowRightIcon\n                className=\"ms-1 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\"\n                size={16}\n                aria-hidden=\"true\"\n              />\n            </a>\n          </div>\n        </div>\n        <Button\n          variant=\"ghost\"\n          className=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\"\n          aria-label=\"Close banner\"\n        >\n          <XIcon\n            size={16}\n            className=\"opacity-60 transition-opacity group-hover:opacity-100\"\n            aria-hidden=\"true\"\n          />\n        </Button>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/notification/notification-08.vue",
          "target": "components/ui/notification-08.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ArrowRightIcon, InfoIcon, XIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\"><div class=\"flex gap-2\"><div class=\"flex grow gap-3\"><InfoIcon class=\"mt-0.5 shrink-0 text-blue-500\" :size=\"16\" aria-hidden=\"true\" /><div class=\"flex grow justify-between gap-12\"><p class=\"text-sm\">Just a quick note!</p><a href=\"#\" class=\"group text-sm font-medium whitespace-nowrap\">Link\n              <ArrowRightIcon class=\"ms-1 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\" :size=\"16\" aria-hidden=\"true\" /></a></div></div><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close banner\"><XIcon :size=\"16\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/notification/notification-08.html",
          "target": "components/ui/notification-08.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\"><div class=\"flex gap-2\"><div class=\"flex grow gap-3\"><InfoIcon class=\"mt-0.5 shrink-0 text-blue-500\" size=\"${16}\" aria-hidden=\"true\" /><div class=\"flex grow justify-between gap-12\"><p class=\"text-sm\">Just a quick note!</p><a href=\"#\" class=\"group text-sm font-medium whitespace-nowrap\">Link\n              <ArrowRightIcon class=\"ms-1 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\" size=\"${16}\" aria-hidden=\"true\" /></a></div></div><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close banner\"><XIcon size=\"${16}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/notification/notification-08.wxml",
          "target": "components/ui/notification-08/notification-08.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\"><view class=\"flex gap-2\"><view class=\"flex grow gap-3\"><infoicon class=\"mt-0.5 shrink-0 text-blue-500\" size=\"{{16}}\" aria-hidden=\"true\" /><view class=\"flex grow justify-between gap-12\"><text class=\"text-sm\">Just a quick note!</text><a href=\"#\" class=\"group text-sm font-medium whitespace-nowrap\">Link\n              <arrowrighticon class=\"ms-1 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\" size=\"{{16}}\" aria-hidden=\"true\" /></a></view></view><button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close banner\"><xicon size=\"{{16}}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></button></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "notification",
          "info"
        ],
        "colSpan": 2,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "notification-08",
          "group": "notification",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "notification-08",
              "path": "registry/default/components/notification/notification-08.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "notification-08",
              "path": "registry/default/components/notification/notification-08.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "notification-08",
              "path": "registry/default/components/notification/notification-08.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "notification-08",
              "path": "registry/default/components/notification/notification-08.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "notification",
        "title": "Notification · Dismissible"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "notification"
      ]
    },
    {
      "name": "notification-09",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/notification/notification-09.tsx",
          "type": "registry:component",
          "target": "components/ui/notification-09.tsx",
          "content": "import { Button } from '@timui/react'\nimport { CircleCheckIcon, XIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    // To make the notification fixed, add classes like `fixed bottom-4 right-4` to the container element.\n    <div className=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\">\n      <div className=\"flex items-center gap-2\">\n        <div className=\"flex grow items-center gap-3\">\n          <CircleCheckIcon\n            className=\"mt-0.5 shrink-0 text-emerald-500\"\n            size={16}\n            aria-hidden=\"true\"\n          />\n          <div className=\"flex grow items-center justify-between gap-12\">\n            <p className=\"text-sm\">You&lsquo;ve made changes!</p>\n            <Button size=\"sm\">Undo</Button>\n          </div>\n        </div>\n        <Button\n          variant=\"ghost\"\n          className=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\"\n          aria-label=\"Close banner\"\n        >\n          <XIcon\n            size={16}\n            className=\"opacity-60 transition-opacity group-hover:opacity-100\"\n            aria-hidden=\"true\"\n          />\n        </Button>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/notification/notification-09.vue",
          "target": "components/ui/notification-09.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { CircleCheckIcon, XIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\"><div class=\"flex items-center gap-2\"><div class=\"flex grow items-center gap-3\"><CircleCheckIcon class=\"mt-0.5 shrink-0 text-emerald-500\" :size=\"16\" aria-hidden=\"true\" /><div class=\"flex grow items-center justify-between gap-12\"><p class=\"text-sm\">You&lsquo;ve made changes!</p><Button size=\"sm\">Undo</Button></div></div><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close banner\"><XIcon :size=\"16\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/notification/notification-09.html",
          "target": "components/ui/notification-09.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\"><div class=\"flex items-center gap-2\"><div class=\"flex grow items-center gap-3\"><CircleCheckIcon class=\"mt-0.5 shrink-0 text-emerald-500\" size=\"${16}\" aria-hidden=\"true\" /><div class=\"flex grow items-center justify-between gap-12\"><p class=\"text-sm\">You&lsquo;ve made changes!</p><Button size=\"sm\">Undo</Button></div></div><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close banner\"><XIcon size=\"${16}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/notification/notification-09.wxml",
          "target": "components/ui/notification-09/notification-09.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\"><view class=\"flex items-center gap-2\"><view class=\"flex grow items-center gap-3\"><circlecheckicon class=\"mt-0.5 shrink-0 text-emerald-500\" size=\"{{16}}\" aria-hidden=\"true\" /><view class=\"flex grow items-center justify-between gap-12\"><text class=\"text-sm\">You&lsquo;ve made changes!</text><button size=\"sm\">Undo</button></view></view><button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close banner\"><xicon size=\"{{16}}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></button></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "notification",
          "button",
          "success"
        ],
        "colSpan": 2,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "notification-09",
          "group": "notification",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "notification-09",
              "path": "registry/default/components/notification/notification-09.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "notification-09",
              "path": "registry/default/components/notification/notification-09.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "notification-09",
              "path": "registry/default/components/notification/notification-09.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "notification-09",
              "path": "registry/default/components/notification/notification-09.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "notification",
        "title": "Notification · Dismissible"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "notification"
      ]
    },
    {
      "name": "notification-10",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/notification/notification-10.tsx",
          "type": "registry:component",
          "target": "components/ui/notification-10.tsx",
          "content": "import { Button } from '@timui/react'\nimport { CircleCheckIcon, XIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    // To make the notification fixed, add classes like `fixed bottom-4 right-4` to the container element.\n    <div className=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\">\n      <div className=\"flex gap-2\">\n        <div className=\"flex grow gap-3\">\n          <CircleCheckIcon\n            className=\"mt-0.5 shrink-0 text-emerald-500\"\n            size={16}\n            aria-hidden=\"true\"\n          />\n          <div className=\"flex grow justify-between gap-12\">\n            <p className=\"text-sm\">Message sent</p>\n            <div className=\"text-sm whitespace-nowrap\">\n              <button className=\"text-sm font-medium hover:underline\">View</button>{' '}\n              <span className=\"text-muted-foreground mx-1\">·</span>{' '}\n              <button className=\"text-sm font-medium hover:underline\">Undo</button>\n            </div>\n          </div>\n        </div>\n        <Button\n          variant=\"ghost\"\n          className=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\"\n          aria-label=\"Close banner\"\n        >\n          <XIcon\n            size={16}\n            className=\"opacity-60 transition-opacity group-hover:opacity-100\"\n            aria-hidden=\"true\"\n          />\n        </Button>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/notification/notification-10.vue",
          "target": "components/ui/notification-10.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { CircleCheckIcon, XIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\"><div class=\"flex gap-2\"><div class=\"flex grow gap-3\"><CircleCheckIcon class=\"mt-0.5 shrink-0 text-emerald-500\" :size=\"16\" aria-hidden=\"true\" /><div class=\"flex grow justify-between gap-12\"><p class=\"text-sm\">Message sent</p><div class=\"text-sm whitespace-nowrap\"><button class=\"text-sm font-medium hover:underline\">View</button>{{ ' ' }}<span class=\"text-muted-foreground mx-1\">·</span>{{ ' ' }}<button class=\"text-sm font-medium hover:underline\">Undo</button></div></div></div><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close banner\"><XIcon :size=\"16\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/notification/notification-10.html",
          "target": "components/ui/notification-10.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\"><div class=\"flex gap-2\"><div class=\"flex grow gap-3\"><CircleCheckIcon class=\"mt-0.5 shrink-0 text-emerald-500\" size=\"${16}\" aria-hidden=\"true\" /><div class=\"flex grow justify-between gap-12\"><p class=\"text-sm\">Message sent</p><div class=\"text-sm whitespace-nowrap\"><button class=\"text-sm font-medium hover:underline\">View</button>${' '}<span class=\"text-muted-foreground mx-1\">·</span>${' '}<button class=\"text-sm font-medium hover:underline\">Undo</button></div></div></div><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close banner\"><XIcon size=\"${16}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/notification/notification-10.wxml",
          "target": "components/ui/notification-10/notification-10.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"bg-background z-50 max-w-[400px] rounded-md border px-4 py-3 shadow-lg\"><view class=\"flex gap-2\"><view class=\"flex grow gap-3\"><circlecheckicon class=\"mt-0.5 shrink-0 text-emerald-500\" size=\"{{16}}\" aria-hidden=\"true\" /><view class=\"flex grow justify-between gap-12\"><text class=\"text-sm\">Message sent</text><view class=\"text-sm whitespace-nowrap\"><button class=\"text-sm font-medium hover:underline\">View</button>{{ ' ' }}<text class=\"text-muted-foreground mx-1\">·</text>{{ ' ' }}<button class=\"text-sm font-medium hover:underline\">Undo</button></view></view></view><button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close banner\"><xicon size=\"{{16}}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></button></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "notification",
          "success"
        ],
        "colSpan": 2,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "notification-10",
          "group": "notification",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "notification-10",
              "path": "registry/default/components/notification/notification-10.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "notification-10",
              "path": "registry/default/components/notification/notification-10.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "notification-10",
              "path": "registry/default/components/notification/notification-10.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "notification-10",
              "path": "registry/default/components/notification/notification-10.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "notification",
        "title": "Notification · Dismissible"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "notification"
      ]
    },
    {
      "name": "notification-11",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/notification/notification-11.tsx",
          "type": "registry:component",
          "target": "components/ui/notification-11.tsx",
          "content": "import { Button } from '@timui/react'\nimport { TriangleAlertIcon, XIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    // To make the notification fixed, add classes like `fixed bottom-4 right-4` to the container element.\n    <div className=\"bg-background z-50 max-w-[400px] rounded-md border p-4 shadow-lg\">\n      <div className=\"flex gap-2\">\n        <div className=\"flex grow gap-3\">\n          <TriangleAlertIcon\n            className=\"mt-0.5 shrink-0 text-amber-500\"\n            size={16}\n            aria-hidden=\"true\"\n          />\n          <div className=\"flex grow flex-col gap-3\">\n            <div className=\"space-y-1\">\n              <p className=\"text-sm font-medium\">Something requires your action!</p>\n              <p className=\"text-muted-foreground text-sm\">\n                It conveys that a specific action is needed to resolve or address a situation.\n              </p>\n            </div>\n            <div>\n              <Button size=\"sm\">Learn more</Button>\n            </div>\n          </div>\n        </div>\n        <Button\n          variant=\"ghost\"\n          className=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\"\n          aria-label=\"Close notification\"\n        >\n          <XIcon\n            size={16}\n            className=\"opacity-60 transition-opacity group-hover:opacity-100\"\n            aria-hidden=\"true\"\n          />\n        </Button>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/notification/notification-11.vue",
          "target": "components/ui/notification-11.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { TriangleAlertIcon, XIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border p-4 shadow-lg\"><div class=\"flex gap-2\"><div class=\"flex grow gap-3\"><TriangleAlertIcon class=\"mt-0.5 shrink-0 text-amber-500\" :size=\"16\" aria-hidden=\"true\" /><div class=\"flex grow flex-col gap-3\"><div class=\"space-y-1\"><p class=\"text-sm font-medium\">Something requires your action!</p><p class=\"text-muted-foreground text-sm\">It conveys that a specific action is needed to resolve or address a situation.\n              </p></div><div><Button size=\"sm\">Learn more</Button></div></div></div><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><XIcon :size=\"16\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/notification/notification-11.html",
          "target": "components/ui/notification-11.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border p-4 shadow-lg\"><div class=\"flex gap-2\"><div class=\"flex grow gap-3\"><TriangleAlertIcon class=\"mt-0.5 shrink-0 text-amber-500\" size=\"${16}\" aria-hidden=\"true\" /><div class=\"flex grow flex-col gap-3\"><div class=\"space-y-1\"><p class=\"text-sm font-medium\">Something requires your action!</p><p class=\"text-muted-foreground text-sm\">It conveys that a specific action is needed to resolve or address a situation.\n              </p></div><div><Button size=\"sm\">Learn more</Button></div></div></div><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><XIcon size=\"${16}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/notification/notification-11.wxml",
          "target": "components/ui/notification-11/notification-11.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"bg-background z-50 max-w-[400px] rounded-md border p-4 shadow-lg\"><view class=\"flex gap-2\"><view class=\"flex grow gap-3\"><trianglealerticon class=\"mt-0.5 shrink-0 text-amber-500\" size=\"{{16}}\" aria-hidden=\"true\" /><view class=\"flex grow flex-col gap-3\"><view class=\"space-y-1\"><text class=\"text-sm font-medium\">Something requires your action!</text><text class=\"text-muted-foreground text-sm\">It conveys that a specific action is needed to resolve or address a situation.\n              </text></view><view><button size=\"sm\">Learn more</button></view></view></view><button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><xicon size=\"{{16}}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></button></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "notification",
          "button",
          "warning"
        ],
        "colSpan": 2,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "notification-11",
          "group": "notification",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "notification-11",
              "path": "registry/default/components/notification/notification-11.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "notification-11",
              "path": "registry/default/components/notification/notification-11.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "notification-11",
              "path": "registry/default/components/notification/notification-11.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "notification-11",
              "path": "registry/default/components/notification/notification-11.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "notification",
        "title": "Notification · Dismissible"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "notification"
      ]
    },
    {
      "name": "notification-12",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/notification/notification-12.tsx",
          "type": "registry:component",
          "target": "components/ui/notification-12.tsx",
          "content": "import { Button } from '@timui/react'\nimport { CircleAlertIcon, XIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    // To make the notification fixed, add classes like `fixed bottom-4 right-4` to the container element.\n    <div className=\"bg-background z-50 max-w-[400px] rounded-md border p-4 shadow-lg\">\n      <div className=\"flex gap-2\">\n        <div className=\"flex grow gap-3\">\n          <CircleAlertIcon className=\"mt-0.5 shrink-0 text-red-500\" size={16} aria-hidden=\"true\" />\n          <div className=\"flex grow flex-col gap-3\">\n            <div className=\"space-y-1\">\n              <p className=\"text-sm font-medium\">We couldn&lsquo;t complete your request!</p>\n              <p className=\"text-muted-foreground text-sm\">\n                It indicates that an issue has prevented the processing of the request.\n              </p>\n            </div>\n            <div className=\"flex gap-2\">\n              <Button size=\"sm\">Learn more</Button>\n            </div>\n          </div>\n          <Button\n            variant=\"ghost\"\n            className=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\"\n            aria-label=\"Close notification\"\n          >\n            <XIcon\n              size={16}\n              className=\"opacity-60 transition-opacity group-hover:opacity-100\"\n              aria-hidden=\"true\"\n            />\n          </Button>\n        </div>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/notification/notification-12.vue",
          "target": "components/ui/notification-12.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { CircleAlertIcon, XIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border p-4 shadow-lg\"><div class=\"flex gap-2\"><div class=\"flex grow gap-3\"><CircleAlertIcon class=\"mt-0.5 shrink-0 text-red-500\" :size=\"16\" aria-hidden=\"true\" /><div class=\"flex grow flex-col gap-3\"><div class=\"space-y-1\"><p class=\"text-sm font-medium\">We couldn&lsquo;t complete your request!</p><p class=\"text-muted-foreground text-sm\">It indicates that an issue has prevented the processing of the request.\n              </p></div><div class=\"flex gap-2\"><Button size=\"sm\">Learn more</Button></div></div><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><XIcon :size=\"16\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/notification/notification-12.html",
          "target": "components/ui/notification-12.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border p-4 shadow-lg\"><div class=\"flex gap-2\"><div class=\"flex grow gap-3\"><CircleAlertIcon class=\"mt-0.5 shrink-0 text-red-500\" size=\"${16}\" aria-hidden=\"true\" /><div class=\"flex grow flex-col gap-3\"><div class=\"space-y-1\"><p class=\"text-sm font-medium\">We couldn&lsquo;t complete your request!</p><p class=\"text-muted-foreground text-sm\">It indicates that an issue has prevented the processing of the request.\n              </p></div><div class=\"flex gap-2\"><Button size=\"sm\">Learn more</Button></div></div><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><XIcon size=\"${16}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/notification/notification-12.wxml",
          "target": "components/ui/notification-12/notification-12.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"bg-background z-50 max-w-[400px] rounded-md border p-4 shadow-lg\"><view class=\"flex gap-2\"><view class=\"flex grow gap-3\"><circlealerticon class=\"mt-0.5 shrink-0 text-red-500\" size=\"{{16}}\" aria-hidden=\"true\" /><view class=\"flex grow flex-col gap-3\"><view class=\"space-y-1\"><text class=\"text-sm font-medium\">We couldn&lsquo;t complete your request!</text><text class=\"text-muted-foreground text-sm\">It indicates that an issue has prevented the processing of the request.\n              </text></view><view class=\"flex gap-2\"><button size=\"sm\">Learn more</button></view></view><button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><xicon size=\"{{16}}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></button></view></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "notification",
          "button",
          "error"
        ],
        "colSpan": 2,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "notification-12",
          "group": "notification",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "notification-12",
              "path": "registry/default/components/notification/notification-12.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "notification-12",
              "path": "registry/default/components/notification/notification-12.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "notification-12",
              "path": "registry/default/components/notification/notification-12.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "notification-12",
              "path": "registry/default/components/notification/notification-12.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "notification",
        "title": "Notification · Dismissible"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "notification"
      ]
    },
    {
      "name": "notification-13",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/notification/notification-13.tsx",
          "type": "registry:component",
          "target": "components/ui/notification-13.tsx",
          "content": "import { Button } from '@timui/react'\nimport { CircleCheckIcon, XIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    // To make the notification fixed, add classes like `fixed bottom-4 right-4` to the container element.\n    <div className=\"bg-background z-50 max-w-[400px] rounded-md border p-4 shadow-lg\">\n      <div className=\"flex gap-2\">\n        <div className=\"flex grow gap-3\">\n          <CircleCheckIcon\n            className=\"mt-0.5 shrink-0 text-emerald-500\"\n            size={16}\n            aria-hidden=\"true\"\n          />\n          <div className=\"flex grow flex-col gap-3\">\n            <div className=\"space-y-1\">\n              <p className=\"text-sm font-medium\">Your request was completed!</p>\n              <p className=\"text-muted-foreground text-sm\">\n                It demonstrates that the task or request has been processed.\n              </p>\n            </div>\n            <div className=\"flex gap-2\">\n              <Button size=\"sm\">Learn more</Button>\n            </div>\n          </div>\n          <Button\n            variant=\"ghost\"\n            className=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\"\n            aria-label=\"Close notification\"\n          >\n            <XIcon\n              size={16}\n              className=\"opacity-60 transition-opacity group-hover:opacity-100\"\n              aria-hidden=\"true\"\n            />\n          </Button>\n        </div>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/notification/notification-13.vue",
          "target": "components/ui/notification-13.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { CircleCheckIcon, XIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border p-4 shadow-lg\"><div class=\"flex gap-2\"><div class=\"flex grow gap-3\"><CircleCheckIcon class=\"mt-0.5 shrink-0 text-emerald-500\" :size=\"16\" aria-hidden=\"true\" /><div class=\"flex grow flex-col gap-3\"><div class=\"space-y-1\"><p class=\"text-sm font-medium\">Your request was completed!</p><p class=\"text-muted-foreground text-sm\">It demonstrates that the task or request has been processed.\n              </p></div><div class=\"flex gap-2\"><Button size=\"sm\">Learn more</Button></div></div><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><XIcon :size=\"16\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/notification/notification-13.html",
          "target": "components/ui/notification-13.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border p-4 shadow-lg\"><div class=\"flex gap-2\"><div class=\"flex grow gap-3\"><CircleCheckIcon class=\"mt-0.5 shrink-0 text-emerald-500\" size=\"${16}\" aria-hidden=\"true\" /><div class=\"flex grow flex-col gap-3\"><div class=\"space-y-1\"><p class=\"text-sm font-medium\">Your request was completed!</p><p class=\"text-muted-foreground text-sm\">It demonstrates that the task or request has been processed.\n              </p></div><div class=\"flex gap-2\"><Button size=\"sm\">Learn more</Button></div></div><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><XIcon size=\"${16}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/notification/notification-13.wxml",
          "target": "components/ui/notification-13/notification-13.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"bg-background z-50 max-w-[400px] rounded-md border p-4 shadow-lg\"><view class=\"flex gap-2\"><view class=\"flex grow gap-3\"><circlecheckicon class=\"mt-0.5 shrink-0 text-emerald-500\" size=\"{{16}}\" aria-hidden=\"true\" /><view class=\"flex grow flex-col gap-3\"><view class=\"space-y-1\"><text class=\"text-sm font-medium\">Your request was completed!</text><text class=\"text-muted-foreground text-sm\">It demonstrates that the task or request has been processed.\n              </text></view><view class=\"flex gap-2\"><button size=\"sm\">Learn more</button></view></view><button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><xicon size=\"{{16}}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></button></view></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "notification",
          "button",
          "success"
        ],
        "colSpan": 2,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "notification-13",
          "group": "notification",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "notification-13",
              "path": "registry/default/components/notification/notification-13.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "notification-13",
              "path": "registry/default/components/notification/notification-13.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "notification-13",
              "path": "registry/default/components/notification/notification-13.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "notification-13",
              "path": "registry/default/components/notification/notification-13.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "notification",
        "title": "Notification · Dismissible"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "notification"
      ]
    },
    {
      "name": "notification-14",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/notification/notification-14.tsx",
          "type": "registry:component",
          "target": "components/ui/notification-14.tsx",
          "content": "import { Button } from '@timui/react'\nimport { Info, XIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    // To make the notification fixed, add classes like `fixed bottom-4 right-4` to the container element.\n    <div className=\"bg-background z-50 max-w-[400px] rounded-md border p-4 shadow-lg\">\n      <div className=\"flex gap-2\">\n        <div className=\"flex grow gap-3\">\n          <Info className=\"mt-0.5 shrink-0 text-blue-500\" size={16} aria-hidden=\"true\" />\n          <div className=\"flex grow flex-col gap-3\">\n            <div className=\"space-y-1\">\n              <p className=\"text-sm font-medium\">Here is some helpful information!</p>\n              <p className=\"text-muted-foreground text-sm\">\n                It aims to provide clarity or support for better decision-making.\n              </p>\n            </div>\n            <div className=\"flex gap-2\">\n              <Button size=\"sm\">Learn more</Button>\n            </div>\n          </div>\n          <Button\n            variant=\"ghost\"\n            className=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\"\n            aria-label=\"Close notification\"\n          >\n            <XIcon\n              size={16}\n              className=\"opacity-60 transition-opacity group-hover:opacity-100\"\n              aria-hidden=\"true\"\n            />\n          </Button>\n        </div>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/notification/notification-14.vue",
          "target": "components/ui/notification-14.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Info, XIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border p-4 shadow-lg\"><div class=\"flex gap-2\"><div class=\"flex grow gap-3\"><Info class=\"mt-0.5 shrink-0 text-blue-500\" :size=\"16\" aria-hidden=\"true\" /><div class=\"flex grow flex-col gap-3\"><div class=\"space-y-1\"><p class=\"text-sm font-medium\">Here is some helpful information!</p><p class=\"text-muted-foreground text-sm\">It aims to provide clarity or support for better decision-making.\n              </p></div><div class=\"flex gap-2\"><Button size=\"sm\">Learn more</Button></div></div><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><XIcon :size=\"16\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/notification/notification-14.html",
          "target": "components/ui/notification-14.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border p-4 shadow-lg\"><div class=\"flex gap-2\"><div class=\"flex grow gap-3\"><Info class=\"mt-0.5 shrink-0 text-blue-500\" size=\"${16}\" aria-hidden=\"true\" /><div class=\"flex grow flex-col gap-3\"><div class=\"space-y-1\"><p class=\"text-sm font-medium\">Here is some helpful information!</p><p class=\"text-muted-foreground text-sm\">It aims to provide clarity or support for better decision-making.\n              </p></div><div class=\"flex gap-2\"><Button size=\"sm\">Learn more</Button></div></div><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><XIcon size=\"${16}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/notification/notification-14.wxml",
          "target": "components/ui/notification-14/notification-14.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"bg-background z-50 max-w-[400px] rounded-md border p-4 shadow-lg\"><view class=\"flex gap-2\"><view class=\"flex grow gap-3\"><info class=\"mt-0.5 shrink-0 text-blue-500\" size=\"{{16}}\" aria-hidden=\"true\" /><view class=\"flex grow flex-col gap-3\"><view class=\"space-y-1\"><text class=\"text-sm font-medium\">Here is some helpful information!</text><text class=\"text-muted-foreground text-sm\">It aims to provide clarity or support for better decision-making.\n              </text></view><view class=\"flex gap-2\"><button size=\"sm\">Learn more</button></view></view><button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><xicon size=\"{{16}}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></button></view></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "notification",
          "button",
          "info"
        ],
        "colSpan": 2,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "notification-14",
          "group": "notification",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "notification-14",
              "path": "registry/default/components/notification/notification-14.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "notification-14",
              "path": "registry/default/components/notification/notification-14.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "notification-14",
              "path": "registry/default/components/notification/notification-14.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "notification-14",
              "path": "registry/default/components/notification/notification-14.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "notification",
        "title": "Notification · Dismissible"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "notification"
      ]
    },
    {
      "name": "notification-15",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/notification/notification-15.tsx",
          "type": "registry:component",
          "target": "components/ui/notification-15.tsx",
          "content": "import { Button } from '@timui/react'\nimport { XIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    // To make the notification fixed, add classes like `fixed bottom-4 right-4` to the container element.\n    <div className=\"bg-background z-50 max-w-[400px] rounded-md border p-4 shadow-lg\">\n      <div className=\"flex gap-2\">\n        <div className=\"flex grow flex-col gap-3\">\n          <div className=\"space-y-1\">\n            <p className=\"text-sm font-medium\">We Value Your Privacy 🍪</p>\n            <p className=\"text-muted-foreground text-sm\">\n              We use cookies to improve your experience, and show personalized content.\n            </p>\n          </div>\n          <div className=\"flex gap-2\">\n            <Button size=\"sm\">Accept</Button>\n            <Button size=\"sm\" variant=\"outline\">\n              Decline\n            </Button>\n          </div>\n        </div>\n        <Button\n          variant=\"ghost\"\n          className=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\"\n          aria-label=\"Close notification\"\n        >\n          <XIcon\n            size={16}\n            className=\"opacity-60 transition-opacity group-hover:opacity-100\"\n            aria-hidden=\"true\"\n          />\n        </Button>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/notification/notification-15.vue",
          "target": "components/ui/notification-15.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { XIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border p-4 shadow-lg\"><div class=\"flex gap-2\"><div class=\"flex grow flex-col gap-3\"><div class=\"space-y-1\"><p class=\"text-sm font-medium\">We Value Your Privacy 🍪</p><p class=\"text-muted-foreground text-sm\">We use cookies to improve your experience, and show personalized content.\n            </p></div><div class=\"flex gap-2\"><Button size=\"sm\">Accept</Button><Button size=\"sm\" variant=\"outline\">Decline\n            </Button></div></div><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><XIcon :size=\"16\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/notification/notification-15.html",
          "target": "components/ui/notification-15.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border p-4 shadow-lg\"><div class=\"flex gap-2\"><div class=\"flex grow flex-col gap-3\"><div class=\"space-y-1\"><p class=\"text-sm font-medium\">We Value Your Privacy 🍪</p><p class=\"text-muted-foreground text-sm\">We use cookies to improve your experience, and show personalized content.\n            </p></div><div class=\"flex gap-2\"><Button size=\"sm\">Accept</Button><Button size=\"sm\" variant=\"outline\">Decline\n            </Button></div></div><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><XIcon size=\"${16}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/notification/notification-15.wxml",
          "target": "components/ui/notification-15/notification-15.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"bg-background z-50 max-w-[400px] rounded-md border p-4 shadow-lg\"><view class=\"flex gap-2\"><view class=\"flex grow flex-col gap-3\"><view class=\"space-y-1\"><text class=\"text-sm font-medium\">We Value Your Privacy 🍪</text><text class=\"text-muted-foreground text-sm\">We use cookies to improve your experience, and show personalized content.\n            </text></view><view class=\"flex gap-2\"><button size=\"sm\">Accept</button><button size=\"sm\" variant=\"outline\">Decline\n            </button></view></view><button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><xicon size=\"{{16}}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></button></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "notification",
          "button",
          "cookies",
          "gdpr",
          "privacy"
        ],
        "colSpan": 2,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "notification-15",
          "group": "notification",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "notification-15",
              "path": "registry/default/components/notification/notification-15.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "notification-15",
              "path": "registry/default/components/notification/notification-15.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "notification-15",
              "path": "registry/default/components/notification/notification-15.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "notification-15",
              "path": "registry/default/components/notification/notification-15.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "notification",
        "title": "Notification · Dismissible"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "notification"
      ]
    },
    {
      "name": "notification-16",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/notification/notification-16.tsx",
          "type": "registry:component",
          "target": "components/ui/notification-16.tsx",
          "content": "import { Button } from '@timui/react'\nimport { RefreshCwIcon, XIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    // To make the notification fixed, add classes like `fixed bottom-4 right-4` to the container element.\n    <div className=\"bg-background z-50 max-w-[400px] rounded-md border p-4 shadow-lg\">\n      <div className=\"flex gap-3\">\n        <div\n          className=\"flex size-9 shrink-0 items-center justify-center rounded-full border\"\n          aria-hidden=\"true\"\n        >\n          <RefreshCwIcon className=\"opacity-60\" size={16} />\n        </div>\n        <div className=\"flex grow flex-col gap-3\">\n          <div className=\"space-y-1\">\n            <p className=\"text-sm font-medium\">Version 1.4 is now available!</p>\n            <p className=\"text-muted-foreground text-sm\">\n              This update contains several bug fixes and performance improvements.\n            </p>\n          </div>\n          <div className=\"flex gap-2\">\n            <Button size=\"sm\">Install</Button>\n            <Button size=\"sm\" variant=\"link\">\n              Later\n            </Button>\n          </div>\n        </div>\n        <Button\n          variant=\"ghost\"\n          className=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\"\n          aria-label=\"Close notification\"\n        >\n          <XIcon\n            size={16}\n            className=\"opacity-60 transition-opacity group-hover:opacity-100\"\n            aria-hidden=\"true\"\n          />\n        </Button>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/notification/notification-16.vue",
          "target": "components/ui/notification-16.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { RefreshCwIcon, XIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border p-4 shadow-lg\"><div class=\"flex gap-3\"><div class=\"flex size-9 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><RefreshCwIcon class=\"opacity-60\" :size=\"16\" /></div><div class=\"flex grow flex-col gap-3\"><div class=\"space-y-1\"><p class=\"text-sm font-medium\">Version 1.4 is now available!</p><p class=\"text-muted-foreground text-sm\">This update contains several bug fixes and performance improvements.\n            </p></div><div class=\"flex gap-2\"><Button size=\"sm\">Install</Button><Button size=\"sm\" variant=\"link\">Later\n            </Button></div></div><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><XIcon :size=\"16\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/notification/notification-16.html",
          "target": "components/ui/notification-16.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border p-4 shadow-lg\"><div class=\"flex gap-3\"><div class=\"flex size-9 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><RefreshCwIcon class=\"opacity-60\" size=\"${16}\" /></div><div class=\"flex grow flex-col gap-3\"><div class=\"space-y-1\"><p class=\"text-sm font-medium\">Version 1.4 is now available!</p><p class=\"text-muted-foreground text-sm\">This update contains several bug fixes and performance improvements.\n            </p></div><div class=\"flex gap-2\"><Button size=\"sm\">Install</Button><Button size=\"sm\" variant=\"link\">Later\n            </Button></div></div><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><XIcon size=\"${16}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/notification/notification-16.wxml",
          "target": "components/ui/notification-16/notification-16.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"bg-background z-50 max-w-[400px] rounded-md border p-4 shadow-lg\"><view class=\"flex gap-3\"><view class=\"flex size-9 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><refreshcwicon class=\"opacity-60\" size=\"{{16}}\" /></view><view class=\"flex grow flex-col gap-3\"><view class=\"space-y-1\"><text class=\"text-sm font-medium\">Version 1.4 is now available!</text><text class=\"text-muted-foreground text-sm\">This update contains several bug fixes and performance improvements.\n            </text></view><view class=\"flex gap-2\"><button size=\"sm\">Install</button><button size=\"sm\" variant=\"link\">Later\n            </button></view></view><button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><xicon size=\"{{16}}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></button></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "notification",
          "button",
          "info"
        ],
        "colSpan": 2,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "notification-16",
          "group": "notification",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "notification-16",
              "path": "registry/default/components/notification/notification-16.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "notification-16",
              "path": "registry/default/components/notification/notification-16.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "notification-16",
              "path": "registry/default/components/notification/notification-16.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "notification-16",
              "path": "registry/default/components/notification/notification-16.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "notification",
        "title": "Notification · Dismissible"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "notification"
      ]
    },
    {
      "name": "notification-17",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/notification/notification-17.tsx",
          "type": "registry:component",
          "target": "components/ui/notification-17.tsx",
          "content": "import { Button } from '@timui/react'\nimport { XIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    // To make the notification fixed, add classes like `fixed bottom-4 right-4` to the container element.\n    <div className=\"bg-background z-50 max-w-[400px] rounded-md border p-4 shadow-lg\">\n      <div className=\"flex gap-3\">\n        <img\n          className=\"size-9 rounded-full\"\n          src=\"/avatar-32-01.jpg\"\n          width={32}\n          height={32}\n          alt=\"Mary Palmer\"\n        />\n        <div className=\"flex grow flex-col gap-3\">\n          <div className=\"space-y-1\">\n            <p className=\"text-muted-foreground text-sm\">\n              <a className=\"text-foreground font-medium hover:underline\" href=\"#\">\n                Mary Palmer\n              </a>{' '}\n              mentioned you in{' '}\n              <a className=\"text-foreground font-medium hover:underline\" href=\"#\">\n                project-campaign-02\n              </a>\n              .\n            </p>\n            <p className=\"text-muted-foreground text-xs\">2 min ago</p>\n          </div>\n          <div className=\"flex gap-2\">\n            <Button size=\"sm\">Accept</Button>\n            <Button size=\"sm\" variant=\"outline\">\n              Decline\n            </Button>\n          </div>\n        </div>\n        <Button\n          variant=\"ghost\"\n          className=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\"\n          aria-label=\"Close notification\"\n        >\n          <XIcon\n            size={16}\n            className=\"opacity-60 transition-opacity group-hover:opacity-100\"\n            aria-hidden=\"true\"\n          />\n        </Button>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/notification/notification-17.vue",
          "target": "components/ui/notification-17.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { XIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border p-4 shadow-lg\"><div class=\"flex gap-3\"><img class=\"size-9 rounded-full\" src=\"/avatar-32-01.jpg\" :width=\"32\" :height=\"32\" alt=\"Mary Palmer\" /><div class=\"flex grow flex-col gap-3\"><div class=\"space-y-1\"><p class=\"text-muted-foreground text-sm\"><a class=\"text-foreground font-medium hover:underline\" href=\"#\">Mary Palmer\n              </a>{{ ' ' }}mentioned you in{{ ' ' }}<a class=\"text-foreground font-medium hover:underline\" href=\"#\">project-campaign-02\n              </a>.\n            </p><p class=\"text-muted-foreground text-xs\">2 min ago</p></div><div class=\"flex gap-2\"><Button size=\"sm\">Accept</Button><Button size=\"sm\" variant=\"outline\">Decline\n            </Button></div></div><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><XIcon :size=\"16\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/notification/notification-17.html",
          "target": "components/ui/notification-17.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border p-4 shadow-lg\"><div class=\"flex gap-3\"><img class=\"size-9 rounded-full\" src=\"/avatar-32-01.jpg\" width=\"${32}\" height=\"${32}\" alt=\"Mary Palmer\" /><div class=\"flex grow flex-col gap-3\"><div class=\"space-y-1\"><p class=\"text-muted-foreground text-sm\"><a class=\"text-foreground font-medium hover:underline\" href=\"#\">Mary Palmer\n              </a>${' '}mentioned you in${' '}<a class=\"text-foreground font-medium hover:underline\" href=\"#\">project-campaign-02\n              </a>.\n            </p><p class=\"text-muted-foreground text-xs\">2 min ago</p></div><div class=\"flex gap-2\"><Button size=\"sm\">Accept</Button><Button size=\"sm\" variant=\"outline\">Decline\n            </Button></div></div><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><XIcon size=\"${16}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/notification/notification-17.wxml",
          "target": "components/ui/notification-17/notification-17.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"bg-background z-50 max-w-[400px] rounded-md border p-4 shadow-lg\"><view class=\"flex gap-3\"><image class=\"size-9 rounded-full\" src=\"/avatar-32-01.jpg\" width=\"{{32}}\" height=\"{{32}}\" alt=\"Mary Palmer\" /><view class=\"flex grow flex-col gap-3\"><view class=\"space-y-1\"><text class=\"text-muted-foreground text-sm\"><a class=\"text-foreground font-medium hover:underline\" href=\"#\">Mary Palmer\n              </a>{{ ' ' }}mentioned you in{{ ' ' }}<a class=\"text-foreground font-medium hover:underline\" href=\"#\">project-campaign-02\n              </a>.\n            </text><text class=\"text-muted-foreground text-xs\">2 min ago</text></view><view class=\"flex gap-2\"><button size=\"sm\">Accept</button><button size=\"sm\" variant=\"outline\">Decline\n            </button></view></view><button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><xicon size=\"{{16}}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></button></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "notification",
          "button"
        ],
        "colSpan": 2,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "notification-17",
          "group": "notification",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "notification-17",
              "path": "registry/default/components/notification/notification-17.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "notification-17",
              "path": "registry/default/components/notification/notification-17.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "notification-17",
              "path": "registry/default/components/notification/notification-17.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "notification-17",
              "path": "registry/default/components/notification/notification-17.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "notification",
        "title": "Notification · Dismissible"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "notification"
      ]
    },
    {
      "name": "notification-18",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/notification/notification-18.tsx",
          "type": "registry:component",
          "target": "components/ui/notification-18.tsx",
          "content": "import { Button } from '@timui/react'\nimport { RadioIcon, XIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    // To make the notification fixed, add classes like `fixed bottom-4 right-4` to the container element.\n    <div className=\"bg-background z-50 max-w-[400px] rounded-md border p-4 shadow-lg\">\n      <div className=\"flex items-center gap-2\">\n        <div\n          className=\"flex size-9 shrink-0 items-center justify-center rounded-full border\"\n          aria-hidden=\"true\"\n        >\n          <RadioIcon className=\"opacity-60\" size={16} />\n        </div>\n        <div className=\"flex grow items-center gap-12\">\n          <div className=\"space-y-1\">\n            <p className=\"text-sm font-medium\">Live in 27 hours</p>\n            <p className=\"text-muted-foreground text-xs\">November 20 at 8:00 PM.</p>\n          </div>\n          <Button size=\"sm\">Notify me</Button>\n        </div>\n        <Button\n          variant=\"ghost\"\n          className=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\"\n          aria-label=\"Close notification\"\n        >\n          <XIcon\n            size={16}\n            className=\"opacity-60 transition-opacity group-hover:opacity-100\"\n            aria-hidden=\"true\"\n          />\n        </Button>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/notification/notification-18.vue",
          "target": "components/ui/notification-18.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { RadioIcon, XIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border p-4 shadow-lg\"><div class=\"flex items-center gap-2\"><div class=\"flex size-9 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><RadioIcon class=\"opacity-60\" :size=\"16\" /></div><div class=\"flex grow items-center gap-12\"><div class=\"space-y-1\"><p class=\"text-sm font-medium\">Live in 27 hours</p><p class=\"text-muted-foreground text-xs\">November 20 at 8:00 PM.</p></div><Button size=\"sm\">Notify me</Button></div><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><XIcon :size=\"16\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/notification/notification-18.html",
          "target": "components/ui/notification-18.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"bg-background z-50 max-w-[400px] rounded-md border p-4 shadow-lg\"><div class=\"flex items-center gap-2\"><div class=\"flex size-9 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><RadioIcon class=\"opacity-60\" size=\"${16}\" /></div><div class=\"flex grow items-center gap-12\"><div class=\"space-y-1\"><p class=\"text-sm font-medium\">Live in 27 hours</p><p class=\"text-muted-foreground text-xs\">November 20 at 8:00 PM.</p></div><Button size=\"sm\">Notify me</Button></div><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><XIcon size=\"${16}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/notification/notification-18.wxml",
          "target": "components/ui/notification-18/notification-18.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"bg-background z-50 max-w-[400px] rounded-md border p-4 shadow-lg\"><view class=\"flex items-center gap-2\"><view class=\"flex size-9 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><radioicon class=\"opacity-60\" size=\"{{16}}\" /></view><view class=\"flex grow items-center gap-12\"><view class=\"space-y-1\"><text class=\"text-sm font-medium\">Live in 27 hours</text><text class=\"text-muted-foreground text-xs\">November 20 at 8:00 PM.</text></view><button size=\"sm\">Notify me</button></view><button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><xicon size=\"{{16}}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></button></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "notification",
          "button"
        ],
        "colSpan": 2,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "notification-18",
          "group": "notification",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "notification-18",
              "path": "registry/default/components/notification/notification-18.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "notification-18",
              "path": "registry/default/components/notification/notification-18.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "notification-18",
              "path": "registry/default/components/notification/notification-18.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "notification-18",
              "path": "registry/default/components/notification/notification-18.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "notification",
        "title": "Notification · Dismissible"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "notification"
      ]
    },
    {
      "name": "notification-19",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/toast.json"
      ],
      "files": [
        {
          "path": "registry/default/components/notification/notification-19.tsx",
          "type": "registry:component",
          "target": "components/ui/notification-19.tsx",
          "content": "'use client'\n\nimport { Button, ToastAction } from '@timui/react'\n\nimport { useToast } from '@/registry/default/hooks/use-toast'\n\nexport default function Component() {\n  const { toast } = useToast()\n\n  return (\n    <Button\n      variant=\"outline\"\n      onClick={() => {\n        toast({\n          title: \"We couldn't complete your request!\",\n          description: 'There was a problem with your request.',\n          action: <ToastAction altText=\"Try again\">Try again</ToastAction>,\n        })\n      }}\n    >\n      Show toast\n    </Button>\n  )\n}\n"
        },
        {
          "path": "registry/default/hooks/use-toast.ts",
          "type": "registry:hook",
          "target": "components/ui/notification-19/use-toast.ts",
          "content": "'use client'\n\n// Inspired by react-hot-toast library\nimport * as React from 'react'\n\nimport type { ToastActionElement, ToastProps } from '../components/ui/toast'\n\nconst TOAST_LIMIT = 1\nconst TOAST_REMOVE_DELAY = 1000000\n\ntype ToasterToast = ToastProps & {\n  id: string\n  title?: React.ReactNode\n  description?: React.ReactNode\n  action?: ToastActionElement\n}\n\nconst actionTypes = {\n  ADD_TOAST: 'ADD_TOAST',\n  UPDATE_TOAST: 'UPDATE_TOAST',\n  DISMISS_TOAST: 'DISMISS_TOAST',\n  REMOVE_TOAST: 'REMOVE_TOAST',\n} as const\n\nlet count = 0\n\nfunction genId() {\n  count = (count + 1) % Number.MAX_SAFE_INTEGER\n  return count.toString()\n}\n\ntype ActionType = typeof actionTypes\n\ntype Action =\n  | {\n      type: ActionType['ADD_TOAST']\n      toast: ToasterToast\n    }\n  | {\n      type: ActionType['UPDATE_TOAST']\n      toast: Partial<ToasterToast>\n    }\n  | {\n      type: ActionType['DISMISS_TOAST']\n      toastId?: ToasterToast['id']\n    }\n  | {\n      type: ActionType['REMOVE_TOAST']\n      toastId?: ToasterToast['id']\n    }\n\ninterface State {\n  toasts: ToasterToast[]\n}\n\nconst toastTimeouts = new Map<string, ReturnType<typeof setTimeout>>()\n\nconst addToRemoveQueue = (toastId: string) => {\n  if (toastTimeouts.has(toastId)) {\n    return\n  }\n\n  const timeout = setTimeout(() => {\n    toastTimeouts.delete(toastId)\n    dispatch({\n      type: 'REMOVE_TOAST',\n      toastId: toastId,\n    })\n  }, TOAST_REMOVE_DELAY)\n\n  toastTimeouts.set(toastId, timeout)\n}\n\nexport const reducer = (state: State, action: Action): State => {\n  switch (action.type) {\n    case 'ADD_TOAST':\n      return {\n        ...state,\n        toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT),\n      }\n\n    case 'UPDATE_TOAST':\n      return {\n        ...state,\n        toasts: state.toasts.map((t) => (t.id === action.toast.id ? { ...t, ...action.toast } : t)),\n      }\n\n    case 'DISMISS_TOAST': {\n      const { toastId } = action\n\n      // ! Side effects ! - This could be extracted into a dismissToast() action,\n      // but I'll keep it here for simplicity\n      if (toastId) {\n        addToRemoveQueue(toastId)\n      } else {\n        state.toasts.forEach((toast) => {\n          addToRemoveQueue(toast.id)\n        })\n      }\n\n      return {\n        ...state,\n        toasts: state.toasts.map((t) =>\n          t.id === toastId || toastId === undefined\n            ? {\n                ...t,\n                open: false,\n              }\n            : t\n        ),\n      }\n    }\n    case 'REMOVE_TOAST':\n      if (action.toastId === undefined) {\n        return {\n          ...state,\n          toasts: [],\n        }\n      }\n      return {\n        ...state,\n        toasts: state.toasts.filter((t) => t.id !== action.toastId),\n      }\n  }\n}\n\nconst listeners: Array<(state: State) => void> = []\n\nlet memoryState: State = { toasts: [] }\n\nfunction dispatch(action: Action) {\n  memoryState = reducer(memoryState, action)\n  listeners.forEach((listener) => {\n    listener(memoryState)\n  })\n}\n\ntype Toast = Omit<ToasterToast, 'id'>\n\nfunction toast({ ...props }: Toast) {\n  const id = genId()\n\n  const update = (props: ToasterToast) =>\n    dispatch({\n      type: 'UPDATE_TOAST',\n      toast: { ...props, id },\n    })\n  const dismiss = () => dispatch({ type: 'DISMISS_TOAST', toastId: id })\n\n  dispatch({\n    type: 'ADD_TOAST',\n    toast: {\n      ...props,\n      id,\n      open: true,\n      onOpenChange: (open) => {\n        if (!open) dismiss()\n      },\n    },\n  })\n\n  return {\n    id: id,\n    dismiss,\n    update,\n  }\n}\n\nfunction useToast() {\n  const [state, setState] = React.useState<State>(memoryState)\n\n  React.useEffect(() => {\n    listeners.push(setState)\n    return () => {\n      const index = listeners.indexOf(setState)\n      if (index > -1) {\n        listeners.splice(index, 1)\n      }\n    }\n  }, [state])\n\n  return {\n    ...state,\n    toast,\n    dismiss: (toastId?: string) => dispatch({ type: 'DISMISS_TOAST', toastId }),\n  }\n}\n\nexport { toast, useToast }\n"
        },
        {
          "path": "registry/default/components/notification/notification-19.vue",
          "target": "components/ui/notification-19.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { h } from 'vue';\nimport { Button } from '@timui/vue';\nimport { ToastAction } from '@timui/vue';\nimport { useToast } from '@/registry/default/hooks/use-toast-vue';\n\nconst { toast } = useToast();\n\nconst TryAgainAction = () =>\n  h(ToastAction, { altText: 'Try again' }, { default: () => 'Try again' });\n\nfunction handleShowToast() {\n  toast({\n    title: \"We couldn't complete your request!\",\n    description: 'There was a problem with your request.',\n    action: TryAgainAction,\n  });\n}\n</script>\n\n<template>\n  <Button variant=\"outline\" @click=\"handleShowToast\">Show toast</Button>\n</template>\n"
        },
        {
          "path": "registry/default/components/notification/notification-19.html",
          "target": "components/ui/notification-19.html",
          "type": "registry:component",
          "content": "<template>\n  <Button variant=\"outline\" on-click=\"${() => {\n        toast({\n          title: \"We couldn't complete your request!\",\n          description: 'There was a problem with your request.',\n          action: <ToastAction altText=\"Try again\">Try again</ToastAction>,\n        })\n      }}\">Show toast\n    </Button>\n</template>"
        },
        {
          "path": "registry/default/components/notification/notification-19.wxml",
          "target": "components/ui/notification-19/notification-19.wxml",
          "type": "registry:component",
          "content": "<view>\n  <button variant=\"outline\" bindtap=\"{\n        toast({\n          title: \"We couldn't complete your request!\",\n          description: 'There was a problem with your request.',\n          action: <ToastAction altText=\"Try again\">Try again</ToastAction>,\n        })\n      }\">Show toast\n    </button>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "notification",
          "toast",
          "radix"
        ],
        "colSpan": 2,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "notification-19",
          "group": "notification",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "notification-19",
              "path": "registry/default/components/notification/notification-19.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "notification-19",
              "path": "registry/default/components/notification/notification-19.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "notification-19",
              "path": "registry/default/components/notification/notification-19.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "notification-19",
              "path": "registry/default/components/notification/notification-19.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "notification",
        "title": "Notification · Outlined Style"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "notification"
      ]
    },
    {
      "name": "notification-20",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/toast.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/notification/notification-20.tsx",
          "type": "registry:component",
          "target": "components/ui/notification-20.tsx",
          "content": "'use client'\n\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport {\n  Button,\n  Toast,\n  ToastAction,\n  ToastClose,\n  ToastDescription,\n  ToastProvider,\n  ToastTitle,\n  ToastViewport,\n} from '@timui/react'\nimport { CircleCheckIcon, XIcon } from 'lucide-react'\n\ninterface UseProgressTimerProps {\n  duration: number\n  interval?: number\n  onComplete?: () => void\n}\n\nfunction useProgressTimer({ duration, interval = 100, onComplete }: UseProgressTimerProps) {\n  const [progress, setProgress] = useState(duration)\n  const timerRef = useRef(0)\n  const timerState = useRef({\n    startTime: 0,\n    remaining: duration,\n    isPaused: false,\n  })\n\n  const cleanup = useCallback(() => {\n    window.clearInterval(timerRef.current)\n  }, [])\n\n  const reset = useCallback(() => {\n    cleanup()\n    setProgress(duration)\n    timerState.current = {\n      startTime: 0,\n      remaining: duration,\n      isPaused: false,\n    }\n  }, [duration, cleanup])\n\n  const start = useCallback(() => {\n    const state = timerState.current\n    state.startTime = Date.now()\n    state.isPaused = false\n\n    timerRef.current = window.setInterval(() => {\n      const elapsedTime = Date.now() - state.startTime\n      const remaining = Math.max(0, state.remaining - elapsedTime)\n\n      setProgress(remaining)\n\n      if (remaining <= 0) {\n        cleanup()\n        onComplete?.()\n      }\n    }, interval)\n  }, [interval, cleanup, onComplete])\n\n  const pause = useCallback(() => {\n    const state = timerState.current\n    if (!state.isPaused) {\n      cleanup()\n      state.remaining = Math.max(0, state.remaining - (Date.now() - state.startTime))\n      state.isPaused = true\n    }\n  }, [cleanup])\n\n  const resume = useCallback(() => {\n    const state = timerState.current\n    if (state.isPaused && state.remaining > 0) {\n      start()\n    }\n  }, [start])\n\n  useEffect(() => {\n    return cleanup\n  }, [cleanup])\n\n  return {\n    progress,\n    start,\n    pause,\n    resume,\n    reset,\n  }\n}\n\nexport default function Component() {\n  const [open, setOpen] = useState(false)\n  const toastDuration = 5000\n  const { progress, start, pause, resume, reset } = useProgressTimer({\n    duration: toastDuration,\n    onComplete: () => setOpen(false),\n  })\n\n  const handleOpenChange = useCallback(\n    (isOpen: boolean) => {\n      setOpen(isOpen)\n      if (isOpen) {\n        reset()\n        start()\n      }\n    },\n    [reset, start]\n  )\n\n  const handleButtonClick = useCallback(() => {\n    if (open) {\n      setOpen(false)\n      // Wait for the close animation to finish\n      window.setTimeout(() => {\n        handleOpenChange(true)\n      }, 150)\n    } else {\n      handleOpenChange(true)\n    }\n  }, [open, handleOpenChange])\n\n  return (\n    <ToastProvider swipeDirection=\"left\">\n      <Button variant=\"outline\" onClick={handleButtonClick}>\n        Custom toast\n      </Button>\n      <Toast open={open} onOpenChange={handleOpenChange} onPause={pause} onResume={resume}>\n        <div className=\"flex w-full justify-between gap-3\">\n          <CircleCheckIcon\n            className=\"mt-0.5 shrink-0 text-emerald-500\"\n            size={16}\n            aria-hidden=\"true\"\n          />\n          <div className=\"flex grow flex-col gap-3\">\n            <div className=\"space-y-1\">\n              <ToastTitle>Your request was completed!</ToastTitle>\n              <ToastDescription>\n                It demonstrates that the task or request has been processed.\n              </ToastDescription>\n            </div>\n            <div>\n              <ToastAction altText=\"Undo changes\" asChild>\n                <Button size=\"sm\">Undo changes</Button>\n              </ToastAction>\n            </div>\n          </div>\n          <ToastClose asChild>\n            <Button\n              variant=\"ghost\"\n              className=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\"\n              aria-label=\"Close notification\"\n            >\n              <XIcon\n                size={16}\n                className=\"opacity-60 transition-opacity group-hover:opacity-100\"\n                aria-hidden=\"true\"\n              />\n            </Button>\n          </ToastClose>\n        </div>\n        <div className=\"contents\" aria-hidden=\"true\">\n          <div\n            className=\"pointer-events-none absolute bottom-0 left-0 h-1 w-full bg-emerald-500\"\n            style={{\n              width: `${(progress / toastDuration) * 100}%`,\n              transition: 'width 100ms linear',\n            }}\n          />\n        </div>\n      </Toast>\n      <ToastViewport className=\"sm:right-auto sm:left-0\" />\n    </ToastProvider>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/notification/notification-20.vue",
          "target": "components/ui/notification-20.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { onBeforeUnmount, ref } from 'vue'\nimport { CircleCheckIcon, XIcon } from 'lucide-vue-next'\nimport { Button } from '@timui/vue'\nimport { Toast } from '@timui/vue'\nimport { ToastAction } from '@timui/vue'\nimport { ToastClose } from '@timui/vue'\nimport { ToastDescription } from '@timui/vue'\nimport { ToastProvider } from '@timui/vue'\nimport { ToastTitle } from '@timui/vue'\nimport { ToastViewport } from '@timui/vue'\n\nconst open = ref(false)\nconst toastDuration = 5000\nconst progress = ref(toastDuration)\nconst timerRef = ref<number | null>(null)\nconst timerState = ref({\n  startTime: 0,\n  remaining: toastDuration,\n  isPaused: false,\n})\n\nconst cleanup = () => {\n  if (timerRef.value !== null) {\n    window.clearInterval(timerRef.value)\n    timerRef.value = null\n  }\n}\n\nconst reset = () => {\n  cleanup()\n  progress.value = toastDuration\n  timerState.value = {\n    startTime: 0,\n    remaining: toastDuration,\n    isPaused: false,\n  }\n}\n\nconst start = () => {\n  const state = timerState.value\n  state.startTime = Date.now()\n  state.isPaused = false\n  cleanup()\n\n  timerRef.value = window.setInterval(() => {\n    const elapsed = Date.now() - state.startTime\n    const remaining = Math.max(0, state.remaining - elapsed)\n    progress.value = remaining\n\n    if (remaining <= 0) {\n      cleanup()\n      open.value = false\n    }\n  }, 100)\n}\n\nconst pause = () => {\n  const state = timerState.value\n  if (!state.isPaused) {\n    cleanup()\n    state.remaining = Math.max(0, state.remaining - (Date.now() - state.startTime))\n    state.isPaused = true\n  }\n}\n\nconst resume = () => {\n  const state = timerState.value\n  if (state.isPaused && state.remaining > 0) {\n    start()\n  }\n}\n\nconst handleOpenChange = (isOpen: boolean) => {\n  open.value = isOpen\n  if (isOpen) {\n    reset()\n    start()\n  } else {\n    cleanup()\n  }\n}\n\nconst handleButtonClick = () => {\n  if (open.value) {\n    open.value = false\n    window.setTimeout(() => {\n      handleOpenChange(true)\n    }, 150)\n    return\n  }\n  handleOpenChange(true)\n}\n\nonBeforeUnmount(() => {\n  cleanup()\n})\n</script>\n\n<template>\n  <ToastProvider swipeDirection=\"left\">\n    <Button variant=\"outline\" @click=\"handleButtonClick\">Custom toast</Button>\n    <Toast :open=\"open\" @update:open=\"handleOpenChange\" :onPause=\"pause\" :onResume=\"resume\">\n      <div class=\"flex w-full justify-between gap-3\">\n        <CircleCheckIcon class=\"mt-0.5 shrink-0 text-emerald-500\" :size=\"16\" aria-hidden=\"true\" />\n        <div class=\"flex grow flex-col gap-3\">\n          <div class=\"space-y-1\">\n            <ToastTitle>Your request was completed!</ToastTitle>\n            <ToastDescription>It demonstrates that the task or request has been processed.</ToastDescription>\n          </div>\n          <div>\n            <ToastAction altText=\"Undo changes\" as-child>\n              <Button size=\"sm\">Undo changes</Button>\n            </ToastAction>\n          </div>\n        </div>\n        <ToastClose as-child>\n          <Button\n            variant=\"ghost\"\n            class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\"\n            aria-label=\"Close notification\"\n          >\n            <XIcon\n              :size=\"16\"\n              class=\"opacity-60 transition-opacity group-hover:opacity-100\"\n              aria-hidden=\"true\"\n            />\n          </Button>\n        </ToastClose>\n      </div>\n      <div class=\"contents\" aria-hidden=\"true\">\n        <div\n          class=\"pointer-events-none absolute bottom-0 left-0 h-1 w-full bg-emerald-500\"\n          :style=\"{\n            width: `${(progress / toastDuration) * 100}%`,\n            transition: 'width 100ms linear',\n          }\"\n        />\n      </div>\n    </Toast>\n    <ToastViewport class=\"sm:right-auto sm:left-0\" />\n  </ToastProvider>\n</template>\n"
        },
        {
          "path": "registry/default/components/notification/notification-20.html",
          "target": "components/ui/notification-20.html",
          "type": "registry:component",
          "content": "<template>\n  <ToastProvider swipedirection=\"left\"><Button variant=\"outline\" on-click=\"${handleButtonClick}\">Custom toast\n      </Button><Toast open=\"${open}\" on-open-change=\"${handleOpenChange}\" onpause=\"${pause}\" onresume=\"${resume}\"><div class=\"flex w-full justify-between gap-3\"><CircleCheckIcon class=\"mt-0.5 shrink-0 text-emerald-500\" size=\"${16}\" aria-hidden=\"true\" /><div class=\"flex grow flex-col gap-3\"><div class=\"space-y-1\"><ToastTitle>Your request was completed!</ToastTitle><ToastDescription>It demonstrates that the task or request has been processed.\n              </ToastDescription></div><div><ToastAction alttext=\"Undo changes\" aschild><Button size=\"sm\">Undo changes</Button></ToastAction></div></div><ToastClose aschild><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><XIcon size=\"${16}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></Button></ToastClose></div><div class=\"contents\" aria-hidden=\"true\"><div class=\"pointer-events-none absolute bottom-0 left-0 h-1 w-full bg-emerald-500\" style=\"${{\n              width: `${(progress / toastDuration) * 100}%`,\n              transition: 'width 100ms linear',\n            }}\" /></div></Toast><ToastViewport class=\"sm:right-auto sm:left-0\" /></ToastProvider>\n</template>"
        },
        {
          "path": "registry/default/components/notification/notification-20.wxml",
          "target": "components/ui/notification-20/notification-20.wxml",
          "type": "registry:component",
          "content": "<view>\n  <toastprovider swipedirection=\"left\"><button variant=\"outline\" bindtap=\"handleButtonClick\">Custom toast\n      </button><toast open=\"{{open}}\" bindchange=\"handleOpenChange\" onpause=\"{{pause}}\" onresume=\"{{resume}}\"><view class=\"flex w-full justify-between gap-3\"><circlecheckicon class=\"mt-0.5 shrink-0 text-emerald-500\" size=\"{{16}}\" aria-hidden=\"true\" /><view class=\"flex grow flex-col gap-3\"><view class=\"space-y-1\"><toasttitle>Your request was completed!</toasttitle><toastdescription>It demonstrates that the task or request has been processed.\n              </toastdescription></view><view><toastaction alttext=\"Undo changes\" aschild><button size=\"sm\">Undo changes</button></toastaction></view></view><toastclose aschild><button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" aria-label=\"Close notification\"><xicon size=\"{{16}}\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\" /></button></toastclose></view><view class=\"contents\" aria-hidden=\"true\"><div class=\"pointer-events-none absolute bottom-0 left-0 h-1 w-full bg-emerald-500\" style=\"{{{\n              width: `${(progress / toastDuration) * 100}%`,\n              transition: 'width 100ms linear',\n            }}}\" /></view></toast><toastviewport class=\"sm:right-auto sm:left-0\" /></toastprovider>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "notification",
          "toast",
          "success",
          "radix"
        ],
        "colSpan": 2,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "notification-20",
          "group": "notification",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "notification-20",
              "path": "registry/default/components/notification/notification-20.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "notification-20",
              "path": "registry/default/components/notification/notification-20.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "notification-20",
              "path": "registry/default/components/notification/notification-20.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "notification-20",
              "path": "registry/default/components/notification/notification-20.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "notification",
        "title": "Notification · Dismissible"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "notification"
      ]
    },
    {
      "name": "notification-21",
      "type": "registry:component",
      "dependencies": [
        "@timui/react"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "sonner"
      ],
      "files": [
        {
          "path": "registry/default/components/notification/notification-21.tsx",
          "type": "registry:component",
          "target": "components/ui/notification-21.tsx",
          "content": "'use client'\n\nimport { Button } from '@timui/react'\nimport { toast } from 'sonner'\n\nexport default function Component() {\n  return (\n    <Button\n      variant=\"outline\"\n      onClick={() => {\n        toast('Your request was completed!', {\n          description: 'It was a long journey, but we made it!',\n          action: {\n            label: 'Undo',\n            onClick: () => console.log('Undo'),\n          },\n        })\n      }}\n    >\n      Show sonner\n    </Button>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/notification/notification-21.vue",
          "target": "components/ui/notification-21.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { h } from 'vue'\nimport { Button, ToastAction, toast } from '@timui/vue'\n\nconst handleUndo = () => {\n  console.log('Undo')\n}\n\nconst showToast = () => {\n  toast({\n    title: 'Your request was completed!',\n    description: 'It was a long journey, but we made it!',\n    action: h(\n      ToastAction,\n      {\n        altText: 'Undo',\n        onClick: handleUndo,\n      },\n      () => 'Undo'\n    ),\n  })\n}\n</script>\n\n<template>\n  <Button variant=\"outline\" @click=\"showToast\">Show toast</Button>\n</template>\n"
        },
        {
          "path": "registry/default/components/notification/notification-21.html",
          "target": "components/ui/notification-21.html",
          "type": "registry:component",
          "content": "<template>\n  <Button variant=\"outline\" on-click=\"${() => {\n        toast('Your request was completed!', {\n          description: 'It was a long journey, but we made it!',\n          action: {\n            label: 'Undo',\n            onClick: () => console.log('Undo'),\n          },\n        })\n      }}\">Show sonner\n    </Button>\n</template>"
        },
        {
          "path": "registry/default/components/notification/notification-21.wxml",
          "target": "components/ui/notification-21/notification-21.wxml",
          "type": "registry:component",
          "content": "<view>\n  <button variant=\"outline\" bindtap=\"{\n        toast('Your request was completed!', {\n          description: 'It was a long journey, but we made it!',\n          action: {\n            label: 'Undo',\n            onClick: () => console.log('Undo'),\n          },\n        })\n      }\">Show sonner\n    </button>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "notification",
          "toast",
          "sonner",
          "radix"
        ],
        "colSpan": 2,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "notification-21",
          "group": "notification",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "notification-21",
              "path": "registry/default/components/notification/notification-21.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "notification-21",
              "path": "registry/default/components/notification/notification-21.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "notification-21",
              "path": "registry/default/components/notification/notification-21.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "notification-21",
              "path": "registry/default/components/notification/notification-21.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "sonner"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "notification",
        "title": "Notification · Outlined Style"
      },
      "categories": [
        "notification"
      ]
    },
    {
      "name": "notification-22",
      "type": "registry:component",
      "dependencies": [
        "@timui/react"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react",
        "sonner"
      ],
      "files": [
        {
          "path": "registry/default/components/notification/notification-22.tsx",
          "type": "registry:component",
          "target": "components/ui/notification-22.tsx",
          "content": "'use client'\n\nimport { Button } from '@timui/react'\nimport { CircleCheckIcon, XIcon } from 'lucide-react'\nimport { toast } from 'sonner'\n\nexport default function Component() {\n  return (\n    <Button\n      variant=\"outline\"\n      onClick={() => {\n        toast.custom((t) => (\n          <div className=\"bg-background text-foreground w-full rounded-md border px-4 py-3 shadow-lg sm:w-[var(--width)]\">\n            <div className=\"flex gap-2\">\n              <div className=\"flex grow gap-3\">\n                <CircleCheckIcon\n                  className=\"mt-0.5 shrink-0 text-emerald-500\"\n                  size={16}\n                  aria-hidden=\"true\"\n                />\n                <div className=\"flex grow justify-between gap-12\">\n                  <p className=\"text-sm\">Message sent</p>\n                  <div className=\"text-sm whitespace-nowrap\">\n                    <button className=\"text-sm font-medium hover:underline\">View</button>{' '}\n                    <span className=\"text-muted-foreground mx-1\">·</span>{' '}\n                    <button\n                      className=\"text-sm font-medium hover:underline\"\n                      onClick={() => toast.dismiss(t)}\n                    >\n                      Undo\n                    </button>\n                  </div>\n                </div>\n              </div>\n              <Button\n                variant=\"ghost\"\n                className=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\"\n                onClick={() => toast.dismiss(t)}\n                aria-label=\"Close banner\"\n              >\n                <XIcon\n                  size={16}\n                  className=\"opacity-60 transition-opacity group-hover:opacity-100\"\n                  aria-hidden=\"true\"\n                />\n              </Button>\n            </div>\n          </div>\n        ))\n      }}\n    >\n      Custom sonner\n    </Button>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/notification/notification-22.vue",
          "target": "components/ui/notification-22.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { h } from 'vue'\nimport { Button, ToastAction, toast } from '@timui/vue'\n\nfunction showCustomToast() {\n  toast({\n    title: 'Message sent',\n    description: 'It was a long journey, but we made it!',\n    action: h(\n      ToastAction,\n      {\n        altText: 'Undo',\n        onClick: () =>\n          toast({\n            title: 'Undo clicked',\n          }),\n      },\n      () => 'Undo'\n    ),\n  })\n}\n</script>\n\n<template>\n  <Button variant=\"outline\" @click=\"showCustomToast\">Custom toast</Button>\n</template>\n"
        },
        {
          "path": "registry/default/components/notification/notification-22.html",
          "target": "components/ui/notification-22.html",
          "type": "registry:component",
          "content": "<template>\n  <Button variant=\"outline\" on-click=\"${() => {\n        toast.custom((t) => (\n          <div className=\"bg-background text-foreground w-full rounded-md border px-4 py-3 shadow-lg sm:w-[var(--width)]\">\n            <div className=\"flex gap-2\">\n              <div className=\"flex grow gap-3\">\n                <CircleCheckIcon\n                  className=\"mt-0.5 shrink-0 text-emerald-500\"\n                  size={16}\n                  aria-hidden=\"true\"\n                />\n                <div className=\"flex grow justify-between gap-12\">\n                  <p className=\"text-sm\">Message sent</p>\n                  <div className=\"text-sm whitespace-nowrap\">\n                    <button className=\"text-sm font-medium hover:underline\">View</button>{' '}\n                    <span className=\"text-muted-foreground mx-1\">·</span>{' '}\n                    <button\n                      className=\"text-sm font-medium hover:underline\"\n                      onClick={() => toast.dismiss(t)}\n                    >\n                      Undo\n                    </button>\n                  </div>\n                </div>\n              </div>\n              <Button\n                variant=\"ghost\"\n                className=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\"\n                onClick={() => toast.dismiss(t)}\n                aria-label=\"Close banner\"\n              >\n                <XIcon\n                  size={16}\n                  className=\"opacity-60 transition-opacity group-hover:opacity-100\"\n                  aria-hidden=\"true\"\n                />\n              </Button>\n            </div>\n          </div>\n        ))\n      }}\">Custom sonner\n    </Button>\n</template>"
        },
        {
          "path": "registry/default/components/notification/notification-22.wxml",
          "target": "components/ui/notification-22/notification-22.wxml",
          "type": "registry:component",
          "content": "<view>\n  <button variant=\"outline\" bindtap=\"{\n        toast.custom((t) => (\n          <div className=\"bg-background text-foreground w-full rounded-md border px-4 py-3 shadow-lg sm:w-[var(--width)]\">\n            <div className=\"flex gap-2\">\n              <div className=\"flex grow gap-3\">\n                <CircleCheckIcon\n                  className=\"mt-0.5 shrink-0 text-emerald-500\"\n                  size={16}\n                  aria-hidden=\"true\"\n                />\n                <div className=\"flex grow justify-between gap-12\">\n                  <p className=\"text-sm\">Message sent</p>\n                  <div className=\"text-sm whitespace-nowrap\">\n                    <button className=\"text-sm font-medium hover:underline\">View</button>{' '}\n                    <span className=\"text-muted-foreground mx-1\">·</span>{' '}\n                    <button\n                      className=\"text-sm font-medium hover:underline\"\n                      onClick={() => toast.dismiss(t)}\n                    >\n                      Undo\n                    </button>\n                  </div>\n                </div>\n              </div>\n              <Button\n                variant=\"ghost\"\n                className=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\"\n                onClick={() => toast.dismiss(t)}\n                aria-label=\"Close banner\"\n              >\n                <XIcon\n                  size={16}\n                  className=\"opacity-60 transition-opacity group-hover:opacity-100\"\n                  aria-hidden=\"true\"\n                />\n              </Button>\n            </div>\n          </div>\n        ))\n      }\">Custom sonner\n    </button>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "notification",
          "toast",
          "sonner",
          "success",
          "radix"
        ],
        "colSpan": 2,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "notification-22",
          "group": "notification",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "notification-22",
              "path": "registry/default/components/notification/notification-22.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "notification-22",
              "path": "registry/default/components/notification/notification-22.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "notification-22",
              "path": "registry/default/components/notification/notification-22.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "notification-22",
              "path": "registry/default/components/notification/notification-22.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react",
              "sonner"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "notification",
        "title": "Notification · Dismissible"
      },
      "categories": [
        "notification"
      ]
    },
    {
      "name": "banner-01",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "files": [
        {
          "path": "registry/default/components/banner/banner-01.tsx",
          "type": "registry:component",
          "target": "components/ui/banner-01.tsx",
          "content": "import { Banner, BannerActions, BannerContent, BannerDescription, Button } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Banner className=\"bg-background z-50 rounded-md border px-4 py-3 shadow-lg\">\n      <BannerContent className=\"flex-col justify-between gap-3 md:flex-row md:items-center\">\n        <BannerDescription className=\"text-sm text-foreground\">\n          We use cookies to improve your experience, analyze site usage, and show personalized\n          content.\n        </BannerDescription>\n        <BannerActions className=\"flex gap-2 max-md:flex-wrap\">\n          <Button size=\"sm\">Accept</Button>\n          <Button variant=\"outline\" size=\"sm\">\n            Decline\n          </Button>\n        </BannerActions>\n      </BannerContent>\n    </Banner>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/banner/banner-01.vue",
          "target": "components/ui/banner-01.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Banner } from '@timui/vue';\nimport { BannerActions } from '@timui/vue';\nimport { BannerContent } from '@timui/vue';\nimport { BannerDescription } from '@timui/vue';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Banner class=\"bg-background z-50 rounded-md border px-4 py-3 shadow-lg\"><BannerContent class=\"flex-col justify-between gap-3 md:flex-row md:items-center\"><BannerDescription class=\"text-sm text-foreground\">We use cookies to improve your experience, analyze site usage, and show personalized\n          content.\n        </BannerDescription><BannerActions class=\"flex gap-2 max-md:flex-wrap\"><Button size=\"sm\">Accept</Button><Button variant=\"outline\" size=\"sm\">Decline\n          </Button></BannerActions></BannerContent></Banner>\n</template>\n"
        },
        {
          "path": "registry/default/components/banner/banner-01.html",
          "target": "components/ui/banner-01.html",
          "type": "registry:component",
          "content": "<template>\n  <Banner class=\"bg-background z-50 rounded-md border px-4 py-3 shadow-lg\"><BannerContent class=\"flex-col justify-between gap-3 md:flex-row md:items-center\"><BannerDescription class=\"text-sm text-foreground\">We use cookies to improve your experience, analyze site usage, and show personalized\n          content.\n        </BannerDescription><BannerActions class=\"flex gap-2 max-md:flex-wrap\"><Button size=\"sm\">Accept</Button><Button variant=\"outline\" size=\"sm\">Decline\n          </Button></BannerActions></BannerContent></Banner>\n</template>"
        },
        {
          "path": "registry/default/components/banner/banner-01.wxml",
          "target": "components/ui/banner-01/banner-01.wxml",
          "type": "registry:component",
          "content": "<view>\n  <banner class=\"bg-background z-50 rounded-md border px-4 py-3 shadow-lg\"><bannercontent class=\"flex-col justify-between gap-3 md:flex-row md:items-center\"><bannerdescription class=\"text-sm text-foreground\">We use cookies to improve your experience, analyze site usage, and show personalized\n          content.\n        </bannerdescription><banneractions class=\"flex gap-2 max-md:flex-wrap\"><button size=\"sm\">Accept</button><button variant=\"outline\" size=\"sm\">Decline\n          </button></banneractions></bannercontent></banner>\n</view>"
        },
        {
          "path": "registry/default/components/banner/banner-01.wxss",
          "target": "components/ui/banner-01/banner-01.wxss",
          "type": "registry:component",
          "content": ".banner-container {\n  background-color: #fff;\n  z-index: 50;\n  border-radius: 6px;\n  border: 1px solid #e2e8f0; /* border-input */\n  padding: 12px 16px;\n  box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);\n}\n\n.banner-content {\n  display: flex;\n  flex-direction: column;\n  gap: 12px;\n}\n\n@media (min-width: 640px) {\n  .banner-content {\n    flex-direction: row;\n    align-items: center;\n    justify-content: space-between;\n  }\n}\n\n.banner-text {\n  font-size: 14px;\n  color: #09090b; /* foreground */\n}\n\n.banner-actions {\n  display: flex;\n  gap: 8px;\n}\n\n.btn-primary {\n  background-color: #18181b;\n  color: #fff;\n  font-size: 12px;\n}\n\n.btn-outline {\n  background-color: transparent;\n  color: #18181b;\n  border: 1px solid #e2e8f0;\n  font-size: 12px;\n}\n"
        },
        {
          "path": "registry/default/components/banner/banner-01.json",
          "target": "components/ui/banner-01/banner-01.json",
          "type": "registry:component",
          "content": "{\n    \"component\": true,\n    \"usingComponents\": {}\n}"
        }
      ],
      "meta": {
        "tags": [
          "banner",
          "cookies",
          "gdpr",
          "privacy"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "banner-01",
          "group": "banner",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "banner-01",
              "path": "registry/default/components/banner/banner-01.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "banner-01",
              "path": "registry/default/components/banner/banner-01.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "banner-01",
              "path": "registry/default/components/banner/banner-01.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "banner-01",
              "path": "registry/default/components/banner/banner-01.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "banners",
        "title": "Banner · Outlined Style"
      },
      "categories": [
        "banners",
        "banner"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "banner-02",
      "type": "registry:component",
      "files": [
        {
          "path": "registry/default/components/banner/banner-02.tsx",
          "type": "registry:component",
          "target": "components/ui/banner-02.tsx",
          "content": "import { Banner, BannerContent, BannerDescription } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Banner className=\"dark bg-muted text-foreground px-4 py-3\">\n      <BannerContent className=\"justify-center\">\n        <BannerDescription className=\"text-sm text-foreground\">\n          <a href=\"#\" className=\"group\">\n            <span className=\"me-1 text-base leading-none\">✨</span>\n            Introducing transactional and marketing emails\n            <svg\n              className=\"ms-2 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\"\n              width={16}\n              height={16}\n              viewBox=\"0 0 24 24\"\n              fill=\"none\"\n              stroke=\"currentColor\"\n              strokeWidth=\"2\"\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              aria-hidden=\"true\"\n            >\n              <path d=\"M5 12h14\" />\n              <path d=\"m13 5 7 7-7 7\" />\n            </svg>\n          </a>\n        </BannerDescription>\n      </BannerContent>\n    </Banner>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/banner/banner-02.vue",
          "target": "components/ui/banner-02.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Banner } from '@timui/vue';\nimport { BannerContent } from '@timui/vue';\nimport { BannerDescription } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Banner class=\"dark bg-muted text-foreground px-4 py-3\"><BannerContent class=\"justify-center\"><BannerDescription class=\"text-sm text-foreground\"><a href=\"#\" class=\"group\"><span class=\"me-1 text-base leading-none\">✨</span>Introducing transactional and marketing emails\n            <svg class=\"ms-2 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\" :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M5 12h14\" /><path d=\"m13 5 7 7-7 7\" /></svg></a></BannerDescription></BannerContent></Banner>\n</template>\n"
        },
        {
          "path": "registry/default/components/banner/banner-02.html",
          "target": "components/ui/banner-02.html",
          "type": "registry:component",
          "content": "<template>\n  <Banner class=\"dark bg-muted text-foreground px-4 py-3\"><BannerContent class=\"justify-center\"><BannerDescription class=\"text-sm text-foreground\"><a href=\"#\" class=\"group\"><span class=\"me-1 text-base leading-none\">✨</span>Introducing transactional and marketing emails\n            <svg class=\"ms-2 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\" width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M5 12h14\" /><path d=\"m13 5 7 7-7 7\" /></svg></a></BannerDescription></BannerContent></Banner>\n</template>"
        },
        {
          "path": "registry/default/components/banner/banner-02.wxml",
          "target": "components/ui/banner-02/banner-02.wxml",
          "type": "registry:component",
          "content": "<view>\n  <banner class=\"dark bg-muted text-foreground px-4 py-3\"><bannercontent class=\"justify-center\"><bannerdescription class=\"text-sm text-foreground\"><a href=\"#\" class=\"group\"><text class=\"me-1 text-base leading-none\">✨</text>Introducing transactional and marketing emails\n            <svg class=\"ms-2 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\" width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M5 12h14\" /><path d=\"m13 5 7 7-7 7\" /></svg></a></bannerdescription></bannercontent></banner>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "banner"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "banner-02",
          "group": "banner",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "banner-02",
              "path": "registry/default/components/banner/banner-02.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "banner-02",
              "path": "registry/default/components/banner/banner-02.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "banner-02",
              "path": "registry/default/components/banner/banner-02.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "banner-02",
              "path": "registry/default/components/banner/banner-02.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "banners",
        "title": "Banner · Interactive State"
      },
      "categories": [
        "banners",
        "banner"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "banner-03",
      "type": "registry:component",
      "files": [
        {
          "path": "registry/default/components/banner/banner-03.tsx",
          "type": "registry:component",
          "target": "components/ui/banner-03.tsx",
          "content": "import { Banner, BannerContent, BannerDescription, BannerIcon } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Banner className=\"dark bg-muted text-foreground px-4 py-3\">\n      <BannerContent className=\"justify-center\">\n        <BannerIcon className=\"me-3 -mt-0.5 opacity-60\">\n          <svg\n            width={16}\n            height={16}\n            viewBox=\"0 0 24 24\"\n            fill=\"none\"\n            stroke=\"currentColor\"\n            strokeWidth=\"2\"\n            strokeLinecap=\"round\"\n            strokeLinejoin=\"round\"\n            aria-hidden=\"true\"\n          >\n            <path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" />\n          </svg>\n        </BannerIcon>\n        <BannerDescription className=\"text-sm text-foreground text-center\">\n          Get the most out of your app with real-time updates and analytics{' '}\n          <span className=\"text-muted-foreground\">·</span>{' '}\n          <a href=\"#\" className=\"font-medium underline hover:no-underline\">\n            Upgrade\n          </a>\n        </BannerDescription>\n      </BannerContent>\n    </Banner>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/banner/banner-03.vue",
          "target": "components/ui/banner-03.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Banner } from '@timui/vue';\nimport { BannerContent } from '@timui/vue';\nimport { BannerDescription } from '@timui/vue';\nimport { BannerIcon } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Banner class=\"dark bg-muted text-foreground px-4 py-3\"><BannerContent class=\"justify-center\"><BannerIcon class=\"me-3 -mt-0.5 opacity-60\"><svg :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" /></svg></BannerIcon><BannerDescription class=\"text-sm text-foreground text-center\">Get the most out of your app with real-time updates and analytics{{ ' ' }}<span class=\"text-muted-foreground\">·</span>{{ ' ' }}<a href=\"#\" class=\"font-medium underline hover:no-underline\">Upgrade\n          </a></BannerDescription></BannerContent></Banner>\n</template>\n"
        },
        {
          "path": "registry/default/components/banner/banner-03.html",
          "target": "components/ui/banner-03.html",
          "type": "registry:component",
          "content": "<template>\n  <Banner class=\"dark bg-muted text-foreground px-4 py-3\"><BannerContent class=\"justify-center\"><BannerIcon class=\"me-3 -mt-0.5 opacity-60\"><svg width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" /></svg></BannerIcon><BannerDescription class=\"text-sm text-foreground text-center\">Get the most out of your app with real-time updates and analytics${' '}<span class=\"text-muted-foreground\">·</span>${' '}<a href=\"#\" class=\"font-medium underline hover:no-underline\">Upgrade\n          </a></BannerDescription></BannerContent></Banner>\n</template>"
        },
        {
          "path": "registry/default/components/banner/banner-03.wxml",
          "target": "components/ui/banner-03/banner-03.wxml",
          "type": "registry:component",
          "content": "<view>\n  <banner class=\"dark bg-muted text-foreground px-4 py-3\"><bannercontent class=\"justify-center\"><bannericon class=\"me-3 -mt-0.5 opacity-60\"><svg width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" /></svg></bannericon><bannerdescription class=\"text-sm text-foreground text-center\">Get the most out of your app with real-time updates and analytics{{ ' ' }}<text class=\"text-muted-foreground\">·</text>{{ ' ' }}<a href=\"#\" class=\"font-medium underline hover:no-underline\">Upgrade\n          </a></bannerdescription></bannercontent></banner>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "banner"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "banner-03",
          "group": "banner",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "banner-03",
              "path": "registry/default/components/banner/banner-03.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "banner-03",
              "path": "registry/default/components/banner/banner-03.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "banner-03",
              "path": "registry/default/components/banner/banner-03.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "banner-03",
              "path": "registry/default/components/banner/banner-03.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "banners",
        "title": "Banner · Interactive State"
      },
      "categories": [
        "banners",
        "banner"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "banner-04",
      "type": "registry:component",
      "files": [
        {
          "path": "registry/default/components/banner/banner-04.tsx",
          "type": "registry:component",
          "target": "components/ui/banner-04.tsx",
          "content": "import { Banner, BannerActions, BannerContent, BannerDescription, BannerIcon } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Banner className=\"dark bg-muted text-foreground px-4 py-3\">\n      <BannerContent className=\"flex-col justify-between gap-2 md:flex-row\">\n        <div className=\"flex grow gap-3\">\n          <BannerIcon className=\"mt-0.5 opacity-60\">\n            <svg\n              width={16}\n              height={16}\n              viewBox=\"0 0 24 24\"\n              fill=\"none\"\n              stroke=\"currentColor\"\n              strokeWidth=\"2\"\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              aria-hidden=\"true\"\n            >\n              <path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" />\n            </svg>\n          </BannerIcon>\n          <div className=\"flex grow flex-col justify-between gap-2 md:flex-row md:items-center\">\n            <BannerDescription className=\"text-sm text-foreground\">\n              We just added something awesome to make your experience even better.\n            </BannerDescription>\n            <BannerActions className=\"text-sm\">\n              <a href=\"#\" className=\"group text-sm font-medium whitespace-nowrap\">\n                Learn more\n                <svg\n                  className=\"ms-1 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\"\n                  width={16}\n                  height={16}\n                  viewBox=\"0 0 24 24\"\n                  fill=\"none\"\n                  stroke=\"currentColor\"\n                  strokeWidth=\"2\"\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  aria-hidden=\"true\"\n                >\n                  <path d=\"M5 12h14\" />\n                  <path d=\"m13 5 7 7-7 7\" />\n                </svg>\n              </a>\n            </BannerActions>\n          </div>\n        </div>\n      </BannerContent>\n    </Banner>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/banner/banner-04.vue",
          "target": "components/ui/banner-04.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Banner } from '@timui/vue';\nimport { BannerActions } from '@timui/vue';\nimport { BannerContent } from '@timui/vue';\nimport { BannerDescription } from '@timui/vue';\nimport { BannerIcon } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Banner class=\"dark bg-muted text-foreground px-4 py-3\"><BannerContent class=\"flex-col justify-between gap-2 md:flex-row\"><div class=\"flex grow gap-3\"><BannerIcon class=\"mt-0.5 opacity-60\"><svg :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" /></svg></BannerIcon><div class=\"flex grow flex-col justify-between gap-2 md:flex-row md:items-center\"><BannerDescription class=\"text-sm text-foreground\">We just added something awesome to make your experience even better.\n            </BannerDescription><BannerActions class=\"text-sm\"><a href=\"#\" class=\"group text-sm font-medium whitespace-nowrap\">Learn more\n                <svg class=\"ms-1 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\" :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M5 12h14\" /><path d=\"m13 5 7 7-7 7\" /></svg></a></BannerActions></div></div></BannerContent></Banner>\n</template>\n"
        },
        {
          "path": "registry/default/components/banner/banner-04.html",
          "target": "components/ui/banner-04.html",
          "type": "registry:component",
          "content": "<template>\n  <Banner class=\"dark bg-muted text-foreground px-4 py-3\"><BannerContent class=\"flex-col justify-between gap-2 md:flex-row\"><div class=\"flex grow gap-3\"><BannerIcon class=\"mt-0.5 opacity-60\"><svg width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" /></svg></BannerIcon><div class=\"flex grow flex-col justify-between gap-2 md:flex-row md:items-center\"><BannerDescription class=\"text-sm text-foreground\">We just added something awesome to make your experience even better.\n            </BannerDescription><BannerActions class=\"text-sm\"><a href=\"#\" class=\"group text-sm font-medium whitespace-nowrap\">Learn more\n                <svg class=\"ms-1 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\" width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M5 12h14\" /><path d=\"m13 5 7 7-7 7\" /></svg></a></BannerActions></div></div></BannerContent></Banner>\n</template>"
        },
        {
          "path": "registry/default/components/banner/banner-04.wxml",
          "target": "components/ui/banner-04/banner-04.wxml",
          "type": "registry:component",
          "content": "<view>\n  <banner class=\"dark bg-muted text-foreground px-4 py-3\"><bannercontent class=\"flex-col justify-between gap-2 md:flex-row\"><view class=\"flex grow gap-3\"><bannericon class=\"mt-0.5 opacity-60\"><svg width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" /></svg></bannericon><view class=\"flex grow flex-col justify-between gap-2 md:flex-row md:items-center\"><bannerdescription class=\"text-sm text-foreground\">We just added something awesome to make your experience even better.\n            </bannerdescription><banneractions class=\"text-sm\"><a href=\"#\" class=\"group text-sm font-medium whitespace-nowrap\">Learn more\n                <svg class=\"ms-1 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\" width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M5 12h14\" /><path d=\"m13 5 7 7-7 7\" /></svg></a></banneractions></view></view></bannercontent></banner>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "banner"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "banner-04",
          "group": "banner",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "banner-04",
              "path": "registry/default/components/banner/banner-04.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "banner-04",
              "path": "registry/default/components/banner/banner-04.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "banner-04",
              "path": "registry/default/components/banner/banner-04.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "banner-04",
              "path": "registry/default/components/banner/banner-04.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "banners",
        "title": "Banner · Interactive State"
      },
      "categories": [
        "banners",
        "banner"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "banner-05",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "files": [
        {
          "path": "registry/default/components/banner/banner-05.tsx",
          "type": "registry:component",
          "target": "components/ui/banner-05.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport {\n  Banner,\n  BannerActions,\n  BannerContent,\n  BannerDescription,\n  BannerIcon,\n  Button,\n} from '@timui/react'\n\nexport default function Component() {\n  const [isVisible, setIsVisible] = useState(true)\n\n  if (!isVisible) return null\n\n  return (\n    <Banner className=\"dark bg-muted text-foreground px-4 py-3\">\n      <BannerContent className=\"gap-2\">\n        <div className=\"flex grow gap-3\">\n          <BannerIcon className=\"mt-0.5 opacity-60\">\n            <svg\n              width={16}\n              height={16}\n              viewBox=\"0 0 24 24\"\n              fill=\"none\"\n              stroke=\"currentColor\"\n              strokeWidth=\"2\"\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              aria-hidden=\"true\"\n            >\n              <path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" />\n            </svg>\n          </BannerIcon>\n          <div className=\"flex grow flex-col justify-between gap-2 md:flex-row\">\n            <BannerDescription className=\"text-sm text-foreground\">\n              We just added something awesome to make your experience even better.\n            </BannerDescription>\n            <BannerActions className=\"text-sm\">\n              <a href=\"#\" className=\"group text-sm font-medium whitespace-nowrap\">\n                Learn more\n                <svg\n                  className=\"ms-1 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\"\n                  width={16}\n                  height={16}\n                  viewBox=\"0 0 24 24\"\n                  fill=\"none\"\n                  stroke=\"currentColor\"\n                  strokeWidth=\"2\"\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  aria-hidden=\"true\"\n                >\n                  <path d=\"M5 12h14\" />\n                  <path d=\"m13 5 7 7-7 7\" />\n                </svg>\n              </a>\n            </BannerActions>\n          </div>\n        </div>\n        <BannerActions className=\"shrink-0\">\n          <Button\n            variant=\"ghost\"\n            className=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\"\n            onClick={() => setIsVisible(false)}\n            aria-label=\"Close banner\"\n          >\n            <svg\n              width={16}\n              height={16}\n              viewBox=\"0 0 24 24\"\n              fill=\"none\"\n              stroke=\"currentColor\"\n              strokeWidth=\"2\"\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              className=\"opacity-60 transition-opacity group-hover:opacity-100\"\n              aria-hidden=\"true\"\n            >\n              <path d=\"M18 6 6 18\" />\n              <path d=\"M6 6 18 18\" />\n            </svg>\n          </Button>\n        </BannerActions>\n      </BannerContent>\n    </Banner>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/banner/banner-05.vue",
          "target": "components/ui/banner-05.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Banner } from '@timui/vue';\nimport { BannerActions } from '@timui/vue';\nimport { BannerContent } from '@timui/vue';\nimport { BannerDescription } from '@timui/vue';\nimport { BannerIcon } from '@timui/vue';\nimport { Button } from '@timui/vue';\n\n\n\nconst isVisible = ref(true);\n\n\nfunction setIsVisible(next: typeof isVisible.value | ((prev: typeof isVisible.value) => typeof isVisible.value)) {\n  isVisible.value = typeof next === 'function'\n    ? (next as (prev: typeof isVisible.value) => typeof isVisible.value)(isVisible.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <Banner class=\"dark bg-muted text-foreground px-4 py-3\"><BannerContent class=\"gap-2\"><div class=\"flex grow gap-3\"><BannerIcon class=\"mt-0.5 opacity-60\"><svg :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" /></svg></BannerIcon><div class=\"flex grow flex-col justify-between gap-2 md:flex-row\"><BannerDescription class=\"text-sm text-foreground\">We just added something awesome to make your experience even better.\n            </BannerDescription><BannerActions class=\"text-sm\"><a href=\"#\" class=\"group text-sm font-medium whitespace-nowrap\">Learn more\n                <svg class=\"ms-1 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\" :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M5 12h14\" /><path d=\"m13 5 7 7-7 7\" /></svg></a></BannerActions></div></div><BannerActions class=\"shrink-0\"><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" @click=\"setIsVisible(false)\" aria-label=\"Close banner\"><svg :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\"><path d=\"M18 6 6 18\" /><path d=\"M6 6 18 18\" /></svg></Button></BannerActions></BannerContent></Banner>\n</template>\n"
        },
        {
          "path": "registry/default/components/banner/banner-05.html",
          "target": "components/ui/banner-05.html",
          "type": "registry:component",
          "content": "<template>\n  <Banner class=\"dark bg-muted text-foreground px-4 py-3\"><BannerContent class=\"gap-2\"><div class=\"flex grow gap-3\"><BannerIcon class=\"mt-0.5 opacity-60\"><svg width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" /></svg></BannerIcon><div class=\"flex grow flex-col justify-between gap-2 md:flex-row\"><BannerDescription class=\"text-sm text-foreground\">We just added something awesome to make your experience even better.\n            </BannerDescription><BannerActions class=\"text-sm\"><a href=\"#\" class=\"group text-sm font-medium whitespace-nowrap\">Learn more\n                <svg class=\"ms-1 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\" width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M5 12h14\" /><path d=\"m13 5 7 7-7 7\" /></svg></a></BannerActions></div></div><BannerActions class=\"shrink-0\"><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" on-click=\"${() => setIsVisible(false)}\" aria-label=\"Close banner\"><svg width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\"><path d=\"M18 6 6 18\" /><path d=\"M6 6 18 18\" /></svg></Button></BannerActions></BannerContent></Banner>\n</template>"
        },
        {
          "path": "registry/default/components/banner/banner-05.wxml",
          "target": "components/ui/banner-05/banner-05.wxml",
          "type": "registry:component",
          "content": "<view>\n  <banner class=\"dark bg-muted text-foreground px-4 py-3\"><bannercontent class=\"gap-2\"><view class=\"flex grow gap-3\"><bannericon class=\"mt-0.5 opacity-60\"><svg width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" /></svg></bannericon><view class=\"flex grow flex-col justify-between gap-2 md:flex-row\"><bannerdescription class=\"text-sm text-foreground\">We just added something awesome to make your experience even better.\n            </bannerdescription><banneractions class=\"text-sm\"><a href=\"#\" class=\"group text-sm font-medium whitespace-nowrap\">Learn more\n                <svg class=\"ms-1 -mt-0.5 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5\" width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M5 12h14\" /><path d=\"m13 5 7 7-7 7\" /></svg></a></banneractions></view></view><banneractions class=\"shrink-0\"><button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" bindtap=\"setIsVisible(false)\" aria-label=\"Close banner\"><svg width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\"><path d=\"M18 6 6 18\" /><path d=\"M6 6 18 18\" /></svg></button></banneractions></bannercontent></banner>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "banner"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "banner-05",
          "group": "banner",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "banner-05",
              "path": "registry/default/components/banner/banner-05.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "banner-05",
              "path": "registry/default/components/banner/banner-05.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "banner-05",
              "path": "registry/default/components/banner/banner-05.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "banner-05",
              "path": "registry/default/components/banner/banner-05.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "banners",
        "title": "Banner · Dismissible"
      },
      "categories": [
        "banners",
        "banner"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "banner-06",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "files": [
        {
          "path": "registry/default/components/banner/banner-06.tsx",
          "type": "registry:component",
          "target": "components/ui/banner-06.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport {\n  Banner,\n  BannerActions,\n  BannerContent,\n  BannerDescription,\n  BannerIcon,\n  Button,\n} from '@timui/react'\n\nexport default function Component() {\n  const [isVisible, setIsVisible] = useState(true)\n\n  if (!isVisible) return null\n\n  return (\n    <Banner className=\"dark bg-muted text-foreground px-4 py-3 md:py-2\">\n      <BannerContent className=\"gap-2 md:items-center\">\n        <div className=\"flex grow gap-3 md:items-center\">\n          <BannerIcon className=\"opacity-60 max-md:mt-0.5\">\n            <svg\n              width={16}\n              height={16}\n              viewBox=\"0 0 24 24\"\n              fill=\"none\"\n              stroke=\"currentColor\"\n              strokeWidth=\"2\"\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              aria-hidden=\"true\"\n            >\n              <path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" />\n            </svg>\n          </BannerIcon>\n          <div className=\"flex grow flex-col justify-between gap-3 md:flex-row md:items-center\">\n            <BannerDescription className=\"text-sm text-foreground\">\n              It&lsquo;s live and ready to use! Start exploring the latest addition to your toolkit.\n            </BannerDescription>\n            <BannerActions className=\"flex gap-2 max-md:flex-wrap\">\n              <Button size=\"sm\" className=\"text-sm\">\n                Download\n              </Button>\n              <Button variant=\"outline\" size=\"sm\" className=\"text-sm\">\n                Learn more\n              </Button>\n            </BannerActions>\n          </div>\n        </div>\n        <BannerActions className=\"shrink-0\">\n          <Button\n            variant=\"ghost\"\n            className=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\"\n            onClick={() => setIsVisible(false)}\n            aria-label=\"Close banner\"\n          >\n            <svg\n              width={16}\n              height={16}\n              viewBox=\"0 0 24 24\"\n              fill=\"none\"\n              stroke=\"currentColor\"\n              strokeWidth=\"2\"\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              className=\"opacity-60 transition-opacity group-hover:opacity-100\"\n              aria-hidden=\"true\"\n            >\n              <path d=\"M18 6 6 18\" />\n              <path d=\"M6 6 18 18\" />\n            </svg>\n          </Button>\n        </BannerActions>\n      </BannerContent>\n    </Banner>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/banner/banner-06.vue",
          "target": "components/ui/banner-06.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Banner } from '@timui/vue';\nimport { BannerActions } from '@timui/vue';\nimport { BannerContent } from '@timui/vue';\nimport { BannerDescription } from '@timui/vue';\nimport { BannerIcon } from '@timui/vue';\nimport { Button } from '@timui/vue';\n\n\n\nconst isVisible = ref(true);\n\n\nfunction setIsVisible(next: typeof isVisible.value | ((prev: typeof isVisible.value) => typeof isVisible.value)) {\n  isVisible.value = typeof next === 'function'\n    ? (next as (prev: typeof isVisible.value) => typeof isVisible.value)(isVisible.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <Banner class=\"dark bg-muted text-foreground px-4 py-3 md:py-2\"><BannerContent class=\"gap-2 md:items-center\"><div class=\"flex grow gap-3 md:items-center\"><BannerIcon class=\"opacity-60 max-md:mt-0.5\"><svg :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" /></svg></BannerIcon><div class=\"flex grow flex-col justify-between gap-3 md:flex-row md:items-center\"><BannerDescription class=\"text-sm text-foreground\">It&lsquo;s live and ready to use! Start exploring the latest addition to your toolkit.\n            </BannerDescription><BannerActions class=\"flex gap-2 max-md:flex-wrap\"><Button size=\"sm\" class=\"text-sm\">Download\n              </Button><Button variant=\"outline\" size=\"sm\" class=\"text-sm\">Learn more\n              </Button></BannerActions></div></div><BannerActions class=\"shrink-0\"><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" @click=\"setIsVisible(false)\" aria-label=\"Close banner\"><svg :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\"><path d=\"M18 6 6 18\" /><path d=\"M6 6 18 18\" /></svg></Button></BannerActions></BannerContent></Banner>\n</template>\n"
        },
        {
          "path": "registry/default/components/banner/banner-06.html",
          "target": "components/ui/banner-06.html",
          "type": "registry:component",
          "content": "<template>\n  <Banner class=\"dark bg-muted text-foreground px-4 py-3 md:py-2\"><BannerContent class=\"gap-2 md:items-center\"><div class=\"flex grow gap-3 md:items-center\"><BannerIcon class=\"opacity-60 max-md:mt-0.5\"><svg width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" /></svg></BannerIcon><div class=\"flex grow flex-col justify-between gap-3 md:flex-row md:items-center\"><BannerDescription class=\"text-sm text-foreground\">It&lsquo;s live and ready to use! Start exploring the latest addition to your toolkit.\n            </BannerDescription><BannerActions class=\"flex gap-2 max-md:flex-wrap\"><Button size=\"sm\" class=\"text-sm\">Download\n              </Button><Button variant=\"outline\" size=\"sm\" class=\"text-sm\">Learn more\n              </Button></BannerActions></div></div><BannerActions class=\"shrink-0\"><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" on-click=\"${() => setIsVisible(false)}\" aria-label=\"Close banner\"><svg width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\"><path d=\"M18 6 6 18\" /><path d=\"M6 6 18 18\" /></svg></Button></BannerActions></BannerContent></Banner>\n</template>"
        },
        {
          "path": "registry/default/components/banner/banner-06.wxml",
          "target": "components/ui/banner-06/banner-06.wxml",
          "type": "registry:component",
          "content": "<view>\n  <banner class=\"dark bg-muted text-foreground px-4 py-3 md:py-2\"><bannercontent class=\"gap-2 md:items-center\"><view class=\"flex grow gap-3 md:items-center\"><bannericon class=\"opacity-60 max-md:mt-0.5\"><svg width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" /></svg></bannericon><view class=\"flex grow flex-col justify-between gap-3 md:flex-row md:items-center\"><bannerdescription class=\"text-sm text-foreground\">It&lsquo;s live and ready to use! Start exploring the latest addition to your toolkit.\n            </bannerdescription><banneractions class=\"flex gap-2 max-md:flex-wrap\"><button size=\"sm\" class=\"text-sm\">Download\n              </button><button variant=\"outline\" size=\"sm\" class=\"text-sm\">Learn more\n              </button></banneractions></view></view><banneractions class=\"shrink-0\"><button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" bindtap=\"setIsVisible(false)\" aria-label=\"Close banner\"><svg width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\"><path d=\"M18 6 6 18\" /><path d=\"M6 6 18 18\" /></svg></button></banneractions></bannercontent></banner>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "banner"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "banner-06",
          "group": "banner",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "banner-06",
              "path": "registry/default/components/banner/banner-06.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "banner-06",
              "path": "registry/default/components/banner/banner-06.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "banner-06",
              "path": "registry/default/components/banner/banner-06.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "banner-06",
              "path": "registry/default/components/banner/banner-06.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "banners",
        "title": "Banner · Dismissible"
      },
      "categories": [
        "banners",
        "banner"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "banner-07",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "files": [
        {
          "path": "registry/default/components/banner/banner-07.tsx",
          "type": "registry:component",
          "target": "components/ui/banner-07.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport {\n  Banner,\n  BannerActions,\n  BannerContent,\n  BannerDescription,\n  BannerIcon,\n  Button,\n} from '@timui/react'\n\nexport default function Component() {\n  const [isVisible, setIsVisible] = useState(true)\n\n  if (!isVisible) return null\n\n  return (\n    <Banner className=\"dark bg-muted text-foreground px-4 py-3 md:py-2\">\n      <BannerContent className=\"gap-2 md:items-center\">\n        <div className=\"flex grow gap-3 md:items-center\">\n          <BannerIcon className=\"opacity-60 max-md:mt-0.5\">\n            <svg\n              width={16}\n              height={16}\n              viewBox=\"0 0 24 24\"\n              fill=\"none\"\n              stroke=\"currentColor\"\n              strokeWidth=\"2\"\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              aria-hidden=\"true\"\n            >\n              <path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" />\n            </svg>\n          </BannerIcon>\n          <div className=\"flex grow flex-col justify-between gap-3 md:flex-row md:items-center\">\n            <BannerDescription className=\"text-sm text-foreground\">\n              It&lsquo;s live and ready to use! Start exploring the latest addition to your toolkit.\n            </BannerDescription>\n            <BannerActions className=\"flex gap-2 max-md:flex-wrap\">\n              <Button size=\"sm\" className=\"text-sm\">\n                Download\n              </Button>\n              <Button variant=\"link\" size=\"sm\" className=\"text-sm\">\n                Learn more\n              </Button>\n            </BannerActions>\n          </div>\n        </div>\n        <BannerActions className=\"shrink-0\">\n          <Button\n            variant=\"ghost\"\n            className=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\"\n            onClick={() => setIsVisible(false)}\n            aria-label=\"Close banner\"\n          >\n            <svg\n              width={16}\n              height={16}\n              viewBox=\"0 0 24 24\"\n              fill=\"none\"\n              stroke=\"currentColor\"\n              strokeWidth=\"2\"\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              className=\"opacity-60 transition-opacity group-hover:opacity-100\"\n              aria-hidden=\"true\"\n            >\n              <path d=\"M18 6 6 18\" />\n              <path d=\"M6 6 18 18\" />\n            </svg>\n          </Button>\n        </BannerActions>\n      </BannerContent>\n    </Banner>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/banner/banner-07.vue",
          "target": "components/ui/banner-07.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Banner } from '@timui/vue';\nimport { BannerActions } from '@timui/vue';\nimport { BannerContent } from '@timui/vue';\nimport { BannerDescription } from '@timui/vue';\nimport { BannerIcon } from '@timui/vue';\nimport { Button } from '@timui/vue';\n\n\n\nconst isVisible = ref(true);\n\n\nfunction setIsVisible(next: typeof isVisible.value | ((prev: typeof isVisible.value) => typeof isVisible.value)) {\n  isVisible.value = typeof next === 'function'\n    ? (next as (prev: typeof isVisible.value) => typeof isVisible.value)(isVisible.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <Banner class=\"dark bg-muted text-foreground px-4 py-3 md:py-2\"><BannerContent class=\"gap-2 md:items-center\"><div class=\"flex grow gap-3 md:items-center\"><BannerIcon class=\"opacity-60 max-md:mt-0.5\"><svg :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" /></svg></BannerIcon><div class=\"flex grow flex-col justify-between gap-3 md:flex-row md:items-center\"><BannerDescription class=\"text-sm text-foreground\">It&lsquo;s live and ready to use! Start exploring the latest addition to your toolkit.\n            </BannerDescription><BannerActions class=\"flex gap-2 max-md:flex-wrap\"><Button size=\"sm\" class=\"text-sm\">Download\n              </Button><Button variant=\"link\" size=\"sm\" class=\"text-sm\">Learn more\n              </Button></BannerActions></div></div><BannerActions class=\"shrink-0\"><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" @click=\"setIsVisible(false)\" aria-label=\"Close banner\"><svg :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\"><path d=\"M18 6 6 18\" /><path d=\"M6 6 18 18\" /></svg></Button></BannerActions></BannerContent></Banner>\n</template>\n"
        },
        {
          "path": "registry/default/components/banner/banner-07.html",
          "target": "components/ui/banner-07.html",
          "type": "registry:component",
          "content": "<template>\n  <Banner class=\"dark bg-muted text-foreground px-4 py-3 md:py-2\"><BannerContent class=\"gap-2 md:items-center\"><div class=\"flex grow gap-3 md:items-center\"><BannerIcon class=\"opacity-60 max-md:mt-0.5\"><svg width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" /></svg></BannerIcon><div class=\"flex grow flex-col justify-between gap-3 md:flex-row md:items-center\"><BannerDescription class=\"text-sm text-foreground\">It&lsquo;s live and ready to use! Start exploring the latest addition to your toolkit.\n            </BannerDescription><BannerActions class=\"flex gap-2 max-md:flex-wrap\"><Button size=\"sm\" class=\"text-sm\">Download\n              </Button><Button variant=\"link\" size=\"sm\" class=\"text-sm\">Learn more\n              </Button></BannerActions></div></div><BannerActions class=\"shrink-0\"><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" on-click=\"${() => setIsVisible(false)}\" aria-label=\"Close banner\"><svg width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\"><path d=\"M18 6 6 18\" /><path d=\"M6 6 18 18\" /></svg></Button></BannerActions></BannerContent></Banner>\n</template>"
        },
        {
          "path": "registry/default/components/banner/banner-07.wxml",
          "target": "components/ui/banner-07/banner-07.wxml",
          "type": "registry:component",
          "content": "<view>\n  <banner class=\"dark bg-muted text-foreground px-4 py-3 md:py-2\"><bannercontent class=\"gap-2 md:items-center\"><view class=\"flex grow gap-3 md:items-center\"><bannericon class=\"opacity-60 max-md:mt-0.5\"><svg width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" /></svg></bannericon><view class=\"flex grow flex-col justify-between gap-3 md:flex-row md:items-center\"><bannerdescription class=\"text-sm text-foreground\">It&lsquo;s live and ready to use! Start exploring the latest addition to your toolkit.\n            </bannerdescription><banneractions class=\"flex gap-2 max-md:flex-wrap\"><button size=\"sm\" class=\"text-sm\">Download\n              </button><button variant=\"link\" size=\"sm\" class=\"text-sm\">Learn more\n              </button></banneractions></view></view><banneractions class=\"shrink-0\"><button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" bindtap=\"setIsVisible(false)\" aria-label=\"Close banner\"><svg width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\"><path d=\"M18 6 6 18\" /><path d=\"M6 6 18 18\" /></svg></button></banneractions></bannercontent></banner>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "banner"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "banner-07",
          "group": "banner",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "banner-07",
              "path": "registry/default/components/banner/banner-07.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "banner-07",
              "path": "registry/default/components/banner/banner-07.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "banner-07",
              "path": "registry/default/components/banner/banner-07.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "banner-07",
              "path": "registry/default/components/banner/banner-07.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "banners",
        "title": "Banner · Dismissible"
      },
      "categories": [
        "banners",
        "banner"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "banner-08",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "files": [
        {
          "path": "registry/default/components/banner/banner-08.tsx",
          "type": "registry:component",
          "target": "components/ui/banner-08.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport {\n  Banner,\n  BannerActions,\n  BannerContent,\n  BannerDescription,\n  BannerIcon,\n  Button,\n} from '@timui/react'\n\nexport default function Component() {\n  const [isVisible, setIsVisible] = useState(true)\n\n  if (!isVisible) return null\n\n  return (\n    <Banner className=\"dark bg-muted text-foreground px-4 py-3 md:py-2\">\n      <BannerContent className=\"gap-2 md:items-center\">\n        <div className=\"flex grow gap-3 md:items-center md:justify-center\">\n          <BannerIcon className=\"opacity-60 max-md:mt-0.5\">\n            <svg\n              width={16}\n              height={16}\n              viewBox=\"0 0 24 24\"\n              fill=\"none\"\n              stroke=\"currentColor\"\n              strokeWidth=\"2\"\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              aria-hidden=\"true\"\n            >\n              <path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" />\n            </svg>\n          </BannerIcon>\n          <div className=\"flex flex-col justify-between gap-3 md:flex-row md:items-center\">\n            <BannerDescription className=\"text-sm text-foreground\">\n              It&lsquo;s live and ready to use! Start exploring the latest addition to your toolkit.\n            </BannerDescription>\n            <BannerActions className=\"flex gap-2 max-md:flex-wrap\">\n              <Button size=\"sm\" className=\"rounded-full\">\n                Learn more\n              </Button>\n            </BannerActions>\n          </div>\n        </div>\n        <BannerActions className=\"shrink-0\">\n          <Button\n            variant=\"ghost\"\n            className=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\"\n            onClick={() => setIsVisible(false)}\n            aria-label=\"Close banner\"\n          >\n            <svg\n              width={16}\n              height={16}\n              viewBox=\"0 0 24 24\"\n              fill=\"none\"\n              stroke=\"currentColor\"\n              strokeWidth=\"2\"\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              className=\"opacity-60 transition-opacity group-hover:opacity-100\"\n              aria-hidden=\"true\"\n            >\n              <path d=\"M18 6 6 18\" />\n              <path d=\"M6 6 18 18\" />\n            </svg>\n          </Button>\n        </BannerActions>\n      </BannerContent>\n    </Banner>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/banner/banner-08.vue",
          "target": "components/ui/banner-08.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Banner } from '@timui/vue';\nimport { BannerActions } from '@timui/vue';\nimport { BannerContent } from '@timui/vue';\nimport { BannerDescription } from '@timui/vue';\nimport { BannerIcon } from '@timui/vue';\nimport { Button } from '@timui/vue';\n\n\n\nconst isVisible = ref(true);\n\n\nfunction setIsVisible(next: typeof isVisible.value | ((prev: typeof isVisible.value) => typeof isVisible.value)) {\n  isVisible.value = typeof next === 'function'\n    ? (next as (prev: typeof isVisible.value) => typeof isVisible.value)(isVisible.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <Banner class=\"dark bg-muted text-foreground px-4 py-3 md:py-2\"><BannerContent class=\"gap-2 md:items-center\"><div class=\"flex grow gap-3 md:items-center md:justify-center\"><BannerIcon class=\"opacity-60 max-md:mt-0.5\"><svg :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" /></svg></BannerIcon><div class=\"flex flex-col justify-between gap-3 md:flex-row md:items-center\"><BannerDescription class=\"text-sm text-foreground\">It&lsquo;s live and ready to use! Start exploring the latest addition to your toolkit.\n            </BannerDescription><BannerActions class=\"flex gap-2 max-md:flex-wrap\"><Button size=\"sm\" class=\"rounded-full\">Learn more\n              </Button></BannerActions></div></div><BannerActions class=\"shrink-0\"><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" @click=\"setIsVisible(false)\" aria-label=\"Close banner\"><svg :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\"><path d=\"M18 6 6 18\" /><path d=\"M6 6 18 18\" /></svg></Button></BannerActions></BannerContent></Banner>\n</template>\n"
        },
        {
          "path": "registry/default/components/banner/banner-08.html",
          "target": "components/ui/banner-08.html",
          "type": "registry:component",
          "content": "<template>\n  <Banner class=\"dark bg-muted text-foreground px-4 py-3 md:py-2\"><BannerContent class=\"gap-2 md:items-center\"><div class=\"flex grow gap-3 md:items-center md:justify-center\"><BannerIcon class=\"opacity-60 max-md:mt-0.5\"><svg width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" /></svg></BannerIcon><div class=\"flex flex-col justify-between gap-3 md:flex-row md:items-center\"><BannerDescription class=\"text-sm text-foreground\">It&lsquo;s live and ready to use! Start exploring the latest addition to your toolkit.\n            </BannerDescription><BannerActions class=\"flex gap-2 max-md:flex-wrap\"><Button size=\"sm\" class=\"rounded-full\">Learn more\n              </Button></BannerActions></div></div><BannerActions class=\"shrink-0\"><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" on-click=\"${() => setIsVisible(false)}\" aria-label=\"Close banner\"><svg width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\"><path d=\"M18 6 6 18\" /><path d=\"M6 6 18 18\" /></svg></Button></BannerActions></BannerContent></Banner>\n</template>"
        },
        {
          "path": "registry/default/components/banner/banner-08.wxml",
          "target": "components/ui/banner-08/banner-08.wxml",
          "type": "registry:component",
          "content": "<view>\n  <banner class=\"dark bg-muted text-foreground px-4 py-3 md:py-2\"><bannercontent class=\"gap-2 md:items-center\"><view class=\"flex grow gap-3 md:items-center md:justify-center\"><bannericon class=\"opacity-60 max-md:mt-0.5\"><svg width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" /></svg></bannericon><view class=\"flex flex-col justify-between gap-3 md:flex-row md:items-center\"><bannerdescription class=\"text-sm text-foreground\">It&lsquo;s live and ready to use! Start exploring the latest addition to your toolkit.\n            </bannerdescription><banneractions class=\"flex gap-2 max-md:flex-wrap\"><button size=\"sm\" class=\"rounded-full\">Learn more\n              </button></banneractions></view></view><banneractions class=\"shrink-0\"><button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" bindtap=\"setIsVisible(false)\" aria-label=\"Close banner\"><svg width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\"><path d=\"M18 6 6 18\" /><path d=\"M6 6 18 18\" /></svg></button></banneractions></bannercontent></banner>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "banner"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "banner-08",
          "group": "banner",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "banner-08",
              "path": "registry/default/components/banner/banner-08.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "banner-08",
              "path": "registry/default/components/banner/banner-08.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "banner-08",
              "path": "registry/default/components/banner/banner-08.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "banner-08",
              "path": "registry/default/components/banner/banner-08.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "banners",
        "title": "Banner · Dismissible"
      },
      "categories": [
        "banners",
        "banner"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "banner-09",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "files": [
        {
          "path": "registry/default/components/banner/banner-09.tsx",
          "type": "registry:component",
          "target": "components/ui/banner-09.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport {\n  Banner,\n  BannerActions,\n  BannerContent,\n  BannerDescription,\n  BannerIcon,\n  BannerTitle,\n  Button,\n} from '@timui/react'\n\nexport default function Component() {\n  const [isVisible, setIsVisible] = useState(true)\n\n  if (!isVisible) return null\n\n  return (\n    <Banner className=\"dark bg-muted text-foreground px-4 py-3\">\n      <BannerContent className=\"gap-2 md:items-center\">\n        <div className=\"flex grow gap-3 md:items-center\">\n          <BannerIcon className=\"bg-primary/15 flex size-9 shrink-0 items-center justify-center rounded-full max-md:mt-0.5\">\n            <svg\n              className=\"opacity-80\"\n              width={16}\n              height={16}\n              viewBox=\"0 0 24 24\"\n              fill=\"none\"\n              stroke=\"currentColor\"\n              strokeWidth=\"2\"\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              aria-hidden=\"true\"\n            >\n              <path d=\"M4.5 16.5c-1.5-1.5-1-4.5 1-6.5 2-2 9-5 13-5 0 4-3 11-5 13-2 2-5 2.5-6.5 1L4 20l.5-3.5z\" />\n              <path d=\"M15 9 9 15\" />\n            </svg>\n          </BannerIcon>\n          <div className=\"flex grow flex-col justify-between gap-3 md:flex-row md:items-center\">\n            <div className=\"space-y-0.5\">\n              <BannerTitle>Boost your experience with Timkit UI</BannerTitle>\n              <BannerDescription className=\"text-sm\">\n                The new feature is live! Try it out and let us know what you think.\n              </BannerDescription>\n            </div>\n            <BannerActions className=\"flex gap-2 max-md:flex-wrap\">\n              <Button size=\"sm\" className=\"text-sm\">\n                Try now\n              </Button>\n            </BannerActions>\n          </div>\n        </div>\n        <BannerActions className=\"shrink-0\">\n          <Button\n            variant=\"ghost\"\n            className=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\"\n            onClick={() => setIsVisible(false)}\n            aria-label=\"Close banner\"\n          >\n            <svg\n              width={16}\n              height={16}\n              viewBox=\"0 0 24 24\"\n              fill=\"none\"\n              stroke=\"currentColor\"\n              strokeWidth=\"2\"\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              className=\"opacity-60 transition-opacity group-hover:opacity-100\"\n              aria-hidden=\"true\"\n            >\n              <path d=\"M18 6 6 18\" />\n              <path d=\"M6 6 18 18\" />\n            </svg>\n          </Button>\n        </BannerActions>\n      </BannerContent>\n    </Banner>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/banner/banner-09.vue",
          "target": "components/ui/banner-09.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Banner } from '@timui/vue';\nimport { BannerActions } from '@timui/vue';\nimport { BannerContent } from '@timui/vue';\nimport { BannerDescription } from '@timui/vue';\nimport { BannerIcon } from '@timui/vue';\nimport { BannerTitle } from '@timui/vue';\nimport { Button } from '@timui/vue';\n\n\n\nconst isVisible = ref(true);\n\n\nfunction setIsVisible(next: typeof isVisible.value | ((prev: typeof isVisible.value) => typeof isVisible.value)) {\n  isVisible.value = typeof next === 'function'\n    ? (next as (prev: typeof isVisible.value) => typeof isVisible.value)(isVisible.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <Banner class=\"dark bg-muted text-foreground px-4 py-3\"><BannerContent class=\"gap-2 md:items-center\"><div class=\"flex grow gap-3 md:items-center\"><BannerIcon class=\"bg-primary/15 flex size-9 shrink-0 items-center justify-center rounded-full max-md:mt-0.5\"><svg class=\"opacity-80\" :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M4.5 16.5c-1.5-1.5-1-4.5 1-6.5 2-2 9-5 13-5 0 4-3 11-5 13-2 2-5 2.5-6.5 1L4 20l.5-3.5z\" /><path d=\"M15 9 9 15\" /></svg></BannerIcon><div class=\"flex grow flex-col justify-between gap-3 md:flex-row md:items-center\"><div class=\"space-y-0.5\"><BannerTitle>Boost your experience with Timkit UI</BannerTitle><BannerDescription class=\"text-sm\">The new feature is live! Try it out and let us know what you think.\n              </BannerDescription></div><BannerActions class=\"flex gap-2 max-md:flex-wrap\"><Button size=\"sm\" class=\"text-sm\">Try now\n              </Button></BannerActions></div></div><BannerActions class=\"shrink-0\"><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" @click=\"setIsVisible(false)\" aria-label=\"Close banner\"><svg :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\"><path d=\"M18 6 6 18\" /><path d=\"M6 6 18 18\" /></svg></Button></BannerActions></BannerContent></Banner>\n</template>\n"
        },
        {
          "path": "registry/default/components/banner/banner-09.html",
          "target": "components/ui/banner-09.html",
          "type": "registry:component",
          "content": "<template>\n  <Banner class=\"dark bg-muted text-foreground px-4 py-3\"><BannerContent class=\"gap-2 md:items-center\"><div class=\"flex grow gap-3 md:items-center\"><BannerIcon class=\"bg-primary/15 flex size-9 shrink-0 items-center justify-center rounded-full max-md:mt-0.5\"><svg class=\"opacity-80\" width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M4.5 16.5c-1.5-1.5-1-4.5 1-6.5 2-2 9-5 13-5 0 4-3 11-5 13-2 2-5 2.5-6.5 1L4 20l.5-3.5z\" /><path d=\"M15 9 9 15\" /></svg></BannerIcon><div class=\"flex grow flex-col justify-between gap-3 md:flex-row md:items-center\"><div class=\"space-y-0.5\"><BannerTitle>Boost your experience with Timkit UI</BannerTitle><BannerDescription class=\"text-sm\">The new feature is live! Try it out and let us know what you think.\n              </BannerDescription></div><BannerActions class=\"flex gap-2 max-md:flex-wrap\"><Button size=\"sm\" class=\"text-sm\">Try now\n              </Button></BannerActions></div></div><BannerActions class=\"shrink-0\"><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" on-click=\"${() => setIsVisible(false)}\" aria-label=\"Close banner\"><svg width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\"><path d=\"M18 6 6 18\" /><path d=\"M6 6 18 18\" /></svg></Button></BannerActions></BannerContent></Banner>\n</template>"
        },
        {
          "path": "registry/default/components/banner/banner-09.wxml",
          "target": "components/ui/banner-09/banner-09.wxml",
          "type": "registry:component",
          "content": "<view>\n  <banner class=\"dark bg-muted text-foreground px-4 py-3\"><bannercontent class=\"gap-2 md:items-center\"><view class=\"flex grow gap-3 md:items-center\"><bannericon class=\"bg-primary/15 flex size-9 shrink-0 items-center justify-center rounded-full max-md:mt-0.5\"><svg class=\"opacity-80\" width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M4.5 16.5c-1.5-1.5-1-4.5 1-6.5 2-2 9-5 13-5 0 4-3 11-5 13-2 2-5 2.5-6.5 1L4 20l.5-3.5z\" /><path d=\"M15 9 9 15\" /></svg></bannericon><view class=\"flex grow flex-col justify-between gap-3 md:flex-row md:items-center\"><view class=\"space-y-0.5\"><bannertitle>Boost your experience with Timkit UI</bannertitle><bannerdescription class=\"text-sm\">The new feature is live! Try it out and let us know what you think.\n              </bannerdescription></view><banneractions class=\"flex gap-2 max-md:flex-wrap\"><button size=\"sm\" class=\"text-sm\">Try now\n              </button></banneractions></view></view><banneractions class=\"shrink-0\"><button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" bindtap=\"setIsVisible(false)\" aria-label=\"Close banner\"><svg width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\"><path d=\"M18 6 6 18\" /><path d=\"M6 6 18 18\" /></svg></button></banneractions></bannercontent></banner>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "banner"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "banner-09",
          "group": "banner",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "banner-09",
              "path": "registry/default/components/banner/banner-09.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "banner-09",
              "path": "registry/default/components/banner/banner-09.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "banner-09",
              "path": "registry/default/components/banner/banner-09.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "banner-09",
              "path": "registry/default/components/banner/banner-09.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "banners",
        "title": "Banner · Dismissible"
      },
      "categories": [
        "banners",
        "banner"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "banner-10",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "files": [
        {
          "path": "registry/default/components/banner/banner-10.tsx",
          "type": "registry:component",
          "target": "components/ui/banner-10.tsx",
          "content": "'use client'\n\nimport { useEffect, useState } from 'react'\nimport {\n  Banner,\n  BannerActions,\n  BannerContent,\n  BannerDescription,\n  BannerIcon,\n  BannerTitle,\n  Button,\n} from '@timui/react'\n\n// Define the sale end date - eg: new Date('2024-12-31T23:59:59');\nconst saleEndDate = new Date(Date.now() + 9 * 60 * 60 * 1000 + 45 * 60 * 1000 + 24 * 1000) // Setting 9h 45m 24s from now for demo purposes\n\ninterface TimeLeft {\n  days: number\n  hours: number\n  minutes: number\n  seconds: number\n  isExpired: boolean\n}\n\nexport default function Component() {\n  const [isVisible, setIsVisible] = useState(true)\n  const [timeLeft, setTimeLeft] = useState<TimeLeft>({\n    days: 0,\n    hours: 0,\n    minutes: 0,\n    seconds: 0,\n    isExpired: false,\n  })\n\n  useEffect(() => {\n    const calculateTimeLeft = () => {\n      const now = new Date()\n      const difference = saleEndDate.getTime() - now.getTime()\n\n      if (difference <= 0) {\n        setTimeLeft({\n          days: 0,\n          hours: 0,\n          minutes: 0,\n          seconds: 0,\n          isExpired: true,\n        })\n        return\n      }\n\n      const days = Math.floor(difference / (1000 * 60 * 60 * 24))\n      const hours = Math.floor((difference % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))\n      const minutes = Math.floor((difference % (1000 * 60 * 60)) / (1000 * 60))\n      const seconds = Math.floor((difference % (1000 * 60)) / 1000)\n\n      setTimeLeft({\n        days,\n        hours,\n        minutes,\n        seconds,\n        isExpired: false,\n      })\n    }\n\n    // Calculate immediately and then every second\n    calculateTimeLeft()\n    const timer = setInterval(calculateTimeLeft, 1000)\n\n    return () => clearInterval(timer)\n  }, [])\n\n  if (!isVisible || timeLeft.isExpired) return null\n\n  return (\n    <Banner className=\"dark bg-muted text-foreground px-4 py-3\">\n      <BannerContent className=\"gap-2 md:items-center\">\n        <div className=\"flex grow gap-3 md:items-center\">\n          <BannerIcon className=\"bg-primary/15 flex size-9 shrink-0 items-center justify-center rounded-full max-md:mt-0.5\">\n            <svg\n              className=\"opacity-80\"\n              width={16}\n              height={16}\n              viewBox=\"0 0 24 24\"\n              fill=\"none\"\n              stroke=\"currentColor\"\n              strokeWidth=\"2\"\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              aria-hidden=\"true\"\n            >\n              <path d=\"M3 7a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v3a2 2 0 0 0 0 4v3a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-3a2 2 0 0 0 0-4V7z\" />\n              <path d=\"m9 9 6 6\" />\n              <circle cx=\"9\" cy=\"9\" r=\"1\" />\n              <circle cx=\"15\" cy=\"15\" r=\"1\" />\n            </svg>\n          </BannerIcon>\n          <div className=\"flex grow flex-col justify-between gap-3 md:flex-row md:items-center\">\n            <div className=\"space-y-0.5\">\n              <BannerTitle>Black Friday Sale!</BannerTitle>\n              <BannerDescription className=\"text-sm\">\n                It kicks off today and is available for just 24 hours—don&lsquo;t miss out!\n              </BannerDescription>\n            </div>\n            <BannerActions className=\"flex gap-3 max-md:flex-wrap\">\n              <div className=\"divide-primary-foreground bg-primary/15 flex items-center divide-x rounded-md text-sm tabular-nums\">\n                {timeLeft.days > 0 && (\n                  <span className=\"flex h-8 items-center justify-center p-2\">\n                    {timeLeft.days}\n                    <span className=\"text-muted-foreground\">d</span>\n                  </span>\n                )}\n                <span className=\"flex h-8 items-center justify-center p-2\">\n                  {timeLeft.hours.toString().padStart(2, '0')}\n                  <span className=\"text-muted-foreground\">h</span>\n                </span>\n                <span className=\"flex h-8 items-center justify-center p-2\">\n                  {timeLeft.minutes.toString().padStart(2, '0')}\n                  <span className=\"text-muted-foreground\">m</span>\n                </span>\n                <span className=\"flex h-8 items-center justify-center p-2\">\n                  {timeLeft.seconds.toString().padStart(2, '0')}\n                  <span className=\"text-muted-foreground\">s</span>\n                </span>\n              </div>\n              <Button size=\"sm\" className=\"text-sm\">\n                Buy now\n              </Button>\n            </BannerActions>\n          </div>\n        </div>\n        <BannerActions className=\"shrink-0\">\n          <Button\n            variant=\"ghost\"\n            className=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\"\n            onClick={() => setIsVisible(false)}\n            aria-label=\"Close banner\"\n          >\n            <svg\n              width={16}\n              height={16}\n              viewBox=\"0 0 24 24\"\n              fill=\"none\"\n              stroke=\"currentColor\"\n              strokeWidth=\"2\"\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              className=\"opacity-60 transition-opacity group-hover:opacity-100\"\n              aria-hidden=\"true\"\n            >\n              <path d=\"M18 6 6 18\" />\n              <path d=\"M6 6 18 18\" />\n            </svg>\n          </Button>\n        </BannerActions>\n      </BannerContent>\n    </Banner>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/banner/banner-10.vue",
          "target": "components/ui/banner-10.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Banner } from '@timui/vue';\nimport { BannerActions } from '@timui/vue';\nimport { BannerContent } from '@timui/vue';\nimport { BannerDescription } from '@timui/vue';\nimport { BannerIcon } from '@timui/vue';\nimport { BannerTitle } from '@timui/vue';\nimport { Button } from '@timui/vue';\n\n\n\nconst isVisible = ref(true);\nconst timeLeft = ref<TimeLeft>({\n    days: 0,\n    hours: 0,\n    minutes: 0,\n    seconds: 0,\n    isExpired: false,\n  });\n\n\nfunction setIsVisible(next: typeof isVisible.value | ((prev: typeof isVisible.value) => typeof isVisible.value)) {\n  isVisible.value = typeof next === 'function'\n    ? (next as (prev: typeof isVisible.value) => typeof isVisible.value)(isVisible.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <Banner class=\"dark bg-muted text-foreground px-4 py-3\"><BannerContent class=\"gap-2 md:items-center\"><div class=\"flex grow gap-3 md:items-center\"><BannerIcon class=\"bg-primary/15 flex size-9 shrink-0 items-center justify-center rounded-full max-md:mt-0.5\"><svg class=\"opacity-80\" :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 7a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v3a2 2 0 0 0 0 4v3a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-3a2 2 0 0 0 0-4V7z\" /><path d=\"m9 9 6 6\" /><circle cx=\"9\" cy=\"9\" r=\"1\" /><circle cx=\"15\" cy=\"15\" r=\"1\" /></svg></BannerIcon><div class=\"flex grow flex-col justify-between gap-3 md:flex-row md:items-center\"><div class=\"space-y-0.5\"><BannerTitle>Black Friday Sale!</BannerTitle><BannerDescription class=\"text-sm\">It kicks off today and is available for just 24 hours—don&lsquo;t miss out!\n              </BannerDescription></div><BannerActions class=\"flex gap-3 max-md:flex-wrap\"><div class=\"divide-primary-foreground bg-primary/15 flex items-center divide-x rounded-md text-sm tabular-nums\"><span v-if=\"timeLeft.days > 0\" class=\"flex h-8 items-center justify-center p-2\">{{ timeLeft.days }}<span class=\"text-muted-foreground\">d</span></span><span class=\"flex h-8 items-center justify-center p-2\">{{ timeLeft.hours.toString().padStart(2, '0') }}<span class=\"text-muted-foreground\">h</span></span><span class=\"flex h-8 items-center justify-center p-2\">{{ timeLeft.minutes.toString().padStart(2, '0') }}<span class=\"text-muted-foreground\">m</span></span><span class=\"flex h-8 items-center justify-center p-2\">{{ timeLeft.seconds.toString().padStart(2, '0') }}<span class=\"text-muted-foreground\">s</span></span></div><Button size=\"sm\" class=\"text-sm\">Buy now\n              </Button></BannerActions></div></div><BannerActions class=\"shrink-0\"><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" @click=\"setIsVisible(false)\" aria-label=\"Close banner\"><svg :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\"><path d=\"M18 6 6 18\" /><path d=\"M6 6 18 18\" /></svg></Button></BannerActions></BannerContent></Banner>\n</template>\n"
        },
        {
          "path": "registry/default/components/banner/banner-10.html",
          "target": "components/ui/banner-10.html",
          "type": "registry:component",
          "content": "<template>\n  <Banner class=\"dark bg-muted text-foreground px-4 py-3\"><BannerContent class=\"gap-2 md:items-center\"><div class=\"flex grow gap-3 md:items-center\"><BannerIcon class=\"bg-primary/15 flex size-9 shrink-0 items-center justify-center rounded-full max-md:mt-0.5\"><svg class=\"opacity-80\" width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 7a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v3a2 2 0 0 0 0 4v3a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-3a2 2 0 0 0 0-4V7z\" /><path d=\"m9 9 6 6\" /><circle cx=\"9\" cy=\"9\" r=\"1\" /><circle cx=\"15\" cy=\"15\" r=\"1\" /></svg></BannerIcon><div class=\"flex grow flex-col justify-between gap-3 md:flex-row md:items-center\"><div class=\"space-y-0.5\"><BannerTitle>Black Friday Sale!</BannerTitle><BannerDescription class=\"text-sm\">It kicks off today and is available for just 24 hours—don&lsquo;t miss out!\n              </BannerDescription></div><BannerActions class=\"flex gap-3 max-md:flex-wrap\"><div class=\"divide-primary-foreground bg-primary/15 flex items-center divide-x rounded-md text-sm tabular-nums\"><!-- if timeLeft.days > 0 -->\n<span class=\"flex h-8 items-center justify-center p-2\">${timeLeft.days}<span class=\"text-muted-foreground\">d</span></span>\n<!-- endif --><span class=\"flex h-8 items-center justify-center p-2\">${timeLeft.hours.toString().padStart(2, '0')}<span class=\"text-muted-foreground\">h</span></span><span class=\"flex h-8 items-center justify-center p-2\">${timeLeft.minutes.toString().padStart(2, '0')}<span class=\"text-muted-foreground\">m</span></span><span class=\"flex h-8 items-center justify-center p-2\">${timeLeft.seconds.toString().padStart(2, '0')}<span class=\"text-muted-foreground\">s</span></span></div><Button size=\"sm\" class=\"text-sm\">Buy now\n              </Button></BannerActions></div></div><BannerActions class=\"shrink-0\"><Button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" on-click=\"${() => setIsVisible(false)}\" aria-label=\"Close banner\"><svg width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\"><path d=\"M18 6 6 18\" /><path d=\"M6 6 18 18\" /></svg></Button></BannerActions></BannerContent></Banner>\n</template>"
        },
        {
          "path": "registry/default/components/banner/banner-10.wxml",
          "target": "components/ui/banner-10/banner-10.wxml",
          "type": "registry:component",
          "content": "<view>\n  <banner class=\"dark bg-muted text-foreground px-4 py-3\"><bannercontent class=\"gap-2 md:items-center\"><view class=\"flex grow gap-3 md:items-center\"><bannericon class=\"bg-primary/15 flex size-9 shrink-0 items-center justify-center rounded-full max-md:mt-0.5\"><svg class=\"opacity-80\" width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 7a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v3a2 2 0 0 0 0 4v3a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-3a2 2 0 0 0 0-4V7z\" /><path d=\"m9 9 6 6\" /><circle cx=\"9\" cy=\"9\" r=\"1\" /><circle cx=\"15\" cy=\"15\" r=\"1\" /></svg></bannericon><view class=\"flex grow flex-col justify-between gap-3 md:flex-row md:items-center\"><view class=\"space-y-0.5\"><bannertitle>Black Friday Sale!</bannertitle><bannerdescription class=\"text-sm\">It kicks off today and is available for just 24 hours—don&lsquo;t miss out!\n              </bannerdescription></view><banneractions class=\"flex gap-3 max-md:flex-wrap\"><view class=\"divide-primary-foreground bg-primary/15 flex items-center divide-x rounded-md text-sm tabular-nums\"><text wx:if=\"{{timeLeft.days > 0}}\" class=\"flex h-8 items-center justify-center p-2\">{{ timeLeft.days }}<text class=\"text-muted-foreground\">d</text></text><text class=\"flex h-8 items-center justify-center p-2\">{{ timeLeft.hours.toString().padStart(2, '0') }}<text class=\"text-muted-foreground\">h</text></text><text class=\"flex h-8 items-center justify-center p-2\">{{ timeLeft.minutes.toString().padStart(2, '0') }}<text class=\"text-muted-foreground\">m</text></text><text class=\"flex h-8 items-center justify-center p-2\">{{ timeLeft.seconds.toString().padStart(2, '0') }}<text class=\"text-muted-foreground\">s</text></text></view><button size=\"sm\" class=\"text-sm\">Buy now\n              </button></banneractions></view></view><banneractions class=\"shrink-0\"><button variant=\"ghost\" class=\"group -my-1.5 -me-2 size-8 shrink-0 p-0 hover:bg-transparent\" bindtap=\"setIsVisible(false)\" aria-label=\"Close banner\"><svg width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-60 transition-opacity group-hover:opacity-100\" aria-hidden=\"true\"><path d=\"M18 6 6 18\" /><path d=\"M6 6 18 18\" /></svg></button></banneractions></bannercontent></banner>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "banner",
          "countdown",
          "sale"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "banner-10",
          "group": "banner",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "banner-10",
              "path": "registry/default/components/banner/banner-10.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "banner-10",
              "path": "registry/default/components/banner/banner-10.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "banner-10",
              "path": "registry/default/components/banner/banner-10.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "banner-10",
              "path": "registry/default/components/banner/banner-10.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "banners",
        "title": "Banner · Dismissible"
      },
      "categories": [
        "banners",
        "banner"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "banner-11",
      "type": "registry:component",
      "files": [
        {
          "path": "registry/default/components/banner/banner-11.tsx",
          "type": "registry:component",
          "target": "components/ui/banner-11.tsx",
          "content": "import { Banner, BannerContent, BannerDescription, BannerIcon } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Banner className=\"border-b px-4 py-3\">\n      <BannerContent className=\"justify-center\">\n        <BannerIcon className=\"mr-1 text-base leading-none\">📫</BannerIcon>\n        <BannerDescription className=\"text-sm text-foreground text-center\">\n          Subscribe to our newsletter and get 10% off your first order!{' '}\n          <span className=\"text-muted-foreground mx-1\">·</span>{' '}\n          <a href=\"#\" className=\"font-medium underline hover:no-underline\">\n            Subscribe\n          </a>\n        </BannerDescription>\n      </BannerContent>\n    </Banner>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/banner/banner-11.vue",
          "target": "components/ui/banner-11.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Banner } from '@timui/vue';\nimport { BannerContent } from '@timui/vue';\nimport { BannerDescription } from '@timui/vue';\nimport { BannerIcon } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Banner class=\"border-b px-4 py-3\"><BannerContent class=\"justify-center\"><BannerIcon class=\"mr-1 text-base leading-none\">📫</BannerIcon><BannerDescription class=\"text-sm text-foreground text-center\">Subscribe to our newsletter and get 10% off your first order!{{ ' ' }}<span class=\"text-muted-foreground mx-1\">·</span>{{ ' ' }}<a href=\"#\" class=\"font-medium underline hover:no-underline\">Subscribe\n          </a></BannerDescription></BannerContent></Banner>\n</template>\n"
        },
        {
          "path": "registry/default/components/banner/banner-11.html",
          "target": "components/ui/banner-11.html",
          "type": "registry:component",
          "content": "<template>\n  <Banner class=\"border-b px-4 py-3\"><BannerContent class=\"justify-center\"><BannerIcon class=\"mr-1 text-base leading-none\">📫</BannerIcon><BannerDescription class=\"text-sm text-foreground text-center\">Subscribe to our newsletter and get 10% off your first order!${' '}<span class=\"text-muted-foreground mx-1\">·</span>${' '}<a href=\"#\" class=\"font-medium underline hover:no-underline\">Subscribe\n          </a></BannerDescription></BannerContent></Banner>\n</template>"
        },
        {
          "path": "registry/default/components/banner/banner-11.wxml",
          "target": "components/ui/banner-11/banner-11.wxml",
          "type": "registry:component",
          "content": "<view>\n  <banner class=\"border-b px-4 py-3\"><bannercontent class=\"justify-center\"><bannericon class=\"mr-1 text-base leading-none\">📫</bannericon><bannerdescription class=\"text-sm text-foreground text-center\">Subscribe to our newsletter and get 10% off your first order!{{ ' ' }}<text class=\"text-muted-foreground mx-1\">·</text>{{ ' ' }}<a href=\"#\" class=\"font-medium underline hover:no-underline\">Subscribe\n          </a></bannerdescription></bannercontent></banner>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "banner",
          "newsletter",
          "subscribe"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "banner-11",
          "group": "banner",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "banner-11",
              "path": "registry/default/components/banner/banner-11.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "banner-11",
              "path": "registry/default/components/banner/banner-11.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "banner-11",
              "path": "registry/default/components/banner/banner-11.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "banner-11",
              "path": "registry/default/components/banner/banner-11.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "banners",
        "title": "Banner · Interactive State"
      },
      "categories": [
        "banners",
        "banner"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "banner-12",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "files": [
        {
          "path": "registry/default/components/banner/banner-12.tsx",
          "type": "registry:component",
          "target": "components/ui/banner-12.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Banner, BannerActions, BannerContent, BannerDescription, Button } from '@timui/react'\n\nexport default function Component() {\n  const [isDownloading, setIsDownloading] = useState(false)\n\n  const handleDownload = () => {\n    setIsDownloading(true)\n    // Simulate download\n    setTimeout(() => {\n      setIsDownloading(false)\n    }, 2000)\n  }\n\n  return (\n    <Banner className=\"bg-muted px-4 py-3 md:py-2\">\n      <BannerContent className=\"flex-wrap items-center justify-center gap-x-4 gap-y-2\">\n        <BannerDescription className=\"text-sm text-foreground\">\n          <span className=\"font-medium\">v2.1.0</span>\n          <span className=\"text-muted-foreground mx-2\">•</span>\n          New features and improvements available\n        </BannerDescription>\n        <BannerActions>\n          <Button\n            size=\"sm\"\n            variant=\"outline\"\n            disabled={isDownloading}\n            onClick={handleDownload}\n            className=\"min-w-24\"\n          >\n            {isDownloading ? (\n              <>\n                <svg\n                  className=\"-ms-0.5 me-2 animate-spin\"\n                  width={16}\n                  height={16}\n                  viewBox=\"0 0 24 24\"\n                  fill=\"none\"\n                  stroke=\"currentColor\"\n                  strokeWidth=\"2\"\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  aria-hidden=\"true\"\n                >\n                  <circle cx=\"12\" cy=\"12\" r=\"10\" opacity=\"0.25\" />\n                  <path d=\"M22 12a10 10 0 0 1-10 10\" />\n                </svg>\n                Updating...\n              </>\n            ) : (\n              <>\n                <svg\n                  className=\"-ms-0.5\"\n                  width={16}\n                  height={16}\n                  viewBox=\"0 0 24 24\"\n                  fill=\"none\"\n                  stroke=\"currentColor\"\n                  strokeWidth=\"2\"\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  aria-hidden=\"true\"\n                >\n                  <path d=\"M12 3v12\" />\n                  <path d=\"m7 10 5 5 5-5\" />\n                  <path d=\"M5 21h14\" />\n                </svg>\n                Update now\n              </>\n            )}\n          </Button>\n        </BannerActions>\n      </BannerContent>\n    </Banner>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/banner/banner-12.vue",
          "target": "components/ui/banner-12.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Banner } from '@timui/vue';\nimport { BannerActions } from '@timui/vue';\nimport { BannerContent } from '@timui/vue';\nimport { BannerDescription } from '@timui/vue';\nimport { Button } from '@timui/vue';\n\n\n\nconst isDownloading = ref(false);\n\n</script>\n\n<template>\n  <Banner class=\"bg-muted px-4 py-3 md:py-2\"><BannerContent class=\"flex-wrap items-center justify-center gap-x-4 gap-y-2\"><BannerDescription class=\"text-sm text-foreground\"><span class=\"font-medium\">v2.1.0</span><span class=\"text-muted-foreground mx-2\">•</span>New features and improvements available\n        </BannerDescription><BannerActions><Button size=\"sm\" variant=\"outline\" :disabled=\"isDownloading\" @click=\"handleDownload\" class=\"min-w-24\"><template v-if=\"isDownloading\">\n<svg class=\"-ms-0.5 me-2 animate-spin\" :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"10\" opacity=\"0.25\" /><path d=\"M22 12a10 10 0 0 1-10 10\" /></svg>Updating...\n              \n</template>\n<template v-else>\n<svg class=\"-ms-0.5\" :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M12 3v12\" /><path d=\"m7 10 5 5 5-5\" /><path d=\"M5 21h14\" /></svg>Update now\n              \n</template></Button></BannerActions></BannerContent></Banner>\n</template>\n"
        },
        {
          "path": "registry/default/components/banner/banner-12.html",
          "target": "components/ui/banner-12.html",
          "type": "registry:component",
          "content": "<template>\n  <Banner class=\"bg-muted px-4 py-3 md:py-2\"><BannerContent class=\"flex-wrap items-center justify-center gap-x-4 gap-y-2\"><BannerDescription class=\"text-sm text-foreground\"><span class=\"font-medium\">v2.1.0</span><span class=\"text-muted-foreground mx-2\">•</span>New features and improvements available\n        </BannerDescription><BannerActions><Button size=\"sm\" variant=\"outline\" disabled=\"${isDownloading}\" on-click=\"${handleDownload}\" class=\"min-w-24\"><!-- if isDownloading -->\n<svg class=\"-ms-0.5 me-2 animate-spin\" width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"10\" opacity=\"0.25\" /><path d=\"M22 12a10 10 0 0 1-10 10\" /></svg>Updating...\n              \n<!-- else -->\n<svg class=\"-ms-0.5\" width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M12 3v12\" /><path d=\"m7 10 5 5 5-5\" /><path d=\"M5 21h14\" /></svg>Update now\n              \n<!-- endif --></Button></BannerActions></BannerContent></Banner>\n</template>"
        },
        {
          "path": "registry/default/components/banner/banner-12.wxml",
          "target": "components/ui/banner-12/banner-12.wxml",
          "type": "registry:component",
          "content": "<view>\n  <banner class=\"bg-muted px-4 py-3 md:py-2\"><bannercontent class=\"flex-wrap items-center justify-center gap-x-4 gap-y-2\"><bannerdescription class=\"text-sm text-foreground\"><text class=\"font-medium\">v2.1.0</text><text class=\"text-muted-foreground mx-2\">•</text>New features and improvements available\n        </bannerdescription><banneractions><button size=\"sm\" variant=\"outline\" disabled=\"{{isDownloading}}\" bindtap=\"handleDownload\" class=\"min-w-24\"><block wx:if=\"{{isDownloading}}\">\n<svg class=\"-ms-0.5 me-2 animate-spin\" width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"10\" opacity=\"0.25\" /><path d=\"M22 12a10 10 0 0 1-10 10\" /></svg>Updating...\n              \n</block>\n<block wx:else>\n<svg class=\"-ms-0.5\" width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M12 3v12\" /><path d=\"m7 10 5 5 5-5\" /><path d=\"M5 21h14\" /></svg>Update now\n              \n</block></button></banneractions></bannercontent></banner>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "banner"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "banner-12",
          "group": "banner",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "banner-12",
              "path": "registry/default/components/banner/banner-12.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "banner-12",
              "path": "registry/default/components/banner/banner-12.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "banner-12",
              "path": "registry/default/components/banner/banner-12.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "banner-12",
              "path": "registry/default/components/banner/banner-12.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "banners",
        "title": "Banner · Loading State"
      },
      "categories": [
        "banners",
        "banner"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "dialog-01",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/alert-dialog.json",
        "https://ui.timkit.cn/r/button.json"
      ],
      "files": [
        {
          "path": "registry/default/components/dialog/dialog-01.tsx",
          "type": "registry:component",
          "target": "components/ui/dialog-01.tsx",
          "content": "import {\n  AlertDialog,\n  AlertDialogAction,\n  AlertDialogCancel,\n  AlertDialogContent,\n  AlertDialogDescription,\n  AlertDialogFooter,\n  AlertDialogHeader,\n  AlertDialogTitle,\n  AlertDialogTrigger,\n  Button,\n} from '@timui/react'\n\nexport default function AlertComponent() {\n  return (\n    <AlertDialog>\n      <AlertDialogTrigger asChild>\n        <Button variant=\"outline\">Alert dialog</Button>\n      </AlertDialogTrigger>\n      <AlertDialogContent>\n        <AlertDialogHeader>\n          <AlertDialogTitle>Are you sure?</AlertDialogTitle>\n          <AlertDialogDescription>\n            Take a moment to review the details provided to ensure you understand the implications.\n          </AlertDialogDescription>\n        </AlertDialogHeader>\n        <AlertDialogFooter>\n          <AlertDialogCancel>Cancel</AlertDialogCancel>\n          <AlertDialogAction>Okay</AlertDialogAction>\n        </AlertDialogFooter>\n      </AlertDialogContent>\n    </AlertDialog>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-01.vue",
          "target": "components/ui/dialog-01.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { AlertDialog } from '@timui/vue';\nimport { AlertDialogAction } from '@timui/vue';\nimport { AlertDialogCancel } from '@timui/vue';\nimport { AlertDialogContent } from '@timui/vue';\nimport { AlertDialogDescription } from '@timui/vue';\nimport { AlertDialogFooter } from '@timui/vue';\nimport { AlertDialogHeader } from '@timui/vue';\nimport { AlertDialogTitle } from '@timui/vue';\nimport { AlertDialogTrigger } from '@timui/vue';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <AlertDialog><AlertDialogTrigger as-child><Button variant=\"outline\">Alert dialog</Button></AlertDialogTrigger><AlertDialogContent><AlertDialogHeader><AlertDialogTitle>Are you sure?</AlertDialogTitle><AlertDialogDescription>Take a moment to review the details provided to ensure you understand the implications.\n          </AlertDialogDescription></AlertDialogHeader><AlertDialogFooter><AlertDialogCancel>Cancel</AlertDialogCancel><AlertDialogAction>Okay</AlertDialogAction></AlertDialogFooter></AlertDialogContent></AlertDialog>\n</template>\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-01.html",
          "target": "components/ui/dialog-01.html",
          "type": "registry:component",
          "content": "<template>\n  <AlertDialog><AlertDialogTrigger aschild><Button variant=\"outline\">Alert dialog</Button></AlertDialogTrigger><AlertDialogContent><AlertDialogHeader><AlertDialogTitle>Are you sure?</AlertDialogTitle><AlertDialogDescription>Take a moment to review the details provided to ensure you understand the implications.\n          </AlertDialogDescription></AlertDialogHeader><AlertDialogFooter><AlertDialogCancel>Cancel</AlertDialogCancel><AlertDialogAction>Okay</AlertDialogAction></AlertDialogFooter></AlertDialogContent></AlertDialog>\n</template>"
        },
        {
          "path": "registry/default/components/dialog/dialog-01.wxml",
          "target": "components/ui/dialog-01/dialog-01.wxml",
          "type": "registry:component",
          "content": "<view>\n  <alertdialog><alertdialogtrigger aschild><button variant=\"outline\">Alert dialog</button></alertdialogtrigger><alertdialogcontent><alertdialogheader><alertdialogtitle>Are you sure?</alertdialogtitle><alertdialogdescription>Take a moment to review the details provided to ensure you understand the implications.\n          </alertdialogdescription></alertdialogheader><alertdialogfooter><alertdialogcancel>Cancel</alertdialogcancel><alertdialogaction>Okay</alertdialogaction></alertdialogfooter></alertdialogcontent></alertdialog>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dialog",
          "modal",
          "alert",
          "alert dialog",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dialog-01",
          "group": "dialog",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dialog-01",
              "path": "registry/default/components/dialog/dialog-01.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dialog-01",
              "path": "registry/default/components/dialog/dialog-01.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dialog-01",
              "path": "registry/default/components/dialog/dialog-01.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dialog-01",
              "path": "registry/default/components/dialog/dialog-01.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dialog",
        "title": "Dialog · Overlay Pattern"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "dialog"
      ]
    },
    {
      "name": "dialog-02",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/alert-dialog.json",
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/dialog/dialog-02.tsx",
          "type": "registry:component",
          "target": "components/ui/dialog-02.tsx",
          "content": "import {\n  AlertDialog,\n  AlertDialogAction,\n  AlertDialogCancel,\n  AlertDialogContent,\n  AlertDialogDescription,\n  AlertDialogFooter,\n  AlertDialogHeader,\n  AlertDialogTitle,\n  AlertDialogTrigger,\n  Button,\n} from '@timui/react'\nimport { CircleAlertIcon } from 'lucide-react'\n\nexport default function AlertComponent() {\n  return (\n    <AlertDialog>\n      <AlertDialogTrigger asChild>\n        <Button variant=\"outline\">Alert dialog with icon</Button>\n      </AlertDialogTrigger>\n      <AlertDialogContent>\n        <div className=\"flex flex-col gap-2 max-sm:items-center sm:flex-row sm:gap-4\">\n          <div\n            className=\"flex size-9 shrink-0 items-center justify-center rounded-full border\"\n            aria-hidden=\"true\"\n          >\n            <CircleAlertIcon className=\"opacity-80\" size={16} />\n          </div>\n          <AlertDialogHeader>\n            <AlertDialogTitle>Are you sure?</AlertDialogTitle>\n            <AlertDialogDescription>\n              Are you sure you want to delete your account? All your data will be removed.\n            </AlertDialogDescription>\n          </AlertDialogHeader>\n        </div>\n        <AlertDialogFooter>\n          <AlertDialogCancel>Cancel</AlertDialogCancel>\n          <AlertDialogAction>Confirm</AlertDialogAction>\n        </AlertDialogFooter>\n      </AlertDialogContent>\n    </AlertDialog>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-02.vue",
          "target": "components/ui/dialog-02.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { CircleAlertIcon } from 'lucide-vue-next';\nimport { AlertDialog } from '@timui/vue';\nimport { AlertDialogAction } from '@timui/vue';\nimport { AlertDialogCancel } from '@timui/vue';\nimport { AlertDialogContent } from '@timui/vue';\nimport { AlertDialogDescription } from '@timui/vue';\nimport { AlertDialogFooter } from '@timui/vue';\nimport { AlertDialogHeader } from '@timui/vue';\nimport { AlertDialogTitle } from '@timui/vue';\nimport { AlertDialogTrigger } from '@timui/vue';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <AlertDialog><AlertDialogTrigger as-child><Button variant=\"outline\">Alert dialog with icon</Button></AlertDialogTrigger><AlertDialogContent><div class=\"flex flex-col gap-2 max-sm:items-center sm:flex-row sm:gap-4\"><div class=\"flex size-9 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><CircleAlertIcon class=\"opacity-80\" :size=\"16\" /></div><AlertDialogHeader><AlertDialogTitle>Are you sure?</AlertDialogTitle><AlertDialogDescription>Are you sure you want to delete your account? All your data will be removed.\n            </AlertDialogDescription></AlertDialogHeader></div><AlertDialogFooter><AlertDialogCancel>Cancel</AlertDialogCancel><AlertDialogAction>Confirm</AlertDialogAction></AlertDialogFooter></AlertDialogContent></AlertDialog>\n</template>\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-02.html",
          "target": "components/ui/dialog-02.html",
          "type": "registry:component",
          "content": "<template>\n  <AlertDialog><AlertDialogTrigger aschild><Button variant=\"outline\">Alert dialog with icon</Button></AlertDialogTrigger><AlertDialogContent><div class=\"flex flex-col gap-2 max-sm:items-center sm:flex-row sm:gap-4\"><div class=\"flex size-9 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><CircleAlertIcon class=\"opacity-80\" size=\"${16}\" /></div><AlertDialogHeader><AlertDialogTitle>Are you sure?</AlertDialogTitle><AlertDialogDescription>Are you sure you want to delete your account? All your data will be removed.\n            </AlertDialogDescription></AlertDialogHeader></div><AlertDialogFooter><AlertDialogCancel>Cancel</AlertDialogCancel><AlertDialogAction>Confirm</AlertDialogAction></AlertDialogFooter></AlertDialogContent></AlertDialog>\n</template>"
        },
        {
          "path": "registry/default/components/dialog/dialog-02.wxml",
          "target": "components/ui/dialog-02/dialog-02.wxml",
          "type": "registry:component",
          "content": "<view>\n  <alertdialog><alertdialogtrigger aschild><button variant=\"outline\">Alert dialog with icon</button></alertdialogtrigger><alertdialogcontent><view class=\"flex flex-col gap-2 max-sm:items-center sm:flex-row sm:gap-4\"><view class=\"flex size-9 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><circlealerticon class=\"opacity-80\" size=\"{{16}}\" /></view><alertdialogheader><alertdialogtitle>Are you sure?</alertdialogtitle><alertdialogdescription>Are you sure you want to delete your account? All your data will be removed.\n            </alertdialogdescription></alertdialogheader></view><alertdialogfooter><alertdialogcancel>Cancel</alertdialogcancel><alertdialogaction>Confirm</alertdialogaction></alertdialogfooter></alertdialogcontent></alertdialog>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dialog",
          "modal",
          "alert",
          "alert dialog",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dialog-02",
          "group": "dialog",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dialog-02",
              "path": "registry/default/components/dialog/dialog-02.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dialog-02",
              "path": "registry/default/components/dialog/dialog-02.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dialog-02",
              "path": "registry/default/components/dialog/dialog-02.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dialog-02",
              "path": "registry/default/components/dialog/dialog-02.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dialog",
        "title": "Dialog · Overlay Pattern"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "dialog"
      ]
    },
    {
      "name": "dialog-03",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dialog.json"
      ],
      "files": [
        {
          "path": "registry/default/components/dialog/dialog-03.tsx",
          "type": "registry:component",
          "target": "components/ui/dialog-03.tsx",
          "content": "import {\n  Button,\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n} from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Dialog>\n      <DialogTrigger asChild>\n        <Button variant=\"outline\">Scrollable (native scrollbar)</Button>\n      </DialogTrigger>\n      <DialogContent className=\"flex flex-col gap-0 p-0 sm:max-h-[min(640px,80vh)] sm:max-w-lg [&>button:last-child]:hidden\">\n        <div className=\"overflow-y-auto\">\n          <DialogHeader className=\"contents space-y-0 text-left\">\n            <DialogTitle className=\"px-6 pt-6\">Frequently Asked Questions (FAQ)</DialogTitle>\n            <DialogDescription asChild>\n              <div className=\"p-6\">\n                <div className=\"[&_strong]:text-foreground space-y-4 [&_strong]:font-semibold\">\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Account Management</strong>\n                    </p>\n                    <p>\n                      Navigate to the registration page, provide required information, and verify\n                      your email address. You can sign up using your email or through social media\n                      platforms.\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Password Reset Process</strong>\n                    </p>\n                    <p>\n                      Users can reset their password through the account settings page. Click\n                      &quot;Forgot Password&quot; and follow the email verification steps to regain\n                      account access quickly and securely.\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Service Pricing Tiers</strong>\n                    </p>\n                    <p>\n                      We offer three primary subscription levels designed to meet diverse user\n                      needs: Basic (free with limited features), Professional (monthly fee with\n                      comprehensive access), and Enterprise (custom pricing with full platform\n                      capabilities).\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Technical Support Channels</strong>\n                    </p>\n                    <p>\n                      Customer support is accessible through multiple communication methods\n                      including email support, live chat during business hours, an integrated\n                      support ticket system, and phone support specifically for enterprise-level\n                      customers.\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Data Protection Strategies</strong>\n                    </p>\n                    <p>\n                      Our platform implements rigorous security measures including 256-bit SSL\n                      encryption, regular comprehensive security audits, strict data access\n                      controls, and compliance with international privacy protection standards.\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Platform Compatibility</strong>\n                    </p>\n                    <p>\n                      The service supports multiple device and operating system environments,\n                      including web browsers like Chrome and Firefox, mobile applications for iOS\n                      and Android, and desktop applications compatible with Windows and macOS.\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Subscription Management</strong>\n                    </p>\n                    <p>\n                      Subscriptions can be cancelled at any time through account settings, with\n                      pro-rated refunds available within 30 days of payment. Both monthly and annual\n                      billing options are provided, with special discounts offered for annual\n                      commitments.\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Payment Method Options</strong>\n                    </p>\n                    <p>\n                      We accept a wide range of payment methods including major credit cards such as\n                      Visa, MasterCard, and American Express, digital payment platforms like PayPal,\n                      and direct bank transfers. Regional payment options may also be available\n                      depending on user location.\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Customer Support</strong>\n                    </p>\n                    <p>\n                      Our dedicated customer support team is available 24/7, providing quick and\n                      efficient assistance to address any inquiries or issues you may have.\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Privacy Policy</strong>\n                    </p>\n                    <p>\n                      Our privacy policy outlines how we collect, use, and protect your personal\n                      data, ensuring your privacy is protected at all times.\n                    </p>\n                  </div>\n                </div>\n              </div>\n            </DialogDescription>\n          </DialogHeader>\n          <DialogFooter className=\"px-6 pb-6 sm:justify-start\">\n            <DialogClose asChild>\n              <Button type=\"button\" variant=\"outline\">\n                Cancel\n              </Button>\n            </DialogClose>\n            <DialogClose asChild>\n              <Button type=\"button\">Okay</Button>\n            </DialogClose>\n          </DialogFooter>\n        </div>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-03.vue",
          "target": "components/ui/dialog-03.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\nimport { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Dialog><DialogTrigger as-child><Button variant=\"outline\">Scrollable (native scrollbar)</Button></DialogTrigger><DialogContent class=\"flex flex-col gap-0 p-0 sm:max-h-[min(640px,80vh)] sm:max-w-lg [&>button:last-child]:hidden\"><div class=\"overflow-y-auto\"><DialogHeader class=\"contents space-y-0 text-left\"><DialogTitle class=\"px-6 pt-6\">Frequently Asked Questions (FAQ)</DialogTitle><DialogDescription as-child><div class=\"p-6\"><div class=\"[&_strong]:text-foreground space-y-4 [&_strong]:font-semibold\"><div class=\"space-y-1\"><p><strong>Account Management</strong></p><p>Navigate to the registration page, provide required information, and verify\n                      your email address. You can sign up using your email or through social media\n                      platforms.\n                    </p></div><div class=\"space-y-1\"><p><strong>Password Reset Process</strong></p><p>Users can reset their password through the account settings page. Click\n                      &quot;Forgot Password&quot; and follow the email verification steps to regain\n                      account access quickly and securely.\n                    </p></div><div class=\"space-y-1\"><p><strong>Service Pricing Tiers</strong></p><p>We offer three primary subscription levels designed to meet diverse user\n                      needs: Basic (free with limited features), Professional (monthly fee with\n                      comprehensive access), and Enterprise (custom pricing with full platform\n                      capabilities).\n                    </p></div><div class=\"space-y-1\"><p><strong>Technical Support Channels</strong></p><p>Customer support is accessible through multiple communication methods\n                      including email support, live chat during business hours, an integrated\n                      support ticket system, and phone support specifically for enterprise-level\n                      customers.\n                    </p></div><div class=\"space-y-1\"><p><strong>Data Protection Strategies</strong></p><p>Our platform implements rigorous security measures including 256-bit SSL\n                      encryption, regular comprehensive security audits, strict data access\n                      controls, and compliance with international privacy protection standards.\n                    </p></div><div class=\"space-y-1\"><p><strong>Platform Compatibility</strong></p><p>The service supports multiple device and operating system environments,\n                      including web browsers like Chrome and Firefox, mobile applications for iOS\n                      and Android, and desktop applications compatible with Windows and macOS.\n                    </p></div><div class=\"space-y-1\"><p><strong>Subscription Management</strong></p><p>Subscriptions can be cancelled at any time through account settings, with\n                      pro-rated refunds available within 30 days of payment. Both monthly and annual\n                      billing options are provided, with special discounts offered for annual\n                      commitments.\n                    </p></div><div class=\"space-y-1\"><p><strong>Payment Method Options</strong></p><p>We accept a wide range of payment methods including major credit cards such as\n                      Visa, MasterCard, and American Express, digital payment platforms like PayPal,\n                      and direct bank transfers. Regional payment options may also be available\n                      depending on user location.\n                    </p></div><div class=\"space-y-1\"><p><strong>Customer Support</strong></p><p>Our dedicated customer support team is available 24/7, providing quick and\n                      efficient assistance to address any inquiries or issues you may have.\n                    </p></div><div class=\"space-y-1\"><p><strong>Privacy Policy</strong></p><p>Our privacy policy outlines how we collect, use, and protect your personal\n                      data, ensuring your privacy is protected at all times.\n                    </p></div></div></div></DialogDescription></DialogHeader><DialogFooter class=\"px-6 pb-6 sm:justify-start\"><DialogClose as-child><Button type=\"button\" variant=\"outline\">Cancel\n              </Button></DialogClose><DialogClose as-child><Button type=\"button\">Okay</Button></DialogClose></DialogFooter></div></DialogContent></Dialog>\n</template>\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-03.html",
          "target": "components/ui/dialog-03.html",
          "type": "registry:component",
          "content": "<template>\n  <Dialog><DialogTrigger aschild><Button variant=\"outline\">Scrollable (native scrollbar)</Button></DialogTrigger><DialogContent class=\"flex flex-col gap-0 p-0 sm:max-h-[min(640px,80vh)] sm:max-w-lg [&>button:last-child]:hidden\"><div class=\"overflow-y-auto\"><DialogHeader class=\"contents space-y-0 text-left\"><DialogTitle class=\"px-6 pt-6\">Frequently Asked Questions (FAQ)</DialogTitle><DialogDescription aschild><div class=\"p-6\"><div class=\"[&_strong]:text-foreground space-y-4 [&_strong]:font-semibold\"><div class=\"space-y-1\"><p><strong>Account Management</strong></p><p>Navigate to the registration page, provide required information, and verify\n                      your email address. You can sign up using your email or through social media\n                      platforms.\n                    </p></div><div class=\"space-y-1\"><p><strong>Password Reset Process</strong></p><p>Users can reset their password through the account settings page. Click\n                      &quot;Forgot Password&quot; and follow the email verification steps to regain\n                      account access quickly and securely.\n                    </p></div><div class=\"space-y-1\"><p><strong>Service Pricing Tiers</strong></p><p>We offer three primary subscription levels designed to meet diverse user\n                      needs: Basic (free with limited features), Professional (monthly fee with\n                      comprehensive access), and Enterprise (custom pricing with full platform\n                      capabilities).\n                    </p></div><div class=\"space-y-1\"><p><strong>Technical Support Channels</strong></p><p>Customer support is accessible through multiple communication methods\n                      including email support, live chat during business hours, an integrated\n                      support ticket system, and phone support specifically for enterprise-level\n                      customers.\n                    </p></div><div class=\"space-y-1\"><p><strong>Data Protection Strategies</strong></p><p>Our platform implements rigorous security measures including 256-bit SSL\n                      encryption, regular comprehensive security audits, strict data access\n                      controls, and compliance with international privacy protection standards.\n                    </p></div><div class=\"space-y-1\"><p><strong>Platform Compatibility</strong></p><p>The service supports multiple device and operating system environments,\n                      including web browsers like Chrome and Firefox, mobile applications for iOS\n                      and Android, and desktop applications compatible with Windows and macOS.\n                    </p></div><div class=\"space-y-1\"><p><strong>Subscription Management</strong></p><p>Subscriptions can be cancelled at any time through account settings, with\n                      pro-rated refunds available within 30 days of payment. Both monthly and annual\n                      billing options are provided, with special discounts offered for annual\n                      commitments.\n                    </p></div><div class=\"space-y-1\"><p><strong>Payment Method Options</strong></p><p>We accept a wide range of payment methods including major credit cards such as\n                      Visa, MasterCard, and American Express, digital payment platforms like PayPal,\n                      and direct bank transfers. Regional payment options may also be available\n                      depending on user location.\n                    </p></div><div class=\"space-y-1\"><p><strong>Customer Support</strong></p><p>Our dedicated customer support team is available 24/7, providing quick and\n                      efficient assistance to address any inquiries or issues you may have.\n                    </p></div><div class=\"space-y-1\"><p><strong>Privacy Policy</strong></p><p>Our privacy policy outlines how we collect, use, and protect your personal\n                      data, ensuring your privacy is protected at all times.\n                    </p></div></div></div></DialogDescription></DialogHeader><DialogFooter class=\"px-6 pb-6 sm:justify-start\"><DialogClose aschild><Button type=\"button\" variant=\"outline\">Cancel\n              </Button></DialogClose><DialogClose aschild><Button type=\"button\">Okay</Button></DialogClose></DialogFooter></div></DialogContent></Dialog>\n</template>"
        },
        {
          "path": "registry/default/components/dialog/dialog-03.wxml",
          "target": "components/ui/dialog-03/dialog-03.wxml",
          "type": "registry:component",
          "content": "<view>\n  <dialog><dialogtrigger aschild><button variant=\"outline\">Scrollable (native scrollbar)</button></dialogtrigger><dialogcontent class=\"flex flex-col gap-0 p-0 sm:max-h-[min(640px,80vh)] sm:max-w-lg [&>button:last-child]:hidden\"><view class=\"overflow-y-auto\"><dialogheader class=\"contents space-y-0 text-left\"><dialogtitle class=\"px-6 pt-6\">Frequently Asked Questions (FAQ)</dialogtitle><dialogdescription aschild><view class=\"p-6\"><view class=\"[&_strong]:text-foreground space-y-4 [&_strong]:font-semibold\"><view class=\"space-y-1\"><text><strong>Account Management</strong></text><text>Navigate to the registration page, provide required information, and verify\n                      your email address. You can sign up using your email or through social media\n                      platforms.\n                    </text></view><view class=\"space-y-1\"><text><strong>Password Reset Process</strong></text><text>Users can reset their password through the account settings page. Click\n                      &quot;Forgot Password&quot; and follow the email verification steps to regain\n                      account access quickly and securely.\n                    </text></view><view class=\"space-y-1\"><text><strong>Service Pricing Tiers</strong></text><text>We offer three primary subscription levels designed to meet diverse user\n                      needs: Basic (free with limited features), Professional (monthly fee with\n                      comprehensive access), and Enterprise (custom pricing with full platform\n                      capabilities).\n                    </text></view><view class=\"space-y-1\"><text><strong>Technical Support Channels</strong></text><text>Customer support is accessible through multiple communication methods\n                      including email support, live chat during business hours, an integrated\n                      support ticket system, and phone support specifically for enterprise-level\n                      customers.\n                    </text></view><view class=\"space-y-1\"><text><strong>Data Protection Strategies</strong></text><text>Our platform implements rigorous security measures including 256-bit SSL\n                      encryption, regular comprehensive security audits, strict data access\n                      controls, and compliance with international privacy protection standards.\n                    </text></view><view class=\"space-y-1\"><text><strong>Platform Compatibility</strong></text><text>The service supports multiple device and operating system environments,\n                      including web browsers like Chrome and Firefox, mobile applications for iOS\n                      and Android, and desktop applications compatible with Windows and macOS.\n                    </text></view><view class=\"space-y-1\"><text><strong>Subscription Management</strong></text><text>Subscriptions can be cancelled at any time through account settings, with\n                      pro-rated refunds available within 30 days of payment. Both monthly and annual\n                      billing options are provided, with special discounts offered for annual\n                      commitments.\n                    </text></view><view class=\"space-y-1\"><text><strong>Payment Method Options</strong></text><text>We accept a wide range of payment methods including major credit cards such as\n                      Visa, MasterCard, and American Express, digital payment platforms like PayPal,\n                      and direct bank transfers. Regional payment options may also be available\n                      depending on user location.\n                    </text></view><view class=\"space-y-1\"><text><strong>Customer Support</strong></text><text>Our dedicated customer support team is available 24/7, providing quick and\n                      efficient assistance to address any inquiries or issues you may have.\n                    </text></view><view class=\"space-y-1\"><text><strong>Privacy Policy</strong></text><text>Our privacy policy outlines how we collect, use, and protect your personal\n                      data, ensuring your privacy is protected at all times.\n                    </text></view></view></view></dialogdescription></dialogheader><dialogfooter class=\"px-6 pb-6 sm:justify-start\"><dialogclose aschild><button type=\"button\" variant=\"outline\">Cancel\n              </button></dialogclose><dialogclose aschild><button type=\"button\">Okay</button></dialogclose></dialogfooter></view></dialogcontent></dialog>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dialog",
          "modal",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dialog-03",
          "group": "dialog",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dialog-03",
              "path": "registry/default/components/dialog/dialog-03.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dialog-03",
              "path": "registry/default/components/dialog/dialog-03.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dialog-03",
              "path": "registry/default/components/dialog/dialog-03.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dialog-03",
              "path": "registry/default/components/dialog/dialog-03.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dialog",
        "title": "Dialog · Dismissible"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "dialog"
      ]
    },
    {
      "name": "dialog-04",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dialog.json",
        "https://ui.timkit.cn/r/scroll-area.json"
      ],
      "files": [
        {
          "path": "registry/default/components/dialog/dialog-04.tsx",
          "type": "registry:component",
          "target": "components/ui/dialog-04.tsx",
          "content": "import {\n  Button,\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n  ScrollArea,\n} from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Dialog>\n      <DialogTrigger asChild>\n        <Button variant=\"outline\">Scrollable (custom scrollbar)</Button>\n      </DialogTrigger>\n      <DialogContent className=\"flex flex-col gap-0 p-0 sm:max-h-[min(640px,80vh)] sm:max-w-lg [&>button:last-child]:hidden\">\n        <ScrollArea className=\"flex max-h-full flex-col overflow-hidden\">\n          <DialogHeader className=\"contents space-y-0 text-left\">\n            <DialogTitle className=\"px-6 pt-6\">Frequently Asked Questions (FAQ)</DialogTitle>\n            <DialogDescription asChild>\n              <div className=\"p-6\">\n                <div className=\"[&_strong]:text-foreground space-y-4 [&_strong]:font-semibold\">\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Account Management</strong>\n                    </p>\n                    <p>\n                      Navigate to the registration page, provide required information, and verify\n                      your email address. You can sign up using your email or through social media\n                      platforms.\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Password Reset Process</strong>\n                    </p>\n                    <p>\n                      Users can reset their password through the account settings page. Click\n                      &quot;Forgot Password&quot; and follow the email verification steps to regain\n                      account access quickly and securely.\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Service Pricing Tiers</strong>\n                    </p>\n                    <p>\n                      We offer three primary subscription levels designed to meet diverse user\n                      needs: Basic (free with limited features), Professional (monthly fee with\n                      comprehensive access), and Enterprise (custom pricing with full platform\n                      capabilities).\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Technical Support Channels</strong>\n                    </p>\n                    <p>\n                      Customer support is accessible through multiple communication methods\n                      including email support, live chat during business hours, an integrated\n                      support ticket system, and phone support specifically for enterprise-level\n                      customers.\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Data Protection Strategies</strong>\n                    </p>\n                    <p>\n                      Our platform implements rigorous security measures including 256-bit SSL\n                      encryption, regular comprehensive security audits, strict data access\n                      controls, and compliance with international privacy protection standards.\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Platform Compatibility</strong>\n                    </p>\n                    <p>\n                      The service supports multiple device and operating system environments,\n                      including web browsers like Chrome and Firefox, mobile applications for iOS\n                      and Android, and desktop applications compatible with Windows and macOS.\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Subscription Management</strong>\n                    </p>\n                    <p>\n                      Subscriptions can be cancelled at any time through account settings, with\n                      pro-rated refunds available within 30 days of payment. Both monthly and annual\n                      billing options are provided, with special discounts offered for annual\n                      commitments.\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Payment Method Options</strong>\n                    </p>\n                    <p>\n                      We accept a wide range of payment methods including major credit cards such as\n                      Visa, MasterCard, and American Express, digital payment platforms like PayPal,\n                      and direct bank transfers. Regional payment options may also be available\n                      depending on user location.\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Customer Support</strong>\n                    </p>\n                    <p>\n                      Our dedicated customer support team is available 24/7, providing quick and\n                      efficient assistance to address any inquiries or issues you may have.\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Privacy Policy</strong>\n                    </p>\n                    <p>\n                      Our privacy policy outlines how we collect, use, and protect your personal\n                      data, ensuring your privacy is protected at all times.\n                    </p>\n                  </div>\n                </div>\n              </div>\n            </DialogDescription>\n          </DialogHeader>\n          <DialogFooter className=\"px-6 pb-6 sm:justify-start\">\n            <DialogClose asChild>\n              <Button type=\"button\" variant=\"outline\">\n                Cancel\n              </Button>\n            </DialogClose>\n            <DialogClose asChild>\n              <Button type=\"button\">Okay</Button>\n            </DialogClose>\n          </DialogFooter>\n        </ScrollArea>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-04.vue",
          "target": "components/ui/dialog-04.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\nimport { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from '@timui/vue';\nimport { ScrollArea } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Dialog><DialogTrigger as-child><Button variant=\"outline\">Scrollable (custom scrollbar)</Button></DialogTrigger><DialogContent class=\"flex flex-col gap-0 p-0 sm:max-h-[min(640px,80vh)] sm:max-w-lg [&>button:last-child]:hidden\"><ScrollArea class=\"flex max-h-full flex-col overflow-hidden\"><DialogHeader class=\"contents space-y-0 text-left\"><DialogTitle class=\"px-6 pt-6\">Frequently Asked Questions (FAQ)</DialogTitle><DialogDescription as-child><div class=\"p-6\"><div class=\"[&_strong]:text-foreground space-y-4 [&_strong]:font-semibold\"><div class=\"space-y-1\"><p><strong>Account Management</strong></p><p>Navigate to the registration page, provide required information, and verify\n                      your email address. You can sign up using your email or through social media\n                      platforms.\n                    </p></div><div class=\"space-y-1\"><p><strong>Password Reset Process</strong></p><p>Users can reset their password through the account settings page. Click\n                      &quot;Forgot Password&quot; and follow the email verification steps to regain\n                      account access quickly and securely.\n                    </p></div><div class=\"space-y-1\"><p><strong>Service Pricing Tiers</strong></p><p>We offer three primary subscription levels designed to meet diverse user\n                      needs: Basic (free with limited features), Professional (monthly fee with\n                      comprehensive access), and Enterprise (custom pricing with full platform\n                      capabilities).\n                    </p></div><div class=\"space-y-1\"><p><strong>Technical Support Channels</strong></p><p>Customer support is accessible through multiple communication methods\n                      including email support, live chat during business hours, an integrated\n                      support ticket system, and phone support specifically for enterprise-level\n                      customers.\n                    </p></div><div class=\"space-y-1\"><p><strong>Data Protection Strategies</strong></p><p>Our platform implements rigorous security measures including 256-bit SSL\n                      encryption, regular comprehensive security audits, strict data access\n                      controls, and compliance with international privacy protection standards.\n                    </p></div><div class=\"space-y-1\"><p><strong>Platform Compatibility</strong></p><p>The service supports multiple device and operating system environments,\n                      including web browsers like Chrome and Firefox, mobile applications for iOS\n                      and Android, and desktop applications compatible with Windows and macOS.\n                    </p></div><div class=\"space-y-1\"><p><strong>Subscription Management</strong></p><p>Subscriptions can be cancelled at any time through account settings, with\n                      pro-rated refunds available within 30 days of payment. Both monthly and annual\n                      billing options are provided, with special discounts offered for annual\n                      commitments.\n                    </p></div><div class=\"space-y-1\"><p><strong>Payment Method Options</strong></p><p>We accept a wide range of payment methods including major credit cards such as\n                      Visa, MasterCard, and American Express, digital payment platforms like PayPal,\n                      and direct bank transfers. Regional payment options may also be available\n                      depending on user location.\n                    </p></div><div class=\"space-y-1\"><p><strong>Customer Support</strong></p><p>Our dedicated customer support team is available 24/7, providing quick and\n                      efficient assistance to address any inquiries or issues you may have.\n                    </p></div><div class=\"space-y-1\"><p><strong>Privacy Policy</strong></p><p>Our privacy policy outlines how we collect, use, and protect your personal\n                      data, ensuring your privacy is protected at all times.\n                    </p></div></div></div></DialogDescription></DialogHeader><DialogFooter class=\"px-6 pb-6 sm:justify-start\"><DialogClose as-child><Button type=\"button\" variant=\"outline\">Cancel\n              </Button></DialogClose><DialogClose as-child><Button type=\"button\">Okay</Button></DialogClose></DialogFooter></ScrollArea></DialogContent></Dialog>\n</template>\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-04.html",
          "target": "components/ui/dialog-04.html",
          "type": "registry:component",
          "content": "<template>\n  <Dialog><DialogTrigger aschild><Button variant=\"outline\">Scrollable (custom scrollbar)</Button></DialogTrigger><DialogContent class=\"flex flex-col gap-0 p-0 sm:max-h-[min(640px,80vh)] sm:max-w-lg [&>button:last-child]:hidden\"><ScrollArea class=\"flex max-h-full flex-col overflow-hidden\"><DialogHeader class=\"contents space-y-0 text-left\"><DialogTitle class=\"px-6 pt-6\">Frequently Asked Questions (FAQ)</DialogTitle><DialogDescription aschild><div class=\"p-6\"><div class=\"[&_strong]:text-foreground space-y-4 [&_strong]:font-semibold\"><div class=\"space-y-1\"><p><strong>Account Management</strong></p><p>Navigate to the registration page, provide required information, and verify\n                      your email address. You can sign up using your email or through social media\n                      platforms.\n                    </p></div><div class=\"space-y-1\"><p><strong>Password Reset Process</strong></p><p>Users can reset their password through the account settings page. Click\n                      &quot;Forgot Password&quot; and follow the email verification steps to regain\n                      account access quickly and securely.\n                    </p></div><div class=\"space-y-1\"><p><strong>Service Pricing Tiers</strong></p><p>We offer three primary subscription levels designed to meet diverse user\n                      needs: Basic (free with limited features), Professional (monthly fee with\n                      comprehensive access), and Enterprise (custom pricing with full platform\n                      capabilities).\n                    </p></div><div class=\"space-y-1\"><p><strong>Technical Support Channels</strong></p><p>Customer support is accessible through multiple communication methods\n                      including email support, live chat during business hours, an integrated\n                      support ticket system, and phone support specifically for enterprise-level\n                      customers.\n                    </p></div><div class=\"space-y-1\"><p><strong>Data Protection Strategies</strong></p><p>Our platform implements rigorous security measures including 256-bit SSL\n                      encryption, regular comprehensive security audits, strict data access\n                      controls, and compliance with international privacy protection standards.\n                    </p></div><div class=\"space-y-1\"><p><strong>Platform Compatibility</strong></p><p>The service supports multiple device and operating system environments,\n                      including web browsers like Chrome and Firefox, mobile applications for iOS\n                      and Android, and desktop applications compatible with Windows and macOS.\n                    </p></div><div class=\"space-y-1\"><p><strong>Subscription Management</strong></p><p>Subscriptions can be cancelled at any time through account settings, with\n                      pro-rated refunds available within 30 days of payment. Both monthly and annual\n                      billing options are provided, with special discounts offered for annual\n                      commitments.\n                    </p></div><div class=\"space-y-1\"><p><strong>Payment Method Options</strong></p><p>We accept a wide range of payment methods including major credit cards such as\n                      Visa, MasterCard, and American Express, digital payment platforms like PayPal,\n                      and direct bank transfers. Regional payment options may also be available\n                      depending on user location.\n                    </p></div><div class=\"space-y-1\"><p><strong>Customer Support</strong></p><p>Our dedicated customer support team is available 24/7, providing quick and\n                      efficient assistance to address any inquiries or issues you may have.\n                    </p></div><div class=\"space-y-1\"><p><strong>Privacy Policy</strong></p><p>Our privacy policy outlines how we collect, use, and protect your personal\n                      data, ensuring your privacy is protected at all times.\n                    </p></div></div></div></DialogDescription></DialogHeader><DialogFooter class=\"px-6 pb-6 sm:justify-start\"><DialogClose aschild><Button type=\"button\" variant=\"outline\">Cancel\n              </Button></DialogClose><DialogClose aschild><Button type=\"button\">Okay</Button></DialogClose></DialogFooter></ScrollArea></DialogContent></Dialog>\n</template>"
        },
        {
          "path": "registry/default/components/dialog/dialog-04.wxml",
          "target": "components/ui/dialog-04/dialog-04.wxml",
          "type": "registry:component",
          "content": "<view>\n  <dialog><dialogtrigger aschild><button variant=\"outline\">Scrollable (custom scrollbar)</button></dialogtrigger><dialogcontent class=\"flex flex-col gap-0 p-0 sm:max-h-[min(640px,80vh)] sm:max-w-lg [&>button:last-child]:hidden\"><scrollarea class=\"flex max-h-full flex-col overflow-hidden\"><dialogheader class=\"contents space-y-0 text-left\"><dialogtitle class=\"px-6 pt-6\">Frequently Asked Questions (FAQ)</dialogtitle><dialogdescription aschild><view class=\"p-6\"><view class=\"[&_strong]:text-foreground space-y-4 [&_strong]:font-semibold\"><view class=\"space-y-1\"><text><strong>Account Management</strong></text><text>Navigate to the registration page, provide required information, and verify\n                      your email address. You can sign up using your email or through social media\n                      platforms.\n                    </text></view><view class=\"space-y-1\"><text><strong>Password Reset Process</strong></text><text>Users can reset their password through the account settings page. Click\n                      &quot;Forgot Password&quot; and follow the email verification steps to regain\n                      account access quickly and securely.\n                    </text></view><view class=\"space-y-1\"><text><strong>Service Pricing Tiers</strong></text><text>We offer three primary subscription levels designed to meet diverse user\n                      needs: Basic (free with limited features), Professional (monthly fee with\n                      comprehensive access), and Enterprise (custom pricing with full platform\n                      capabilities).\n                    </text></view><view class=\"space-y-1\"><text><strong>Technical Support Channels</strong></text><text>Customer support is accessible through multiple communication methods\n                      including email support, live chat during business hours, an integrated\n                      support ticket system, and phone support specifically for enterprise-level\n                      customers.\n                    </text></view><view class=\"space-y-1\"><text><strong>Data Protection Strategies</strong></text><text>Our platform implements rigorous security measures including 256-bit SSL\n                      encryption, regular comprehensive security audits, strict data access\n                      controls, and compliance with international privacy protection standards.\n                    </text></view><view class=\"space-y-1\"><text><strong>Platform Compatibility</strong></text><text>The service supports multiple device and operating system environments,\n                      including web browsers like Chrome and Firefox, mobile applications for iOS\n                      and Android, and desktop applications compatible with Windows and macOS.\n                    </text></view><view class=\"space-y-1\"><text><strong>Subscription Management</strong></text><text>Subscriptions can be cancelled at any time through account settings, with\n                      pro-rated refunds available within 30 days of payment. Both monthly and annual\n                      billing options are provided, with special discounts offered for annual\n                      commitments.\n                    </text></view><view class=\"space-y-1\"><text><strong>Payment Method Options</strong></text><text>We accept a wide range of payment methods including major credit cards such as\n                      Visa, MasterCard, and American Express, digital payment platforms like PayPal,\n                      and direct bank transfers. Regional payment options may also be available\n                      depending on user location.\n                    </text></view><view class=\"space-y-1\"><text><strong>Customer Support</strong></text><text>Our dedicated customer support team is available 24/7, providing quick and\n                      efficient assistance to address any inquiries or issues you may have.\n                    </text></view><view class=\"space-y-1\"><text><strong>Privacy Policy</strong></text><text>Our privacy policy outlines how we collect, use, and protect your personal\n                      data, ensuring your privacy is protected at all times.\n                    </text></view></view></view></dialogdescription></dialogheader><dialogfooter class=\"px-6 pb-6 sm:justify-start\"><dialogclose aschild><button type=\"button\" variant=\"outline\">Cancel\n              </button></dialogclose><dialogclose aschild><button type=\"button\">Okay</button></dialogclose></dialogfooter></scrollarea></dialogcontent></dialog>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dialog",
          "modal",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dialog-04",
          "group": "dialog",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dialog-04",
              "path": "registry/default/components/dialog/dialog-04.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dialog-04",
              "path": "registry/default/components/dialog/dialog-04.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dialog-04",
              "path": "registry/default/components/dialog/dialog-04.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dialog-04",
              "path": "registry/default/components/dialog/dialog-04.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dialog",
        "title": "Dialog · Dismissible"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "dialog"
      ]
    },
    {
      "name": "dialog-05",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dialog.json"
      ],
      "files": [
        {
          "path": "registry/default/components/dialog/dialog-05.tsx",
          "type": "registry:component",
          "target": "components/ui/dialog-05.tsx",
          "content": "import {\n  Button,\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n} from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Dialog>\n      <DialogTrigger asChild>\n        <Button variant=\"outline\">Scrollable (sticky header)</Button>\n      </DialogTrigger>\n      <DialogContent className=\"flex flex-col gap-0 p-0 sm:max-h-[min(640px,80vh)] sm:max-w-lg [&>button:last-child]:top-3.5\">\n        <DialogHeader className=\"contents space-y-0 text-left\">\n          <DialogTitle className=\"border-b px-6 py-4 text-base\">\n            Frequently Asked Questions (FAQ)\n          </DialogTitle>\n          <div className=\"overflow-y-auto\">\n            <DialogDescription asChild>\n              <div className=\"px-6 py-4\">\n                <div className=\"[&_strong]:text-foreground space-y-4 [&_strong]:font-semibold\">\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Account Management</strong>\n                    </p>\n                    <p>\n                      Navigate to the registration page, provide required information, and verify\n                      your email address. You can sign up using your email or through social media\n                      platforms.\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Password Reset Process</strong>\n                    </p>\n                    <p>\n                      Users can reset their password through the account settings page. Click\n                      &quot;Forgot Password&quot; and follow the email verification steps to regain\n                      account access quickly and securely.\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Service Pricing Tiers</strong>\n                    </p>\n                    <p>\n                      We offer three primary subscription levels designed to meet diverse user\n                      needs: Basic (free with limited features), Professional (monthly fee with\n                      comprehensive access), and Enterprise (custom pricing with full platform\n                      capabilities).\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Technical Support Channels</strong>\n                    </p>\n                    <p>\n                      Customer support is accessible through multiple communication methods\n                      including email support, live chat during business hours, an integrated\n                      support ticket system, and phone support specifically for enterprise-level\n                      customers.\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Data Protection Strategies</strong>\n                    </p>\n                    <p>\n                      Our platform implements rigorous security measures including 256-bit SSL\n                      encryption, regular comprehensive security audits, strict data access\n                      controls, and compliance with international privacy protection standards.\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Platform Compatibility</strong>\n                    </p>\n                    <p>\n                      The service supports multiple device and operating system environments,\n                      including web browsers like Chrome and Firefox, mobile applications for iOS\n                      and Android, and desktop applications compatible with Windows and macOS.\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Subscription Management</strong>\n                    </p>\n                    <p>\n                      Subscriptions can be cancelled at any time through account settings, with\n                      pro-rated refunds available within 30 days of payment. Both monthly and annual\n                      billing options are provided, with special discounts offered for annual\n                      commitments.\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Payment Method Options</strong>\n                    </p>\n                    <p>\n                      We accept a wide range of payment methods including major credit cards such as\n                      Visa, MasterCard, and American Express, digital payment platforms like PayPal,\n                      and direct bank transfers. Regional payment options may also be available\n                      depending on user location.\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Customer Support</strong>\n                    </p>\n                    <p>\n                      Our dedicated customer support team is available 24/7, providing quick and\n                      efficient assistance to address any inquiries or issues you may have.\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Privacy Policy</strong>\n                    </p>\n                    <p>\n                      Our privacy policy outlines how we collect, use, and protect your personal\n                      data, ensuring your privacy is protected at all times.\n                    </p>\n                  </div>\n                </div>\n              </div>\n            </DialogDescription>\n            <DialogFooter className=\"px-6 pb-6 sm:justify-start\">\n              <DialogClose asChild>\n                <Button type=\"button\">Okay</Button>\n              </DialogClose>\n            </DialogFooter>\n          </div>\n        </DialogHeader>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-05.vue",
          "target": "components/ui/dialog-05.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\nimport { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Dialog><DialogTrigger as-child><Button variant=\"outline\">Scrollable (sticky header)</Button></DialogTrigger><DialogContent class=\"flex flex-col gap-0 p-0 sm:max-h-[min(640px,80vh)] sm:max-w-lg [&>button:last-child]:top-3.5\"><DialogHeader class=\"contents space-y-0 text-left\"><DialogTitle class=\"border-b px-6 py-4 text-base\">Frequently Asked Questions (FAQ)\n          </DialogTitle><div class=\"overflow-y-auto\"><DialogDescription as-child><div class=\"px-6 py-4\"><div class=\"[&_strong]:text-foreground space-y-4 [&_strong]:font-semibold\"><div class=\"space-y-1\"><p><strong>Account Management</strong></p><p>Navigate to the registration page, provide required information, and verify\n                      your email address. You can sign up using your email or through social media\n                      platforms.\n                    </p></div><div class=\"space-y-1\"><p><strong>Password Reset Process</strong></p><p>Users can reset their password through the account settings page. Click\n                      &quot;Forgot Password&quot; and follow the email verification steps to regain\n                      account access quickly and securely.\n                    </p></div><div class=\"space-y-1\"><p><strong>Service Pricing Tiers</strong></p><p>We offer three primary subscription levels designed to meet diverse user\n                      needs: Basic (free with limited features), Professional (monthly fee with\n                      comprehensive access), and Enterprise (custom pricing with full platform\n                      capabilities).\n                    </p></div><div class=\"space-y-1\"><p><strong>Technical Support Channels</strong></p><p>Customer support is accessible through multiple communication methods\n                      including email support, live chat during business hours, an integrated\n                      support ticket system, and phone support specifically for enterprise-level\n                      customers.\n                    </p></div><div class=\"space-y-1\"><p><strong>Data Protection Strategies</strong></p><p>Our platform implements rigorous security measures including 256-bit SSL\n                      encryption, regular comprehensive security audits, strict data access\n                      controls, and compliance with international privacy protection standards.\n                    </p></div><div class=\"space-y-1\"><p><strong>Platform Compatibility</strong></p><p>The service supports multiple device and operating system environments,\n                      including web browsers like Chrome and Firefox, mobile applications for iOS\n                      and Android, and desktop applications compatible with Windows and macOS.\n                    </p></div><div class=\"space-y-1\"><p><strong>Subscription Management</strong></p><p>Subscriptions can be cancelled at any time through account settings, with\n                      pro-rated refunds available within 30 days of payment. Both monthly and annual\n                      billing options are provided, with special discounts offered for annual\n                      commitments.\n                    </p></div><div class=\"space-y-1\"><p><strong>Payment Method Options</strong></p><p>We accept a wide range of payment methods including major credit cards such as\n                      Visa, MasterCard, and American Express, digital payment platforms like PayPal,\n                      and direct bank transfers. Regional payment options may also be available\n                      depending on user location.\n                    </p></div><div class=\"space-y-1\"><p><strong>Customer Support</strong></p><p>Our dedicated customer support team is available 24/7, providing quick and\n                      efficient assistance to address any inquiries or issues you may have.\n                    </p></div><div class=\"space-y-1\"><p><strong>Privacy Policy</strong></p><p>Our privacy policy outlines how we collect, use, and protect your personal\n                      data, ensuring your privacy is protected at all times.\n                    </p></div></div></div></DialogDescription><DialogFooter class=\"px-6 pb-6 sm:justify-start\"><DialogClose as-child><Button type=\"button\">Okay</Button></DialogClose></DialogFooter></div></DialogHeader></DialogContent></Dialog>\n</template>\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-05.html",
          "target": "components/ui/dialog-05.html",
          "type": "registry:component",
          "content": "<template>\n  <Dialog><DialogTrigger aschild><Button variant=\"outline\">Scrollable (sticky header)</Button></DialogTrigger><DialogContent class=\"flex flex-col gap-0 p-0 sm:max-h-[min(640px,80vh)] sm:max-w-lg [&>button:last-child]:top-3.5\"><DialogHeader class=\"contents space-y-0 text-left\"><DialogTitle class=\"border-b px-6 py-4 text-base\">Frequently Asked Questions (FAQ)\n          </DialogTitle><div class=\"overflow-y-auto\"><DialogDescription aschild><div class=\"px-6 py-4\"><div class=\"[&_strong]:text-foreground space-y-4 [&_strong]:font-semibold\"><div class=\"space-y-1\"><p><strong>Account Management</strong></p><p>Navigate to the registration page, provide required information, and verify\n                      your email address. You can sign up using your email or through social media\n                      platforms.\n                    </p></div><div class=\"space-y-1\"><p><strong>Password Reset Process</strong></p><p>Users can reset their password through the account settings page. Click\n                      &quot;Forgot Password&quot; and follow the email verification steps to regain\n                      account access quickly and securely.\n                    </p></div><div class=\"space-y-1\"><p><strong>Service Pricing Tiers</strong></p><p>We offer three primary subscription levels designed to meet diverse user\n                      needs: Basic (free with limited features), Professional (monthly fee with\n                      comprehensive access), and Enterprise (custom pricing with full platform\n                      capabilities).\n                    </p></div><div class=\"space-y-1\"><p><strong>Technical Support Channels</strong></p><p>Customer support is accessible through multiple communication methods\n                      including email support, live chat during business hours, an integrated\n                      support ticket system, and phone support specifically for enterprise-level\n                      customers.\n                    </p></div><div class=\"space-y-1\"><p><strong>Data Protection Strategies</strong></p><p>Our platform implements rigorous security measures including 256-bit SSL\n                      encryption, regular comprehensive security audits, strict data access\n                      controls, and compliance with international privacy protection standards.\n                    </p></div><div class=\"space-y-1\"><p><strong>Platform Compatibility</strong></p><p>The service supports multiple device and operating system environments,\n                      including web browsers like Chrome and Firefox, mobile applications for iOS\n                      and Android, and desktop applications compatible with Windows and macOS.\n                    </p></div><div class=\"space-y-1\"><p><strong>Subscription Management</strong></p><p>Subscriptions can be cancelled at any time through account settings, with\n                      pro-rated refunds available within 30 days of payment. Both monthly and annual\n                      billing options are provided, with special discounts offered for annual\n                      commitments.\n                    </p></div><div class=\"space-y-1\"><p><strong>Payment Method Options</strong></p><p>We accept a wide range of payment methods including major credit cards such as\n                      Visa, MasterCard, and American Express, digital payment platforms like PayPal,\n                      and direct bank transfers. Regional payment options may also be available\n                      depending on user location.\n                    </p></div><div class=\"space-y-1\"><p><strong>Customer Support</strong></p><p>Our dedicated customer support team is available 24/7, providing quick and\n                      efficient assistance to address any inquiries or issues you may have.\n                    </p></div><div class=\"space-y-1\"><p><strong>Privacy Policy</strong></p><p>Our privacy policy outlines how we collect, use, and protect your personal\n                      data, ensuring your privacy is protected at all times.\n                    </p></div></div></div></DialogDescription><DialogFooter class=\"px-6 pb-6 sm:justify-start\"><DialogClose aschild><Button type=\"button\">Okay</Button></DialogClose></DialogFooter></div></DialogHeader></DialogContent></Dialog>\n</template>"
        },
        {
          "path": "registry/default/components/dialog/dialog-05.wxml",
          "target": "components/ui/dialog-05/dialog-05.wxml",
          "type": "registry:component",
          "content": "<view>\n  <dialog><dialogtrigger aschild><button variant=\"outline\">Scrollable (sticky header)</button></dialogtrigger><dialogcontent class=\"flex flex-col gap-0 p-0 sm:max-h-[min(640px,80vh)] sm:max-w-lg [&>button:last-child]:top-3.5\"><dialogheader class=\"contents space-y-0 text-left\"><dialogtitle class=\"border-b px-6 py-4 text-base\">Frequently Asked Questions (FAQ)\n          </dialogtitle><view class=\"overflow-y-auto\"><dialogdescription aschild><view class=\"px-6 py-4\"><view class=\"[&_strong]:text-foreground space-y-4 [&_strong]:font-semibold\"><view class=\"space-y-1\"><text><strong>Account Management</strong></text><text>Navigate to the registration page, provide required information, and verify\n                      your email address. You can sign up using your email or through social media\n                      platforms.\n                    </text></view><view class=\"space-y-1\"><text><strong>Password Reset Process</strong></text><text>Users can reset their password through the account settings page. Click\n                      &quot;Forgot Password&quot; and follow the email verification steps to regain\n                      account access quickly and securely.\n                    </text></view><view class=\"space-y-1\"><text><strong>Service Pricing Tiers</strong></text><text>We offer three primary subscription levels designed to meet diverse user\n                      needs: Basic (free with limited features), Professional (monthly fee with\n                      comprehensive access), and Enterprise (custom pricing with full platform\n                      capabilities).\n                    </text></view><view class=\"space-y-1\"><text><strong>Technical Support Channels</strong></text><text>Customer support is accessible through multiple communication methods\n                      including email support, live chat during business hours, an integrated\n                      support ticket system, and phone support specifically for enterprise-level\n                      customers.\n                    </text></view><view class=\"space-y-1\"><text><strong>Data Protection Strategies</strong></text><text>Our platform implements rigorous security measures including 256-bit SSL\n                      encryption, regular comprehensive security audits, strict data access\n                      controls, and compliance with international privacy protection standards.\n                    </text></view><view class=\"space-y-1\"><text><strong>Platform Compatibility</strong></text><text>The service supports multiple device and operating system environments,\n                      including web browsers like Chrome and Firefox, mobile applications for iOS\n                      and Android, and desktop applications compatible with Windows and macOS.\n                    </text></view><view class=\"space-y-1\"><text><strong>Subscription Management</strong></text><text>Subscriptions can be cancelled at any time through account settings, with\n                      pro-rated refunds available within 30 days of payment. Both monthly and annual\n                      billing options are provided, with special discounts offered for annual\n                      commitments.\n                    </text></view><view class=\"space-y-1\"><text><strong>Payment Method Options</strong></text><text>We accept a wide range of payment methods including major credit cards such as\n                      Visa, MasterCard, and American Express, digital payment platforms like PayPal,\n                      and direct bank transfers. Regional payment options may also be available\n                      depending on user location.\n                    </text></view><view class=\"space-y-1\"><text><strong>Customer Support</strong></text><text>Our dedicated customer support team is available 24/7, providing quick and\n                      efficient assistance to address any inquiries or issues you may have.\n                    </text></view><view class=\"space-y-1\"><text><strong>Privacy Policy</strong></text><text>Our privacy policy outlines how we collect, use, and protect your personal\n                      data, ensuring your privacy is protected at all times.\n                    </text></view></view></view></dialogdescription><dialogfooter class=\"px-6 pb-6 sm:justify-start\"><dialogclose aschild><button type=\"button\">Okay</button></dialogclose></dialogfooter></view></dialogheader></dialogcontent></dialog>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dialog",
          "modal",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dialog-05",
          "group": "dialog",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dialog-05",
              "path": "registry/default/components/dialog/dialog-05.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dialog-05",
              "path": "registry/default/components/dialog/dialog-05.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dialog-05",
              "path": "registry/default/components/dialog/dialog-05.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dialog-05",
              "path": "registry/default/components/dialog/dialog-05.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dialog",
        "title": "Dialog · Dismissible"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "dialog"
      ]
    },
    {
      "name": "dialog-06",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dialog.json"
      ],
      "files": [
        {
          "path": "registry/default/components/dialog/dialog-06.tsx",
          "type": "registry:component",
          "target": "components/ui/dialog-06.tsx",
          "content": "import {\n  Button,\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n} from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Dialog>\n      <DialogTrigger asChild>\n        <Button variant=\"outline\">Scrollable (sticky footer)</Button>\n      </DialogTrigger>\n      <DialogContent className=\"flex flex-col gap-0 p-0 sm:max-h-[min(640px,80vh)] sm:max-w-lg [&>button:last-child]:hidden\">\n        <div className=\"overflow-y-auto\">\n          <DialogHeader className=\"contents space-y-0 text-left\">\n            <DialogTitle className=\"px-6 pt-6 text-base\">\n              Frequently Asked Questions (FAQ)\n            </DialogTitle>\n            <DialogDescription asChild>\n              <div className=\"p-6\">\n                <div className=\"[&_strong]:text-foreground space-y-4 [&_strong]:font-semibold\">\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Account Management</strong>\n                    </p>\n                    <p>\n                      Navigate to the registration page, provide required information, and verify\n                      your email address. You can sign up using your email or through social media\n                      platforms.\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Password Reset Process</strong>\n                    </p>\n                    <p>\n                      Users can reset their password through the account settings page. Click\n                      &quot;Forgot Password&quot; and follow the email verification steps to regain\n                      account access quickly and securely.\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Service Pricing Tiers</strong>\n                    </p>\n                    <p>\n                      We offer three primary subscription levels designed to meet diverse user\n                      needs: Basic (free with limited features), Professional (monthly fee with\n                      comprehensive access), and Enterprise (custom pricing with full platform\n                      capabilities).\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Technical Support Channels</strong>\n                    </p>\n                    <p>\n                      Customer support is accessible through multiple communication methods\n                      including email support, live chat during business hours, an integrated\n                      support ticket system, and phone support specifically for enterprise-level\n                      customers.\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Data Protection Strategies</strong>\n                    </p>\n                    <p>\n                      Our platform implements rigorous security measures including 256-bit SSL\n                      encryption, regular comprehensive security audits, strict data access\n                      controls, and compliance with international privacy protection standards.\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Platform Compatibility</strong>\n                    </p>\n                    <p>\n                      The service supports multiple device and operating system environments,\n                      including web browsers like Chrome and Firefox, mobile applications for iOS\n                      and Android, and desktop applications compatible with Windows and macOS.\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Subscription Management</strong>\n                    </p>\n                    <p>\n                      Subscriptions can be cancelled at any time through account settings, with\n                      pro-rated refunds available within 30 days of payment. Both monthly and annual\n                      billing options are provided, with special discounts offered for annual\n                      commitments.\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Payment Method Options</strong>\n                    </p>\n                    <p>\n                      We accept a wide range of payment methods including major credit cards such as\n                      Visa, MasterCard, and American Express, digital payment platforms like PayPal,\n                      and direct bank transfers. Regional payment options may also be available\n                      depending on user location.\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Customer Support</strong>\n                    </p>\n                    <p>\n                      Our dedicated customer support team is available 24/7, providing quick and\n                      efficient assistance to address any inquiries or issues you may have.\n                    </p>\n                  </div>\n                  <div className=\"space-y-1\">\n                    <p>\n                      <strong>Privacy Policy</strong>\n                    </p>\n                    <p>\n                      Our privacy policy outlines how we collect, use, and protect your personal\n                      data, ensuring your privacy is protected at all times.\n                    </p>\n                  </div>\n                </div>\n              </div>\n            </DialogDescription>\n          </DialogHeader>\n        </div>\n        <DialogFooter className=\"border-t px-6 py-4\">\n          <DialogClose asChild>\n            <Button type=\"button\" variant=\"outline\">\n              Cancel\n            </Button>\n          </DialogClose>\n          <DialogClose asChild>\n            <Button type=\"button\">Okay</Button>\n          </DialogClose>\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-06.vue",
          "target": "components/ui/dialog-06.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\nimport { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Dialog><DialogTrigger as-child><Button variant=\"outline\">Scrollable (sticky footer)</Button></DialogTrigger><DialogContent class=\"flex flex-col gap-0 p-0 sm:max-h-[min(640px,80vh)] sm:max-w-lg [&>button:last-child]:hidden\"><div class=\"overflow-y-auto\"><DialogHeader class=\"contents space-y-0 text-left\"><DialogTitle class=\"px-6 pt-6 text-base\">Frequently Asked Questions (FAQ)\n            </DialogTitle><DialogDescription as-child><div class=\"p-6\"><div class=\"[&_strong]:text-foreground space-y-4 [&_strong]:font-semibold\"><div class=\"space-y-1\"><p><strong>Account Management</strong></p><p>Navigate to the registration page, provide required information, and verify\n                      your email address. You can sign up using your email or through social media\n                      platforms.\n                    </p></div><div class=\"space-y-1\"><p><strong>Password Reset Process</strong></p><p>Users can reset their password through the account settings page. Click\n                      &quot;Forgot Password&quot; and follow the email verification steps to regain\n                      account access quickly and securely.\n                    </p></div><div class=\"space-y-1\"><p><strong>Service Pricing Tiers</strong></p><p>We offer three primary subscription levels designed to meet diverse user\n                      needs: Basic (free with limited features), Professional (monthly fee with\n                      comprehensive access), and Enterprise (custom pricing with full platform\n                      capabilities).\n                    </p></div><div class=\"space-y-1\"><p><strong>Technical Support Channels</strong></p><p>Customer support is accessible through multiple communication methods\n                      including email support, live chat during business hours, an integrated\n                      support ticket system, and phone support specifically for enterprise-level\n                      customers.\n                    </p></div><div class=\"space-y-1\"><p><strong>Data Protection Strategies</strong></p><p>Our platform implements rigorous security measures including 256-bit SSL\n                      encryption, regular comprehensive security audits, strict data access\n                      controls, and compliance with international privacy protection standards.\n                    </p></div><div class=\"space-y-1\"><p><strong>Platform Compatibility</strong></p><p>The service supports multiple device and operating system environments,\n                      including web browsers like Chrome and Firefox, mobile applications for iOS\n                      and Android, and desktop applications compatible with Windows and macOS.\n                    </p></div><div class=\"space-y-1\"><p><strong>Subscription Management</strong></p><p>Subscriptions can be cancelled at any time through account settings, with\n                      pro-rated refunds available within 30 days of payment. Both monthly and annual\n                      billing options are provided, with special discounts offered for annual\n                      commitments.\n                    </p></div><div class=\"space-y-1\"><p><strong>Payment Method Options</strong></p><p>We accept a wide range of payment methods including major credit cards such as\n                      Visa, MasterCard, and American Express, digital payment platforms like PayPal,\n                      and direct bank transfers. Regional payment options may also be available\n                      depending on user location.\n                    </p></div><div class=\"space-y-1\"><p><strong>Customer Support</strong></p><p>Our dedicated customer support team is available 24/7, providing quick and\n                      efficient assistance to address any inquiries or issues you may have.\n                    </p></div><div class=\"space-y-1\"><p><strong>Privacy Policy</strong></p><p>Our privacy policy outlines how we collect, use, and protect your personal\n                      data, ensuring your privacy is protected at all times.\n                    </p></div></div></div></DialogDescription></DialogHeader></div><DialogFooter class=\"border-t px-6 py-4\"><DialogClose as-child><Button type=\"button\" variant=\"outline\">Cancel\n            </Button></DialogClose><DialogClose as-child><Button type=\"button\">Okay</Button></DialogClose></DialogFooter></DialogContent></Dialog>\n</template>\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-06.html",
          "target": "components/ui/dialog-06.html",
          "type": "registry:component",
          "content": "<template>\n  <Dialog><DialogTrigger aschild><Button variant=\"outline\">Scrollable (sticky footer)</Button></DialogTrigger><DialogContent class=\"flex flex-col gap-0 p-0 sm:max-h-[min(640px,80vh)] sm:max-w-lg [&>button:last-child]:hidden\"><div class=\"overflow-y-auto\"><DialogHeader class=\"contents space-y-0 text-left\"><DialogTitle class=\"px-6 pt-6 text-base\">Frequently Asked Questions (FAQ)\n            </DialogTitle><DialogDescription aschild><div class=\"p-6\"><div class=\"[&_strong]:text-foreground space-y-4 [&_strong]:font-semibold\"><div class=\"space-y-1\"><p><strong>Account Management</strong></p><p>Navigate to the registration page, provide required information, and verify\n                      your email address. You can sign up using your email or through social media\n                      platforms.\n                    </p></div><div class=\"space-y-1\"><p><strong>Password Reset Process</strong></p><p>Users can reset their password through the account settings page. Click\n                      &quot;Forgot Password&quot; and follow the email verification steps to regain\n                      account access quickly and securely.\n                    </p></div><div class=\"space-y-1\"><p><strong>Service Pricing Tiers</strong></p><p>We offer three primary subscription levels designed to meet diverse user\n                      needs: Basic (free with limited features), Professional (monthly fee with\n                      comprehensive access), and Enterprise (custom pricing with full platform\n                      capabilities).\n                    </p></div><div class=\"space-y-1\"><p><strong>Technical Support Channels</strong></p><p>Customer support is accessible through multiple communication methods\n                      including email support, live chat during business hours, an integrated\n                      support ticket system, and phone support specifically for enterprise-level\n                      customers.\n                    </p></div><div class=\"space-y-1\"><p><strong>Data Protection Strategies</strong></p><p>Our platform implements rigorous security measures including 256-bit SSL\n                      encryption, regular comprehensive security audits, strict data access\n                      controls, and compliance with international privacy protection standards.\n                    </p></div><div class=\"space-y-1\"><p><strong>Platform Compatibility</strong></p><p>The service supports multiple device and operating system environments,\n                      including web browsers like Chrome and Firefox, mobile applications for iOS\n                      and Android, and desktop applications compatible with Windows and macOS.\n                    </p></div><div class=\"space-y-1\"><p><strong>Subscription Management</strong></p><p>Subscriptions can be cancelled at any time through account settings, with\n                      pro-rated refunds available within 30 days of payment. Both monthly and annual\n                      billing options are provided, with special discounts offered for annual\n                      commitments.\n                    </p></div><div class=\"space-y-1\"><p><strong>Payment Method Options</strong></p><p>We accept a wide range of payment methods including major credit cards such as\n                      Visa, MasterCard, and American Express, digital payment platforms like PayPal,\n                      and direct bank transfers. Regional payment options may also be available\n                      depending on user location.\n                    </p></div><div class=\"space-y-1\"><p><strong>Customer Support</strong></p><p>Our dedicated customer support team is available 24/7, providing quick and\n                      efficient assistance to address any inquiries or issues you may have.\n                    </p></div><div class=\"space-y-1\"><p><strong>Privacy Policy</strong></p><p>Our privacy policy outlines how we collect, use, and protect your personal\n                      data, ensuring your privacy is protected at all times.\n                    </p></div></div></div></DialogDescription></DialogHeader></div><DialogFooter class=\"border-t px-6 py-4\"><DialogClose aschild><Button type=\"button\" variant=\"outline\">Cancel\n            </Button></DialogClose><DialogClose aschild><Button type=\"button\">Okay</Button></DialogClose></DialogFooter></DialogContent></Dialog>\n</template>"
        },
        {
          "path": "registry/default/components/dialog/dialog-06.wxml",
          "target": "components/ui/dialog-06/dialog-06.wxml",
          "type": "registry:component",
          "content": "<view>\n  <dialog><dialogtrigger aschild><button variant=\"outline\">Scrollable (sticky footer)</button></dialogtrigger><dialogcontent class=\"flex flex-col gap-0 p-0 sm:max-h-[min(640px,80vh)] sm:max-w-lg [&>button:last-child]:hidden\"><view class=\"overflow-y-auto\"><dialogheader class=\"contents space-y-0 text-left\"><dialogtitle class=\"px-6 pt-6 text-base\">Frequently Asked Questions (FAQ)\n            </dialogtitle><dialogdescription aschild><view class=\"p-6\"><view class=\"[&_strong]:text-foreground space-y-4 [&_strong]:font-semibold\"><view class=\"space-y-1\"><text><strong>Account Management</strong></text><text>Navigate to the registration page, provide required information, and verify\n                      your email address. You can sign up using your email or through social media\n                      platforms.\n                    </text></view><view class=\"space-y-1\"><text><strong>Password Reset Process</strong></text><text>Users can reset their password through the account settings page. Click\n                      &quot;Forgot Password&quot; and follow the email verification steps to regain\n                      account access quickly and securely.\n                    </text></view><view class=\"space-y-1\"><text><strong>Service Pricing Tiers</strong></text><text>We offer three primary subscription levels designed to meet diverse user\n                      needs: Basic (free with limited features), Professional (monthly fee with\n                      comprehensive access), and Enterprise (custom pricing with full platform\n                      capabilities).\n                    </text></view><view class=\"space-y-1\"><text><strong>Technical Support Channels</strong></text><text>Customer support is accessible through multiple communication methods\n                      including email support, live chat during business hours, an integrated\n                      support ticket system, and phone support specifically for enterprise-level\n                      customers.\n                    </text></view><view class=\"space-y-1\"><text><strong>Data Protection Strategies</strong></text><text>Our platform implements rigorous security measures including 256-bit SSL\n                      encryption, regular comprehensive security audits, strict data access\n                      controls, and compliance with international privacy protection standards.\n                    </text></view><view class=\"space-y-1\"><text><strong>Platform Compatibility</strong></text><text>The service supports multiple device and operating system environments,\n                      including web browsers like Chrome and Firefox, mobile applications for iOS\n                      and Android, and desktop applications compatible with Windows and macOS.\n                    </text></view><view class=\"space-y-1\"><text><strong>Subscription Management</strong></text><text>Subscriptions can be cancelled at any time through account settings, with\n                      pro-rated refunds available within 30 days of payment. Both monthly and annual\n                      billing options are provided, with special discounts offered for annual\n                      commitments.\n                    </text></view><view class=\"space-y-1\"><text><strong>Payment Method Options</strong></text><text>We accept a wide range of payment methods including major credit cards such as\n                      Visa, MasterCard, and American Express, digital payment platforms like PayPal,\n                      and direct bank transfers. Regional payment options may also be available\n                      depending on user location.\n                    </text></view><view class=\"space-y-1\"><text><strong>Customer Support</strong></text><text>Our dedicated customer support team is available 24/7, providing quick and\n                      efficient assistance to address any inquiries or issues you may have.\n                    </text></view><view class=\"space-y-1\"><text><strong>Privacy Policy</strong></text><text>Our privacy policy outlines how we collect, use, and protect your personal\n                      data, ensuring your privacy is protected at all times.\n                    </text></view></view></view></dialogdescription></dialogheader></view><dialogfooter class=\"border-t px-6 py-4\"><dialogclose aschild><button type=\"button\" variant=\"outline\">Cancel\n            </button></dialogclose><dialogclose aschild><button type=\"button\">Okay</button></dialogclose></dialogfooter></dialogcontent></dialog>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dialog",
          "modal",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dialog-06",
          "group": "dialog",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dialog-06",
              "path": "registry/default/components/dialog/dialog-06.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dialog-06",
              "path": "registry/default/components/dialog/dialog-06.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dialog-06",
              "path": "registry/default/components/dialog/dialog-06.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dialog-06",
              "path": "registry/default/components/dialog/dialog-06.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dialog",
        "title": "Dialog · Dismissible"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "dialog"
      ]
    },
    {
      "name": "dialog-07",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dialog.json"
      ],
      "files": [
        {
          "path": "registry/default/components/dialog/dialog-07.tsx",
          "type": "registry:component",
          "target": "components/ui/dialog-07.tsx",
          "content": "'use client'\n\nimport { useRef, useState } from 'react'\nimport {\n  Button,\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n} from '@timui/react'\n\nexport default function Component() {\n  const [hasReadToBottom, setHasReadToBottom] = useState(false)\n  const contentRef = useRef<HTMLDivElement>(null)\n\n  const handleScroll = () => {\n    const content = contentRef.current\n    if (!content) return\n\n    const scrollPercentage = content.scrollTop / (content.scrollHeight - content.clientHeight)\n    if (scrollPercentage >= 0.99 && !hasReadToBottom) {\n      setHasReadToBottom(true)\n    }\n  }\n\n  return (\n    <Dialog>\n      <DialogTrigger asChild>\n        <Button variant=\"outline\">Terms & Conditions</Button>\n      </DialogTrigger>\n      <DialogContent className=\"flex flex-col gap-0 p-0 sm:max-h-[min(640px,80vh)] sm:max-w-lg [&>button:last-child]:top-3.5\">\n        <DialogHeader className=\"contents space-y-0 text-left\">\n          <DialogTitle className=\"border-b px-6 py-4 text-base\">Terms & Conditions</DialogTitle>\n          <div ref={contentRef} onScroll={handleScroll} className=\"overflow-y-auto\">\n            <DialogDescription asChild>\n              <div className=\"px-6 py-4\">\n                <div className=\"[&_strong]:text-foreground space-y-4 [&_strong]:font-semibold\">\n                  <div className=\"space-y-4\">\n                    <div className=\"space-y-1\">\n                      <p>\n                        <strong>Acceptance of Terms</strong>\n                      </p>\n                      <p>\n                        By accessing and using this website, users agree to comply with and be bound\n                        by these Terms of Service. Users who do not agree with these terms should\n                        discontinue use of the website immediately.\n                      </p>\n                    </div>\n\n                    <div className=\"space-y-1\">\n                      <p>\n                        <strong>User Account Responsibilities</strong>\n                      </p>\n                      <p>\n                        Users are responsible for maintaining the confidentiality of their account\n                        credentials. Any activities occurring under a user&lsquo;s account are the\n                        sole responsibility of the account holder. Users must notify the website\n                        administrators immediately of any unauthorized account access.\n                      </p>\n                    </div>\n\n                    <div className=\"space-y-1\">\n                      <p>\n                        <strong>Content Usage and Restrictions</strong>\n                      </p>\n                      <p>\n                        The website and its original content are protected by intellectual property\n                        laws. Users may not reproduce, distribute, modify, create derivative works,\n                        or commercially exploit any content without explicit written permission from\n                        the website owners.\n                      </p>\n                    </div>\n\n                    <div className=\"space-y-1\">\n                      <p>\n                        <strong>Limitation of Liability</strong>\n                      </p>\n                      <p>\n                        The website provides content &ldquo;as is&ldquo; without any warranties. The\n                        website owners shall not be liable for direct, indirect, incidental,\n                        consequential, or punitive damages arising from user interactions with the\n                        platform.\n                      </p>\n                    </div>\n\n                    <div className=\"space-y-1\">\n                      <p>\n                        <strong>User Conduct Guidelines</strong>\n                      </p>\n                      <ul className=\"list-disc pl-6\">\n                        <li>Not upload harmful or malicious content</li>\n                        <li>Respect the rights of other users</li>\n                        <li>Avoid activities that could disrupt website functionality</li>\n                        <li>Comply with applicable local and international laws</li>\n                      </ul>\n                    </div>\n\n                    <div className=\"space-y-1\">\n                      <p>\n                        <strong>Modifications to Terms</strong>\n                      </p>\n                      <p>\n                        The website reserves the right to modify these terms at any time. Continued\n                        use of the website after changes constitutes acceptance of the new terms.\n                      </p>\n                    </div>\n\n                    <div className=\"space-y-1\">\n                      <p>\n                        <strong>Termination Clause</strong>\n                      </p>\n                      <p>\n                        The website may terminate or suspend user access without prior notice for\n                        violations of these terms or for any other reason deemed appropriate by the\n                        administration.\n                      </p>\n                    </div>\n\n                    <div className=\"space-y-1\">\n                      <p>\n                        <strong>Governing Law</strong>\n                      </p>\n                      <p>\n                        These terms are governed by the laws of the jurisdiction where the website\n                        is primarily operated, without regard to conflict of law principles.\n                      </p>\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </DialogDescription>\n          </div>\n        </DialogHeader>\n        <DialogFooter className=\"border-t px-6 py-4 sm:items-center\">\n          {!hasReadToBottom && (\n            <span className=\"text-muted-foreground grow text-xs max-sm:text-center\">\n              Read all terms before accepting.\n            </span>\n          )}\n          <DialogClose asChild>\n            <Button type=\"button\" variant=\"outline\">\n              Cancel\n            </Button>\n          </DialogClose>\n          <DialogClose asChild>\n            <Button type=\"button\" disabled={!hasReadToBottom}>\n              I agree\n            </Button>\n          </DialogClose>\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-07.vue",
          "target": "components/ui/dialog-07.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Button } from '@timui/vue';\nimport { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from '@timui/vue';\n\n\n\nconst hasReadToBottom = ref(false);\nconst contentRef = ref<HTMLDivElement | null>(null);\n\nfunction handleScroll() {\n  const content = contentRef.value;\n  if (!content) return;\n\n  const scrollPercentage = content.scrollTop / (content.scrollHeight - content.clientHeight);\n  if (scrollPercentage >= 0.99 && !hasReadToBottom.value) {\n    hasReadToBottom.value = true;\n  }\n}\n\n</script>\n\n<template>\n  <Dialog><DialogTrigger as-child><Button variant=\"outline\">Terms & Conditions</Button></DialogTrigger><DialogContent class=\"flex flex-col gap-0 p-0 sm:max-h-[min(640px,80vh)] sm:max-w-lg [&>button:last-child]:top-3.5\"><DialogHeader class=\"contents space-y-0 text-left\"><DialogTitle class=\"border-b px-6 py-4 text-base\">Terms & Conditions</DialogTitle><div :ref=\"contentRef\" @scroll=\"handleScroll\" class=\"overflow-y-auto\"><DialogDescription as-child><div class=\"px-6 py-4\"><div class=\"[&_strong]:text-foreground space-y-4 [&_strong]:font-semibold\"><div class=\"space-y-4\"><div class=\"space-y-1\"><p><strong>Acceptance of Terms</strong></p><p>By accessing and using this website, users agree to comply with and be bound\n                        by these Terms of Service. Users who do not agree with these terms should\n                        discontinue use of the website immediately.\n                      </p></div><div class=\"space-y-1\"><p><strong>User Account Responsibilities</strong></p><p>Users are responsible for maintaining the confidentiality of their account\n                        credentials. Any activities occurring under a user&lsquo;s account are the\n                        sole responsibility of the account holder. Users must notify the website\n                        administrators immediately of any unauthorized account access.\n                      </p></div><div class=\"space-y-1\"><p><strong>Content Usage and Restrictions</strong></p><p>The website and its original content are protected by intellectual property\n                        laws. Users may not reproduce, distribute, modify, create derivative works,\n                        or commercially exploit any content without explicit written permission from\n                        the website owners.\n                      </p></div><div class=\"space-y-1\"><p><strong>Limitation of Liability</strong></p><p>The website provides content &ldquo;as is&ldquo; without any warranties. The\n                        website owners shall not be liable for direct, indirect, incidental,\n                        consequential, or punitive damages arising from user interactions with the\n                        platform.\n                      </p></div><div class=\"space-y-1\"><p><strong>User Conduct Guidelines</strong></p><ul class=\"list-disc pl-6\"><li>Not upload harmful or malicious content</li><li>Respect the rights of other users</li><li>Avoid activities that could disrupt website functionality</li><li>Comply with applicable local and international laws</li></ul></div><div class=\"space-y-1\"><p><strong>Modifications to Terms</strong></p><p>The website reserves the right to modify these terms at any time. Continued\n                        use of the website after changes constitutes acceptance of the new terms.\n                      </p></div><div class=\"space-y-1\"><p><strong>Termination Clause</strong></p><p>The website may terminate or suspend user access without prior notice for\n                        violations of these terms or for any other reason deemed appropriate by the\n                        administration.\n                      </p></div><div class=\"space-y-1\"><p><strong>Governing Law</strong></p><p>These terms are governed by the laws of the jurisdiction where the website\n                        is primarily operated, without regard to conflict of law principles.\n                      </p></div></div></div></div></DialogDescription></div></DialogHeader><DialogFooter class=\"border-t px-6 py-4 sm:items-center\"><span v-if=\"!hasReadToBottom\" class=\"text-muted-foreground grow text-xs max-sm:text-center\">Read all terms before accepting.\n            </span><DialogClose as-child><Button type=\"button\" variant=\"outline\">Cancel\n            </Button></DialogClose><DialogClose as-child><Button type=\"button\" :disabled=\"!hasReadToBottom\">I agree\n            </Button></DialogClose></DialogFooter></DialogContent></Dialog>\n</template>\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-07.html",
          "target": "components/ui/dialog-07.html",
          "type": "registry:component",
          "content": "<template>\n  <Dialog><DialogTrigger aschild><Button variant=\"outline\">Terms & Conditions</Button></DialogTrigger><DialogContent class=\"flex flex-col gap-0 p-0 sm:max-h-[min(640px,80vh)] sm:max-w-lg [&>button:last-child]:top-3.5\"><DialogHeader class=\"contents space-y-0 text-left\"><DialogTitle class=\"border-b px-6 py-4 text-base\">Terms & Conditions</DialogTitle><div ref=\"${contentRef}\" onscroll=\"${handleScroll}\" class=\"overflow-y-auto\"><DialogDescription aschild><div class=\"px-6 py-4\"><div class=\"[&_strong]:text-foreground space-y-4 [&_strong]:font-semibold\"><div class=\"space-y-4\"><div class=\"space-y-1\"><p><strong>Acceptance of Terms</strong></p><p>By accessing and using this website, users agree to comply with and be bound\n                        by these Terms of Service. Users who do not agree with these terms should\n                        discontinue use of the website immediately.\n                      </p></div><div class=\"space-y-1\"><p><strong>User Account Responsibilities</strong></p><p>Users are responsible for maintaining the confidentiality of their account\n                        credentials. Any activities occurring under a user&lsquo;s account are the\n                        sole responsibility of the account holder. Users must notify the website\n                        administrators immediately of any unauthorized account access.\n                      </p></div><div class=\"space-y-1\"><p><strong>Content Usage and Restrictions</strong></p><p>The website and its original content are protected by intellectual property\n                        laws. Users may not reproduce, distribute, modify, create derivative works,\n                        or commercially exploit any content without explicit written permission from\n                        the website owners.\n                      </p></div><div class=\"space-y-1\"><p><strong>Limitation of Liability</strong></p><p>The website provides content &ldquo;as is&ldquo; without any warranties. The\n                        website owners shall not be liable for direct, indirect, incidental,\n                        consequential, or punitive damages arising from user interactions with the\n                        platform.\n                      </p></div><div class=\"space-y-1\"><p><strong>User Conduct Guidelines</strong></p><ul class=\"list-disc pl-6\"><li>Not upload harmful or malicious content</li><li>Respect the rights of other users</li><li>Avoid activities that could disrupt website functionality</li><li>Comply with applicable local and international laws</li></ul></div><div class=\"space-y-1\"><p><strong>Modifications to Terms</strong></p><p>The website reserves the right to modify these terms at any time. Continued\n                        use of the website after changes constitutes acceptance of the new terms.\n                      </p></div><div class=\"space-y-1\"><p><strong>Termination Clause</strong></p><p>The website may terminate or suspend user access without prior notice for\n                        violations of these terms or for any other reason deemed appropriate by the\n                        administration.\n                      </p></div><div class=\"space-y-1\"><p><strong>Governing Law</strong></p><p>These terms are governed by the laws of the jurisdiction where the website\n                        is primarily operated, without regard to conflict of law principles.\n                      </p></div></div></div></div></DialogDescription></div></DialogHeader><DialogFooter class=\"border-t px-6 py-4 sm:items-center\"><!-- if !hasReadToBottom -->\n<span class=\"text-muted-foreground grow text-xs max-sm:text-center\">Read all terms before accepting.\n            </span>\n<!-- endif --><DialogClose aschild><Button type=\"button\" variant=\"outline\">Cancel\n            </Button></DialogClose><DialogClose aschild><Button type=\"button\" disabled=\"${!hasReadToBottom}\">I agree\n            </Button></DialogClose></DialogFooter></DialogContent></Dialog>\n</template>"
        },
        {
          "path": "registry/default/components/dialog/dialog-07.wxml",
          "target": "components/ui/dialog-07/dialog-07.wxml",
          "type": "registry:component",
          "content": "<view>\n  <dialog><dialogtrigger aschild><button variant=\"outline\">Terms & Conditions</button></dialogtrigger><dialogcontent class=\"flex flex-col gap-0 p-0 sm:max-h-[min(640px,80vh)] sm:max-w-lg [&>button:last-child]:top-3.5\"><dialogheader class=\"contents space-y-0 text-left\"><dialogtitle class=\"border-b px-6 py-4 text-base\">Terms & Conditions</dialogtitle><view ref=\"{{contentRef}}\" onscroll=\"{{handleScroll}}\" class=\"overflow-y-auto\"><dialogdescription aschild><view class=\"px-6 py-4\"><view class=\"[&_strong]:text-foreground space-y-4 [&_strong]:font-semibold\"><view class=\"space-y-4\"><view class=\"space-y-1\"><text><strong>Acceptance of Terms</strong></text><text>By accessing and using this website, users agree to comply with and be bound\n                        by these Terms of Service. Users who do not agree with these terms should\n                        discontinue use of the website immediately.\n                      </text></view><view class=\"space-y-1\"><text><strong>User Account Responsibilities</strong></text><text>Users are responsible for maintaining the confidentiality of their account\n                        credentials. Any activities occurring under a user&lsquo;s account are the\n                        sole responsibility of the account holder. Users must notify the website\n                        administrators immediately of any unauthorized account access.\n                      </text></view><view class=\"space-y-1\"><text><strong>Content Usage and Restrictions</strong></text><text>The website and its original content are protected by intellectual property\n                        laws. Users may not reproduce, distribute, modify, create derivative works,\n                        or commercially exploit any content without explicit written permission from\n                        the website owners.\n                      </text></view><view class=\"space-y-1\"><text><strong>Limitation of Liability</strong></text><text>The website provides content &ldquo;as is&ldquo; without any warranties. The\n                        website owners shall not be liable for direct, indirect, incidental,\n                        consequential, or punitive damages arising from user interactions with the\n                        platform.\n                      </text></view><view class=\"space-y-1\"><text><strong>User Conduct Guidelines</strong></text><ul class=\"list-disc pl-6\"><li>Not upload harmful or malicious content</li><li>Respect the rights of other users</li><li>Avoid activities that could disrupt website functionality</li><li>Comply with applicable local and international laws</li></ul></view><view class=\"space-y-1\"><text><strong>Modifications to Terms</strong></text><text>The website reserves the right to modify these terms at any time. Continued\n                        use of the website after changes constitutes acceptance of the new terms.\n                      </text></view><view class=\"space-y-1\"><text><strong>Termination Clause</strong></text><text>The website may terminate or suspend user access without prior notice for\n                        violations of these terms or for any other reason deemed appropriate by the\n                        administration.\n                      </text></view><view class=\"space-y-1\"><text><strong>Governing Law</strong></text><text>These terms are governed by the laws of the jurisdiction where the website\n                        is primarily operated, without regard to conflict of law principles.\n                      </text></view></view></view></view></dialogdescription></view></dialogheader><dialogfooter class=\"border-t px-6 py-4 sm:items-center\"><text wx:if=\"{{!hasReadToBottom}}\" class=\"text-muted-foreground grow text-xs max-sm:text-center\">Read all terms before accepting.\n            </text><dialogclose aschild><button type=\"button\" variant=\"outline\">Cancel\n            </button></dialogclose><dialogclose aschild><button type=\"button\" disabled=\"{{!hasReadToBottom}}\">I agree\n            </button></dialogclose></dialogfooter></dialogcontent></dialog>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dialog",
          "modal",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dialog-07",
          "group": "dialog",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dialog-07",
              "path": "registry/default/components/dialog/dialog-07.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dialog-07",
              "path": "registry/default/components/dialog/dialog-07.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dialog-07",
              "path": "registry/default/components/dialog/dialog-07.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dialog-07",
              "path": "registry/default/components/dialog/dialog-07.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dialog",
        "title": "Dialog · Dismissible"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "dialog"
      ]
    },
    {
      "name": "dialog-08",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dialog.json",
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/dialog/dialog-08.tsx",
          "type": "registry:component",
          "target": "components/ui/dialog-08.tsx",
          "content": "'use client'\n\nimport { useId, useState } from 'react'\nimport {\n  Button,\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n  Input,\n  Label,\n} from '@timui/react'\nimport { CircleAlertIcon } from 'lucide-react'\n\nconst PROJECT_NAME = 'Timkit UI'\n\nexport default function Component() {\n  const id = useId()\n  const [inputValue, setInputValue] = useState('')\n\n  return (\n    <Dialog>\n      <DialogTrigger asChild>\n        <Button variant=\"outline\">Delete project</Button>\n      </DialogTrigger>\n      <DialogContent>\n        <div className=\"flex flex-col items-center gap-2\">\n          <div\n            className=\"flex size-9 shrink-0 items-center justify-center rounded-full border\"\n            aria-hidden=\"true\"\n          >\n            <CircleAlertIcon className=\"opacity-80\" size={16} />\n          </div>\n          <DialogHeader>\n            <DialogTitle className=\"sm:text-center\">Final confirmation</DialogTitle>\n            <DialogDescription className=\"sm:text-center\">\n              This action cannot be undone. To confirm, please enter the project name{' '}\n              <span className=\"text-foreground\">Timkit UI</span>.\n            </DialogDescription>\n          </DialogHeader>\n        </div>\n\n        <form className=\"space-y-5\">\n          <div className=\"*:not-first:mt-2\">\n            <Label htmlFor={id}>Project name</Label>\n            <Input\n              id={id}\n              type=\"text\"\n              placeholder=\"Type Timkit UI to confirm\"\n              value={inputValue}\n              onChange={(e) => setInputValue(e.target.value)}\n            />\n          </div>\n          <DialogFooter>\n            <DialogClose asChild>\n              <Button type=\"button\" variant=\"outline\" className=\"flex-1\">\n                Cancel\n              </Button>\n            </DialogClose>\n            <Button type=\"button\" className=\"flex-1\" disabled={inputValue !== PROJECT_NAME}>\n              Delete\n            </Button>\n          </DialogFooter>\n        </form>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-08.vue",
          "target": "components/ui/dialog-08.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { CircleAlertIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from '@timui/vue';\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\nconst PROJECT_NAME = 'Timkit UI';\nconst id = 'dialog-08';\nconst inputValue = ref('');\n</script>\n\n<template>\n  <Dialog>\n    <DialogTrigger as-child>\n      <Button variant=\"outline\">Delete project</Button>\n    </DialogTrigger>\n    <DialogContent>\n      <div class=\"flex flex-col items-center gap-2\">\n        <div class=\"flex size-9 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\">\n          <CircleAlertIcon class=\"opacity-80\" :size=\"16\" />\n        </div>\n        <DialogHeader>\n          <DialogTitle class=\"sm:text-center\">Final confirmation</DialogTitle>\n          <DialogDescription class=\"sm:text-center\">\n            This action cannot be undone. To confirm, please enter the project name\n            <span class=\"text-foreground\">Timkit UI</span>.\n          </DialogDescription>\n        </DialogHeader>\n      </div>\n\n      <form class=\"space-y-5\">\n        <div class=\"*:not-first:mt-2\">\n          <Label :htmlFor=\"id\">Project name</Label>\n          <Input\n            :id=\"id\"\n            type=\"text\"\n            placeholder=\"Type Timkit UI to confirm\"\n            v-model=\"inputValue\"\n          />\n        </div>\n        <DialogFooter>\n          <DialogClose as-child>\n            <Button type=\"button\" variant=\"outline\" class=\"flex-1\">Cancel</Button>\n          </DialogClose>\n          <Button type=\"button\" class=\"flex-1\" :disabled=\"inputValue !== PROJECT_NAME\">Delete</Button>\n        </DialogFooter>\n      </form>\n    </DialogContent>\n  </Dialog>\n</template>\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-08.html",
          "target": "components/ui/dialog-08.html",
          "type": "registry:component",
          "content": "<template>\n  <Dialog><DialogTrigger aschild><Button variant=\"outline\">Delete project</Button></DialogTrigger><DialogContent><div class=\"flex flex-col items-center gap-2\"><div class=\"flex size-9 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><CircleAlertIcon class=\"opacity-80\" size=\"${16}\" /></div><DialogHeader><DialogTitle class=\"sm:text-center\">Final confirmation</DialogTitle><DialogDescription class=\"sm:text-center\">This action cannot be undone. To confirm, please enter the project name${' '}<span class=\"text-foreground\">Timkit UI</span>.\n            </DialogDescription></DialogHeader></div><form class=\"space-y-5\"><div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Project name</Label><Input id=\"${id}\" type=\"text\" placeholder=\"Type Timkit UI to confirm\" value=\"${inputValue}\" onchange=\"${(e) => setInputValue(e.target.value)}\" /></div><DialogFooter><DialogClose aschild><Button type=\"button\" variant=\"outline\" class=\"flex-1\">Cancel\n              </Button></DialogClose><Button type=\"button\" class=\"flex-1\" disabled=\"${inputValue !== PROJECT_NAME}\">Delete\n            </Button></DialogFooter></form></DialogContent></Dialog>\n</template>"
        },
        {
          "path": "registry/default/components/dialog/dialog-08.wxml",
          "target": "components/ui/dialog-08/dialog-08.wxml",
          "type": "registry:component",
          "content": "<view>\n  <dialog><dialogtrigger aschild><button variant=\"outline\">Delete project</button></dialogtrigger><dialogcontent><view class=\"flex flex-col items-center gap-2\"><view class=\"flex size-9 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><circlealerticon class=\"opacity-80\" size=\"{{16}}\" /></view><dialogheader><dialogtitle class=\"sm:text-center\">Final confirmation</dialogtitle><dialogdescription class=\"sm:text-center\">This action cannot be undone. To confirm, please enter the project name{{ ' ' }}<text class=\"text-foreground\">Timkit UI</text>.\n            </dialogdescription></dialogheader></view><form class=\"space-y-5\"><view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Project name</label><input id=\"{{id}}\" type=\"text\" placeholder=\"Type Timkit UI to confirm\" value=\"{{inputValue}}\" onchange=\"{{(e) => setInputValue(e.target.value)}}\" /></view><dialogfooter><dialogclose aschild><button type=\"button\" variant=\"outline\" class=\"flex-1\">Cancel\n              </button></dialogclose><button type=\"button\" class=\"flex-1\" disabled=\"{{inputValue !== PROJECT_NAME}}\">Delete\n            </button></dialogfooter></form></dialogcontent></dialog>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dialog",
          "modal",
          "delete",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dialog-08",
          "group": "dialog",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dialog-08",
              "path": "registry/default/components/dialog/dialog-08.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dialog-08",
              "path": "registry/default/components/dialog/dialog-08.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dialog-08",
              "path": "registry/default/components/dialog/dialog-08.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dialog-08",
              "path": "registry/default/components/dialog/dialog-08.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dialog",
        "title": "Dialog · Project name"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "dialog"
      ]
    },
    {
      "name": "dialog-09",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dialog.json",
        "https://ui.timkit.cn/r/input.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/dialog/dialog-09.tsx",
          "type": "registry:component",
          "target": "components/ui/dialog-09.tsx",
          "content": "import {\n  Button,\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n  Input,\n} from '@timui/react'\nimport { MailIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <Dialog>\n      <DialogTrigger asChild>\n        <Button variant=\"outline\">Newsletter</Button>\n      </DialogTrigger>\n      <DialogContent>\n        <div className=\"mb-2 flex flex-col items-center gap-2\">\n          <div\n            className=\"flex size-11 shrink-0 items-center justify-center rounded-full border\"\n            aria-hidden=\"true\"\n          >\n            <svg\n              className=\"stroke-zinc-800 dark:stroke-zinc-100\"\n              xmlns=\"http://www.w3.org/2000/svg\"\n              width=\"20\"\n              height=\"20\"\n              viewBox=\"0 0 32 32\"\n              aria-hidden=\"true\"\n            >\n              <circle cx=\"16\" cy=\"16\" r=\"12\" fill=\"none\" strokeWidth=\"8\" />\n            </svg>\n          </div>\n          <DialogHeader>\n            <DialogTitle className=\"sm:text-center\">Never miss an update</DialogTitle>\n            <DialogDescription className=\"sm:text-center\">\n              Subscribe to receive news and special offers.\n            </DialogDescription>\n          </DialogHeader>\n        </div>\n\n        <form className=\"space-y-5\">\n          <div className=\"*:not-first:mt-2\">\n            <div className=\"relative\">\n              <Input\n                id=\"dialog-subscribe\"\n                className=\"peer ps-9\"\n                placeholder=\"hi@yourcompany.com\"\n                type=\"email\"\n                aria-label=\"Email\"\n              />\n              <div className=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\">\n                <MailIcon size={16} aria-hidden=\"true\" />\n              </div>\n            </div>\n          </div>\n          <Button type=\"button\" className=\"w-full\">\n            Subscribe\n          </Button>\n        </form>\n\n        <p className=\"text-muted-foreground text-center text-xs\">\n          By subscribing you agree to our{' '}\n          <a className=\"underline hover:no-underline\" href=\"#\">\n            Privacy Policy\n          </a>\n          .\n        </p>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-09.vue",
          "target": "components/ui/dialog-09.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { MailIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from '@timui/vue';\nimport { Input } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Dialog><DialogTrigger as-child><Button variant=\"outline\">Newsletter</Button></DialogTrigger><DialogContent><div class=\"mb-2 flex flex-col items-center gap-2\"><div class=\"flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><svg class=\"stroke-zinc-800 dark:stroke-zinc-100\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 32 32\" aria-hidden=\"true\"><circle cx=\"16\" cy=\"16\" r=\"12\" fill=\"none\" stroke-width=\"8\" /></svg></div><DialogHeader><DialogTitle class=\"sm:text-center\">Never miss an update</DialogTitle><DialogDescription class=\"sm:text-center\">Subscribe to receive news and special offers.\n            </DialogDescription></DialogHeader></div><form class=\"space-y-5\"><div class=\"*:not-first:mt-2\"><div class=\"relative\"><Input id=\"dialog-subscribe\" class=\"peer ps-9\" placeholder=\"hi@yourcompany.com\" type=\"email\" aria-label=\"Email\" /><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\"><MailIcon :size=\"16\" aria-hidden=\"true\" /></div></div></div><Button type=\"button\" class=\"w-full\">Subscribe\n          </Button></form><p class=\"text-muted-foreground text-center text-xs\">By subscribing you agree to our{{ ' ' }}<a class=\"underline hover:no-underline\" href=\"#\">Privacy Policy\n          </a>.\n        </p></DialogContent></Dialog>\n</template>\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-09.html",
          "target": "components/ui/dialog-09.html",
          "type": "registry:component",
          "content": "<template>\n  <Dialog><DialogTrigger aschild><Button variant=\"outline\">Newsletter</Button></DialogTrigger><DialogContent><div class=\"mb-2 flex flex-col items-center gap-2\"><div class=\"flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><svg class=\"stroke-zinc-800 dark:stroke-zinc-100\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewbox=\"0 0 32 32\" aria-hidden=\"true\"><circle cx=\"16\" cy=\"16\" r=\"12\" fill=\"none\" stroke-width=\"8\" /></svg></div><DialogHeader><DialogTitle class=\"sm:text-center\">Never miss an update</DialogTitle><DialogDescription class=\"sm:text-center\">Subscribe to receive news and special offers.\n            </DialogDescription></DialogHeader></div><form class=\"space-y-5\"><div class=\"*:not-first:mt-2\"><div class=\"relative\"><Input id=\"dialog-subscribe\" class=\"peer ps-9\" placeholder=\"hi@yourcompany.com\" type=\"email\" aria-label=\"Email\" /><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\"><MailIcon size=\"${16}\" aria-hidden=\"true\" /></div></div></div><Button type=\"button\" class=\"w-full\">Subscribe\n          </Button></form><p class=\"text-muted-foreground text-center text-xs\">By subscribing you agree to our${' '}<a class=\"underline hover:no-underline\" href=\"#\">Privacy Policy\n          </a>.\n        </p></DialogContent></Dialog>\n</template>"
        },
        {
          "path": "registry/default/components/dialog/dialog-09.wxml",
          "target": "components/ui/dialog-09/dialog-09.wxml",
          "type": "registry:component",
          "content": "<view>\n  <dialog><dialogtrigger aschild><button variant=\"outline\">Newsletter</button></dialogtrigger><dialogcontent><view class=\"mb-2 flex flex-col items-center gap-2\"><view class=\"flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><svg class=\"stroke-zinc-800 dark:stroke-zinc-100\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewbox=\"0 0 32 32\" aria-hidden=\"true\"><circle cx=\"16\" cy=\"16\" r=\"12\" fill=\"none\" stroke-width=\"8\" /></svg></view><dialogheader><dialogtitle class=\"sm:text-center\">Never miss an update</dialogtitle><dialogdescription class=\"sm:text-center\">Subscribe to receive news and special offers.\n            </dialogdescription></dialogheader></view><form class=\"space-y-5\"><view class=\"*:not-first:mt-2\"><view class=\"relative\"><input id=\"dialog-subscribe\" class=\"peer ps-9\" placeholder=\"hi@yourcompany.com\" type=\"email\" aria-label=\"Email\" /><view class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\"><mailicon size=\"{{16}}\" aria-hidden=\"true\" /></view></view></view><button type=\"button\" class=\"w-full\">Subscribe\n          </button></form><text class=\"text-muted-foreground text-center text-xs\">By subscribing you agree to our{{ ' ' }}<a class=\"underline hover:no-underline\" href=\"#\">Privacy Policy\n          </a>.\n        </text></dialogcontent></dialog>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dialog",
          "modal",
          "newsletter",
          "subscribe",
          "form",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dialog-09",
          "group": "dialog",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dialog-09",
              "path": "registry/default/components/dialog/dialog-09.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dialog-09",
              "path": "registry/default/components/dialog/dialog-09.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dialog-09",
              "path": "registry/default/components/dialog/dialog-09.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dialog-09",
              "path": "registry/default/components/dialog/dialog-09.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dialog",
        "title": "Dialog · Email"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "dialog"
      ]
    },
    {
      "name": "dialog-10",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dialog.json",
        "https://ui.timkit.cn/r/textarea.json"
      ],
      "files": [
        {
          "path": "registry/default/components/dialog/dialog-10.tsx",
          "type": "registry:component",
          "target": "components/ui/dialog-10.tsx",
          "content": "import {\n  Button,\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n  Textarea,\n} from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Dialog>\n      <DialogTrigger asChild>\n        <Button variant=\"outline\">Feedback</Button>\n      </DialogTrigger>\n      <DialogContent>\n        <DialogHeader>\n          <DialogTitle>Send us feedback</DialogTitle>\n          <DialogDescription>\n            Watch{' '}\n            <a className=\"text-foreground hover:underline\" href=\"#\">\n              tutorials\n            </a>\n            , read Timkit UI&lsquo;s{' '}\n            <a className=\"text-foreground hover:underline\" href=\"#\">\n              documentation\n            </a>\n            , or join our{' '}\n            <a className=\"text-foreground hover:underline\" href=\"#\">\n              Discord\n            </a>{' '}\n            for community help.\n          </DialogDescription>\n        </DialogHeader>\n        <form className=\"space-y-5\">\n          <Textarea\n            id=\"feedback\"\n            placeholder=\"How can we improve Timkit UI?\"\n            aria-label=\"Send feedback\"\n          />\n          <div className=\"flex flex-col sm:flex-row sm:justify-end\">\n            <Button type=\"button\">Send feedback</Button>\n          </div>\n        </form>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-10.vue",
          "target": "components/ui/dialog-10.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from '@timui/vue';\nimport { Textarea } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Dialog><DialogTrigger as-child><Button variant=\"outline\">Feedback</Button></DialogTrigger><DialogContent><DialogHeader><DialogTitle>Send us feedback</DialogTitle><DialogDescription>Watch{{ ' ' }}<a class=\"text-foreground hover:underline\" href=\"#\">tutorials\n            </a>, read Timkit UI&lsquo;s{{ ' ' }}<a class=\"text-foreground hover:underline\" href=\"#\">documentation\n            </a>, or join our{{ ' ' }}<a class=\"text-foreground hover:underline\" href=\"#\">Discord\n            </a>{{ ' ' }}for community help.\n          </DialogDescription></DialogHeader><form class=\"space-y-5\"><Textarea id=\"feedback\" placeholder=\"How can we improve Timkit UI?\" aria-label=\"Send feedback\" /><div class=\"flex flex-col sm:flex-row sm:justify-end\"><Button type=\"button\">Send feedback</Button></div></form></DialogContent></Dialog>\n</template>\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-10.html",
          "target": "components/ui/dialog-10.html",
          "type": "registry:component",
          "content": "<template>\n  <Dialog><DialogTrigger aschild><Button variant=\"outline\">Feedback</Button></DialogTrigger><DialogContent><DialogHeader><DialogTitle>Send us feedback</DialogTitle><DialogDescription>Watch${' '}<a class=\"text-foreground hover:underline\" href=\"#\">tutorials\n            </a>, read Timkit UI&lsquo;s${' '}<a class=\"text-foreground hover:underline\" href=\"#\">documentation\n            </a>, or join our${' '}<a class=\"text-foreground hover:underline\" href=\"#\">Discord\n            </a>${' '}for community help.\n          </DialogDescription></DialogHeader><form class=\"space-y-5\"><Textarea id=\"feedback\" placeholder=\"How can we improve Timkit UI?\" aria-label=\"Send feedback\" /><div class=\"flex flex-col sm:flex-row sm:justify-end\"><Button type=\"button\">Send feedback</Button></div></form></DialogContent></Dialog>\n</template>"
        },
        {
          "path": "registry/default/components/dialog/dialog-10.wxml",
          "target": "components/ui/dialog-10/dialog-10.wxml",
          "type": "registry:component",
          "content": "<view>\n  <dialog><dialogtrigger aschild><button variant=\"outline\">Feedback</button></dialogtrigger><dialogcontent><dialogheader><dialogtitle>Send us feedback</dialogtitle><dialogdescription>Watch{{ ' ' }}<a class=\"text-foreground hover:underline\" href=\"#\">tutorials\n            </a>, read Timkit UI&lsquo;s{{ ' ' }}<a class=\"text-foreground hover:underline\" href=\"#\">documentation\n            </a>, or join our{{ ' ' }}<a class=\"text-foreground hover:underline\" href=\"#\">Discord\n            </a>{{ ' ' }}for community help.\n          </dialogdescription></dialogheader><form class=\"space-y-5\"><textarea id=\"feedback\" placeholder=\"How can we improve Timkit UI?\" aria-label=\"Send feedback\" /><view class=\"flex flex-col sm:flex-row sm:justify-end\"><button type=\"button\">Send feedback</button></view></form></dialogcontent></dialog>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dialog",
          "modal",
          "feedback",
          "form",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dialog-10",
          "group": "dialog",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dialog-10",
              "path": "registry/default/components/dialog/dialog-10.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dialog-10",
              "path": "registry/default/components/dialog/dialog-10.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dialog-10",
              "path": "registry/default/components/dialog/dialog-10.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dialog-10",
              "path": "registry/default/components/dialog/dialog-10.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dialog",
        "title": "Dialog · Send feedback"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "dialog"
      ]
    },
    {
      "name": "dialog-11",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dialog.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/radio-group.json",
        "https://ui.timkit.cn/r/textarea.json"
      ],
      "files": [
        {
          "path": "registry/default/components/dialog/dialog-11.tsx",
          "type": "registry:component",
          "target": "components/ui/dialog-11.tsx",
          "content": "import {\n  Button,\n  Dialog,\n  DialogContent,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n  Label,\n  RadioGroup,\n  RadioGroupItem,\n  Textarea,\n} from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Dialog>\n      <DialogTrigger asChild>\n        <Button variant=\"outline\">Rating</Button>\n      </DialogTrigger>\n      <DialogContent className=\"flex flex-col gap-0 p-0 [&>button:last-child]:top-3.5\">\n        <DialogHeader className=\"contents space-y-0 text-left\">\n          <DialogTitle className=\"border-b px-6 py-4 text-base\">Help us improve</DialogTitle>\n        </DialogHeader>\n        <div className=\"px-6 py-4\">\n          <form className=\"space-y-5\">\n            <div className=\"space-y-4\">\n              <div>\n                <fieldset className=\"space-y-4\">\n                  <legend className=\"text-foreground text-lg leading-none font-semibold\">\n                    How hard was it to set up your account?\n                  </legend>\n                  <RadioGroup className=\"flex gap-0 -space-x-px rounded-md shadow-xs\">\n                    {[0, 1, 2, 3, 4, 5, 6, 7, 8].map((number) => (\n                      <label\n                        key={number}\n                        className=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex size-9 flex-1 cursor-pointer flex-col items-center justify-center gap-3 border text-center text-sm transition-[color,box-shadow] outline-none first:rounded-s-md last:rounded-e-md has-focus-visible:ring-[3px] has-data-disabled:cursor-not-allowed has-data-disabled:opacity-50 has-data-[state=checked]:z-10\"\n                      >\n                        <RadioGroupItem\n                          id={`radio-17-r${number}`}\n                          value={number.toString()}\n                          className=\"sr-only after:absolute after:inset-0\"\n                        />\n                        {number}\n                      </label>\n                    ))}\n                  </RadioGroup>\n                </fieldset>\n                <div className=\"text-muted-foreground mt-2 flex justify-between text-xs\">\n                  <p>Very easy</p>\n                  <p>Very dificult</p>\n                </div>\n              </div>\n\n              <div className=\"*:not-first:mt-2\">\n                <Label>Why did you give this rating?</Label>\n                <Textarea\n                  id=\"feedback\"\n                  placeholder=\"How can we improve Timkit UI?\"\n                  aria-label=\"Send feedback\"\n                />\n              </div>\n            </div>\n            <Button type=\"button\" className=\"w-full\">\n              Send feedback\n            </Button>\n          </form>\n        </div>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-11.vue",
          "target": "components/ui/dialog-11.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\nimport { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from '@timui/vue';\nimport { Label } from '@timui/vue';\nimport { RadioGroup } from '@timui/vue';\nimport { RadioGroupItem } from '@timui/vue';\nimport { Textarea } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Dialog><DialogTrigger as-child><Button variant=\"outline\">Rating</Button></DialogTrigger><DialogContent class=\"flex flex-col gap-0 p-0 [&>button:last-child]:top-3.5\"><DialogHeader class=\"contents space-y-0 text-left\"><DialogTitle class=\"border-b px-6 py-4 text-base\">Help us improve</DialogTitle></DialogHeader><div class=\"px-6 py-4\"><form class=\"space-y-5\"><div class=\"space-y-4\"><div><fieldset class=\"space-y-4\"><legend class=\"text-foreground text-lg leading-none font-semibold\">How hard was it to set up your account?\n                  </legend><RadioGroup class=\"flex gap-0 -space-x-px rounded-md shadow-xs\"><label v-for=\"(number, index) in [0, 1, 2, 3, 4, 5, 6, 7, 8]\" :key=\"number\" class=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex size-9 flex-1 cursor-pointer flex-col items-center justify-center gap-3 border text-center text-sm transition-[color,box-shadow] outline-none first:rounded-s-md last:rounded-e-md has-focus-visible:ring-[3px] has-data-disabled:cursor-not-allowed has-data-disabled:opacity-50 has-data-[state=checked]:z-10\"><RadioGroupItem :id=\"`radio-17-r${number}`\" :value=\"number.toString()\" class=\"sr-only after:absolute after:inset-0\" />{{ number }}</label></RadioGroup></fieldset><div class=\"text-muted-foreground mt-2 flex justify-between text-xs\"><p>Very easy</p><p>Very dificult</p></div></div><div class=\"*:not-first:mt-2\"><Label>Why did you give this rating?</Label><Textarea id=\"feedback\" placeholder=\"How can we improve Timkit UI?\" aria-label=\"Send feedback\" /></div></div><Button type=\"button\" class=\"w-full\">Send feedback\n            </Button></form></div></DialogContent></Dialog>\n</template>\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-11.html",
          "target": "components/ui/dialog-11.html",
          "type": "registry:component",
          "content": "<template>\n  <Dialog><DialogTrigger aschild><Button variant=\"outline\">Rating</Button></DialogTrigger><DialogContent class=\"flex flex-col gap-0 p-0 [&>button:last-child]:top-3.5\"><DialogHeader class=\"contents space-y-0 text-left\"><DialogTitle class=\"border-b px-6 py-4 text-base\">Help us improve</DialogTitle></DialogHeader><div class=\"px-6 py-4\"><form class=\"space-y-5\"><div class=\"space-y-4\"><div><fieldset class=\"space-y-4\"><legend class=\"text-foreground text-lg leading-none font-semibold\">How hard was it to set up your account?\n                  </legend><RadioGroup class=\"flex gap-0 -space-x-px rounded-md shadow-xs\"><!-- Loop [0, 1, 2, 3, 4, 5, 6, 7, 8] -->\n<label key=\"${number}\" class=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex size-9 flex-1 cursor-pointer flex-col items-center justify-center gap-3 border text-center text-sm transition-[color,box-shadow] outline-none first:rounded-s-md last:rounded-e-md has-focus-visible:ring-[3px] has-data-disabled:cursor-not-allowed has-data-disabled:opacity-50 has-data-[state=checked]:z-10\"><RadioGroupItem id=\"${`radio-17-r${number}`}\" value=\"${number.toString()}\" class=\"sr-only after:absolute after:inset-0\" />${number}</label>\n<!-- End Loop --></RadioGroup></fieldset><div class=\"text-muted-foreground mt-2 flex justify-between text-xs\"><p>Very easy</p><p>Very dificult</p></div></div><div class=\"*:not-first:mt-2\"><Label>Why did you give this rating?</Label><Textarea id=\"feedback\" placeholder=\"How can we improve Timkit UI?\" aria-label=\"Send feedback\" /></div></div><Button type=\"button\" class=\"w-full\">Send feedback\n            </Button></form></div></DialogContent></Dialog>\n</template>"
        },
        {
          "path": "registry/default/components/dialog/dialog-11.wxml",
          "target": "components/ui/dialog-11/dialog-11.wxml",
          "type": "registry:component",
          "content": "<view>\n  <dialog><dialogtrigger aschild><button variant=\"outline\">Rating</button></dialogtrigger><dialogcontent class=\"flex flex-col gap-0 p-0 [&>button:last-child]:top-3.5\"><dialogheader class=\"contents space-y-0 text-left\"><dialogtitle class=\"border-b px-6 py-4 text-base\">Help us improve</dialogtitle></dialogheader><view class=\"px-6 py-4\"><form class=\"space-y-5\"><view class=\"space-y-4\"><view><fieldset class=\"space-y-4\"><legend class=\"text-foreground text-lg leading-none font-semibold\">How hard was it to set up your account?\n                  </legend><radiogroup class=\"flex gap-0 -space-x-px rounded-md shadow-xs\"><label wx:for=\"{{[0, 1, 2, 3, 4, 5, 6, 7, 8]}}\" wx:for-item=\"number\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{number}}\" class=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex size-9 flex-1 cursor-pointer flex-col items-center justify-center gap-3 border text-center text-sm transition-[color,box-shadow] outline-none first:rounded-s-md last:rounded-e-md has-focus-visible:ring-[3px] has-data-disabled:cursor-not-allowed has-data-disabled:opacity-50 has-data-[state=checked]:z-10\"><radiogroupitem id=\"{{`radio-17-r${number}`}}\" value=\"{{number.toString()}}\" class=\"sr-only after:absolute after:inset-0\" />{{ number }}</label></radiogroup></fieldset><view class=\"text-muted-foreground mt-2 flex justify-between text-xs\"><text>Very easy</text><text>Very dificult</text></view></view><view class=\"*:not-first:mt-2\"><label>Why did you give this rating?</label><textarea id=\"feedback\" placeholder=\"How can we improve Timkit UI?\" aria-label=\"Send feedback\" /></view></view><button type=\"button\" class=\"w-full\">Send feedback\n            </button></form></view></dialogcontent></dialog>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dialog",
          "modal",
          "rating",
          "feedback",
          "form",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dialog-11",
          "group": "dialog",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dialog-11",
              "path": "registry/default/components/dialog/dialog-11.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dialog-11",
              "path": "registry/default/components/dialog/dialog-11.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dialog-11",
              "path": "registry/default/components/dialog/dialog-11.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dialog-11",
              "path": "registry/default/components/dialog/dialog-11.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dialog",
        "title": "Dialog · Why did you give this rating?"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "dialog"
      ]
    },
    {
      "name": "dialog-12",
      "type": "registry:component",
      "dependencies": [
        "@timui/core",
        "@timui/react",
        "input-otp"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dialog.json"
      ],
      "files": [
        {
          "path": "registry/default/components/dialog/dialog-12.tsx",
          "type": "registry:component",
          "target": "components/ui/dialog-12.tsx",
          "content": "'use client'\n\nimport { useEffect, useRef, useState } from 'react'\nimport { cn } from '@timui/core'\nimport {\n  Button,\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n} from '@timui/react'\nimport { OTPInput, SlotProps } from 'input-otp'\n\nconst CORRECT_CODE = '6548'\n\nexport default function Component() {\n  const [value, setValue] = useState('')\n  const [hasGuessed, setHasGuessed] = useState<undefined | boolean>(undefined)\n  const inputRef = useRef<HTMLInputElement>(null)\n  const closeButtonRef = useRef<HTMLButtonElement>(null)\n\n  useEffect(() => {\n    if (hasGuessed) {\n      closeButtonRef.current?.focus()\n    }\n  }, [hasGuessed])\n\n  async function onSubmit(e?: React.FormEvent<HTMLFormElement>) {\n    e?.preventDefault?.()\n\n    inputRef.current?.select()\n    await new Promise((r) => setTimeout(r, 1_00))\n\n    setHasGuessed(value === CORRECT_CODE)\n\n    setValue('')\n    setTimeout(() => {\n      inputRef.current?.blur()\n    }, 20)\n  }\n\n  return (\n    <Dialog>\n      <DialogTrigger asChild>\n        <Button variant=\"outline\">OTP code</Button>\n      </DialogTrigger>\n      <DialogContent>\n        <div className=\"flex flex-col items-center gap-2\">\n          <div\n            className=\"flex size-11 shrink-0 items-center justify-center rounded-full border\"\n            aria-hidden=\"true\"\n          >\n            <svg\n              className=\"stroke-zinc-800 dark:stroke-zinc-100\"\n              xmlns=\"http://www.w3.org/2000/svg\"\n              width=\"20\"\n              height=\"20\"\n              viewBox=\"0 0 32 32\"\n              aria-hidden=\"true\"\n            >\n              <circle cx=\"16\" cy=\"16\" r=\"12\" fill=\"none\" strokeWidth=\"8\" />\n            </svg>\n          </div>\n          <DialogHeader>\n            <DialogTitle className=\"sm:text-center\">\n              {hasGuessed ? 'Code verified!' : 'Enter confirmation code'}\n            </DialogTitle>\n            <DialogDescription className=\"sm:text-center\">\n              {hasGuessed\n                ? 'Your code has been successfully verified.'\n                : `Check your email and enter the code - Try ${CORRECT_CODE}`}\n            </DialogDescription>\n          </DialogHeader>\n        </div>\n\n        {hasGuessed ? (\n          <div className=\"text-center\">\n            <DialogClose asChild>\n              <Button type=\"button\" ref={closeButtonRef}>\n                Close\n              </Button>\n            </DialogClose>\n          </div>\n        ) : (\n          <div className=\"space-y-4\">\n            <div className=\"flex justify-center\">\n              <OTPInput\n                id=\"cofirmation-code\"\n                ref={inputRef}\n                value={value}\n                onChange={setValue}\n                containerClassName=\"flex items-center gap-3 has-disabled:opacity-50\"\n                maxLength={4}\n                onFocus={() => setHasGuessed(undefined)}\n                render={({ slots }) => (\n                  <div className=\"flex gap-2\">\n                    {slots.map((slot, idx) => (\n                      <Slot key={idx} {...slot} />\n                    ))}\n                  </div>\n                )}\n                onComplete={onSubmit}\n              />\n            </div>\n            {hasGuessed === false && (\n              <p\n                className=\"text-muted-foreground text-center text-xs\"\n                role=\"alert\"\n                aria-live=\"polite\"\n              >\n                Invalid code. Please try again.\n              </p>\n            )}\n            <p className=\"text-center text-sm\">\n              <a className=\"underline hover:no-underline\" href=\"#\">\n                Resend code\n              </a>\n            </p>\n          </div>\n        )}\n      </DialogContent>\n    </Dialog>\n  )\n}\n\nfunction Slot(props: SlotProps) {\n  return (\n    <div\n      className={cn(\n        'border-input bg-background text-foreground flex size-9 items-center justify-center rounded-md border font-medium shadow-xs transition-[color,box-shadow]',\n        { 'border-ring ring-ring/50 z-10 ring-[3px]': props.isActive }\n      )}\n    >\n      {props.char !== null && <div>{props.char}</div>}\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-12.vue",
          "target": "components/ui/dialog-12.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Button } from '@timui/vue';\nimport { Dialog, DialogClose, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from '@timui/vue';\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\nconst CORRECT_CODE = '6548';\nconst value = ref('');\nconst hasGuessed = ref<undefined | boolean>(undefined);\n\nfunction onSubmit() {\n  hasGuessed.value = value.value === CORRECT_CODE;\n  if (hasGuessed.value) {\n    value.value = '';\n  }\n}\n\nfunction handleCodeChange(next: string | number) {\n  hasGuessed.value = undefined;\n  value.value = String(next).replace(/\\D/g, '').slice(0, 4);\n}\n</script>\n\n<template>\n  <Dialog>\n    <DialogTrigger as-child>\n      <Button variant=\"outline\">OTP code</Button>\n    </DialogTrigger>\n    <DialogContent>\n      <div class=\"flex flex-col items-center gap-2\">\n        <div class=\"flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\">\n          <svg class=\"stroke-zinc-800 dark:stroke-zinc-100\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 32 32\" aria-hidden=\"true\">\n            <circle cx=\"16\" cy=\"16\" r=\"12\" fill=\"none\" stroke-width=\"8\" />\n          </svg>\n        </div>\n        <DialogHeader>\n          <DialogTitle class=\"sm:text-center\">{{ hasGuessed ? 'Code verified!' : 'Enter confirmation code' }}</DialogTitle>\n          <DialogDescription class=\"sm:text-center\">\n            {{ hasGuessed ? 'Your code has been successfully verified.' : `Check your email and enter the code - Try ${CORRECT_CODE}` }}\n          </DialogDescription>\n        </DialogHeader>\n      </div>\n\n      <template v-if=\"hasGuessed\">\n        <div class=\"text-center\">\n          <DialogClose as-child>\n            <Button type=\"button\">Close</Button>\n          </DialogClose>\n        </div>\n      </template>\n      <template v-else>\n        <div class=\"space-y-4\">\n          <div class=\"*:not-first:mt-2\">\n            <Label htmlFor=\"confirmation-code\">Confirmation code</Label>\n            <Input\n              id=\"confirmation-code\"\n              :model-value=\"value\"\n              @update:modelValue=\"(next) => handleCodeChange(next ?? '')\"\n              placeholder=\"Enter 4-digit code\"\n              inputMode=\"numeric\"\n              maxlength=\"4\"\n            />\n          </div>\n          <Button type=\"button\" class=\"w-full\" @click=\"onSubmit\" :disabled=\"value.length !== 4\">Verify code</Button>\n          <p v-if=\"hasGuessed === false\" class=\"text-muted-foreground text-center text-xs\" role=\"alert\" aria-live=\"polite\">\n            Invalid code. Please try again.\n          </p>\n        </div>\n      </template>\n    </DialogContent>\n  </Dialog>\n</template>\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-12.html",
          "target": "components/ui/dialog-12.html",
          "type": "registry:component",
          "content": "<template>\n  <Dialog><DialogTrigger aschild><Button variant=\"outline\">OTP code</Button></DialogTrigger><DialogContent><div class=\"flex flex-col items-center gap-2\"><div class=\"flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><svg class=\"stroke-zinc-800 dark:stroke-zinc-100\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewbox=\"0 0 32 32\" aria-hidden=\"true\"><circle cx=\"16\" cy=\"16\" r=\"12\" fill=\"none\" stroke-width=\"8\" /></svg></div><DialogHeader><DialogTitle class=\"sm:text-center\"><!-- if hasGuessed -->\n${'Code verified!'}\n<!-- else -->\n${'Enter confirmation code'}\n<!-- endif --></DialogTitle><DialogDescription class=\"sm:text-center\"><!-- if hasGuessed -->\n${'Your code has been successfully verified.'}\n<!-- else -->\n${`Check your email and enter the code - Try ${CORRECT_CODE}`}\n<!-- endif --></DialogDescription></DialogHeader></div><!-- if hasGuessed -->\n<div class=\"text-center\"><DialogClose aschild><Button type=\"button\" ref=\"${closeButtonRef}\">Close\n              </Button></DialogClose></div>\n<!-- else -->\n<div class=\"space-y-4\"><div class=\"flex justify-center\"><OTPInput id=\"cofirmation-code\" ref=\"${inputRef}\" value=\"${value}\" onchange=\"${setValue}\" containerclassname=\"flex items-center gap-3 has-disabled:opacity-50\" maxlength=\"${4}\" onfocus=\"${() => setHasGuessed(undefined)}\" render=\"${({ slots }) => (\n                  <div className=\"flex gap-2\">\n                    {slots.map((slot, idx) => (\n                      <Slot key={idx} {...slot} />\n                    ))}\n                  </div>\n                )}\" oncomplete=\"${onSubmit}\" /></div><!-- if hasGuessed === false -->\n<p class=\"text-muted-foreground text-center text-xs\" role=\"alert\" aria-live=\"polite\">Invalid code. Please try again.\n              </p>\n<!-- endif --><p class=\"text-center text-sm\"><a class=\"underline hover:no-underline\" href=\"#\">Resend code\n              </a></p></div>\n<!-- endif --></DialogContent></Dialog>\n</template>"
        },
        {
          "path": "registry/default/components/dialog/dialog-12.wxml",
          "target": "components/ui/dialog-12/dialog-12.wxml",
          "type": "registry:component",
          "content": "<view>\n  <dialog><dialogtrigger aschild><button variant=\"outline\">OTP code</button></dialogtrigger><dialogcontent><view class=\"flex flex-col items-center gap-2\"><view class=\"flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><svg class=\"stroke-zinc-800 dark:stroke-zinc-100\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewbox=\"0 0 32 32\" aria-hidden=\"true\"><circle cx=\"16\" cy=\"16\" r=\"12\" fill=\"none\" stroke-width=\"8\" /></svg></view><dialogheader><dialogtitle class=\"sm:text-center\"><block wx:if=\"{{hasGuessed}}\">\n{{ 'Code verified!' }}\n</block>\n<block wx:else>\n{{ 'Enter confirmation code' }}\n</block></dialogtitle><dialogdescription class=\"sm:text-center\"><block wx:if=\"{{hasGuessed}}\">\n{{ 'Your code has been successfully verified.' }}\n</block>\n<block wx:else>\n{{ `Check your email and enter the code - Try ${CORRECT_CODE}` }}\n</block></dialogdescription></dialogheader></view><block wx:if=\"{{hasGuessed}}\">\n<view class=\"text-center\"><dialogclose aschild><button type=\"button\" ref=\"{{closeButtonRef}}\">Close\n              </button></dialogclose></view>\n</block>\n<block wx:else>\n<view class=\"space-y-4\"><view class=\"flex justify-center\"><otpinput id=\"cofirmation-code\" ref=\"{{inputRef}}\" value=\"{{value}}\" onchange=\"{{setValue}}\" containerclassname=\"flex items-center gap-3 has-disabled:opacity-50\" maxlength=\"{{4}}\" onfocus=\"{{() => setHasGuessed(undefined)}}\" render=\"{{({ slots }) => (\n                  <div className=\"flex gap-2\">\n                    {slots.map((slot, idx) => (\n                      <Slot key={idx} {...slot} />\n                    ))}\n                  </div>\n                )}}\" oncomplete=\"{{onSubmit}}\" /></view><text wx:if=\"{{hasGuessed === false}}\" class=\"text-muted-foreground text-center text-xs\" role=\"alert\" aria-live=\"polite\">Invalid code. Please try again.\n              </text><text class=\"text-center text-sm\"><a class=\"underline hover:no-underline\" href=\"#\">Resend code\n              </a></text></view>\n</block></dialogcontent></dialog>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dialog",
          "modal",
          "otp",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dialog-12",
          "group": "dialog",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dialog-12",
              "path": "registry/default/components/dialog/dialog-12.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dialog-12",
              "path": "registry/default/components/dialog/dialog-12.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dialog-12",
              "path": "registry/default/components/dialog/dialog-12.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dialog-12",
              "path": "registry/default/components/dialog/dialog-12.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@timui/react",
              "input-otp"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dialog",
        "title": "Dialog · Dismissible"
      },
      "categories": [
        "dialog"
      ]
    },
    {
      "name": "dialog-13",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dialog.json",
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/dialog/dialog-13.tsx",
          "type": "registry:component",
          "target": "components/ui/dialog-13.tsx",
          "content": "import { useId } from 'react'\nimport {\n  Button,\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n  Input,\n  Label,\n} from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <Dialog>\n      <DialogTrigger asChild>\n        <Button variant=\"outline\">Sign up</Button>\n      </DialogTrigger>\n      <DialogContent>\n        <div className=\"flex flex-col items-center gap-2\">\n          <div\n            className=\"flex size-11 shrink-0 items-center justify-center rounded-full border\"\n            aria-hidden=\"true\"\n          >\n            <svg\n              className=\"stroke-zinc-800 dark:stroke-zinc-100\"\n              xmlns=\"http://www.w3.org/2000/svg\"\n              width=\"20\"\n              height=\"20\"\n              viewBox=\"0 0 32 32\"\n              aria-hidden=\"true\"\n            >\n              <circle cx=\"16\" cy=\"16\" r=\"12\" fill=\"none\" strokeWidth=\"8\" />\n            </svg>\n          </div>\n          <DialogHeader>\n            <DialogTitle className=\"sm:text-center\">Sign up Timkit UI</DialogTitle>\n            <DialogDescription className=\"sm:text-center\">\n              We just need a few details to get you started.\n            </DialogDescription>\n          </DialogHeader>\n        </div>\n\n        <form className=\"space-y-5\">\n          <div className=\"space-y-4\">\n            <div className=\"*:not-first:mt-2\">\n              <Label htmlFor={`${id}-name`}>Full name</Label>\n              <Input id={`${id}-name`} placeholder=\"Matt Welsh\" type=\"text\" required />\n            </div>\n            <div className=\"*:not-first:mt-2\">\n              <Label htmlFor={`${id}-email`}>Email</Label>\n              <Input id={`${id}-email`} placeholder=\"hi@yourcompany.com\" type=\"email\" required />\n            </div>\n            <div className=\"*:not-first:mt-2\">\n              <Label htmlFor={`${id}-password`}>Password</Label>\n              <Input\n                id={`${id}-password`}\n                placeholder=\"Enter your password\"\n                type=\"password\"\n                required\n              />\n            </div>\n          </div>\n          <Button type=\"button\" className=\"w-full\">\n            Sign up\n          </Button>\n        </form>\n\n        <div className=\"before:bg-border after:bg-border flex items-center gap-3 before:h-px before:flex-1 after:h-px after:flex-1\">\n          <span className=\"text-muted-foreground text-xs\">Or</span>\n        </div>\n\n        <Button variant=\"outline\">Continue with Google</Button>\n\n        <p className=\"text-muted-foreground text-center text-xs\">\n          By signing up you agree to our{' '}\n          <a className=\"underline hover:no-underline\" href=\"#\">\n            Terms\n          </a>\n          .\n        </p>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-13.vue",
          "target": "components/ui/dialog-13.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from '@timui/vue';\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'dialog-13';\n\n</script>\n\n<template>\n  <Dialog><DialogTrigger as-child><Button variant=\"outline\">Sign up</Button></DialogTrigger><DialogContent><div class=\"flex flex-col items-center gap-2\"><div class=\"flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><svg class=\"stroke-zinc-800 dark:stroke-zinc-100\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 32 32\" aria-hidden=\"true\"><circle cx=\"16\" cy=\"16\" r=\"12\" fill=\"none\" stroke-width=\"8\" /></svg></div><DialogHeader><DialogTitle class=\"sm:text-center\">Sign up Timkit UI</DialogTitle><DialogDescription class=\"sm:text-center\">We just need a few details to get you started.\n            </DialogDescription></DialogHeader></div><form class=\"space-y-5\"><div class=\"space-y-4\"><div class=\"*:not-first:mt-2\"><Label :htmlFor=\"`${id}-name`\">Full name</Label><Input :id=\"`${id}-name`\" placeholder=\"Matt Welsh\" type=\"text\" required /></div><div class=\"*:not-first:mt-2\"><Label :htmlFor=\"`${id}-email`\">Email</Label><Input :id=\"`${id}-email`\" placeholder=\"hi@yourcompany.com\" type=\"email\" required /></div><div class=\"*:not-first:mt-2\"><Label :htmlFor=\"`${id}-password`\">Password</Label><Input :id=\"`${id}-password`\" placeholder=\"Enter your password\" type=\"password\" required /></div></div><Button type=\"button\" class=\"w-full\">Sign up\n          </Button></form><div class=\"before:bg-border after:bg-border flex items-center gap-3 before:h-px before:flex-1 after:h-px after:flex-1\"><span class=\"text-muted-foreground text-xs\">Or</span></div><Button variant=\"outline\">Continue with Google</Button><p class=\"text-muted-foreground text-center text-xs\">By signing up you agree to our{{ ' ' }}<a class=\"underline hover:no-underline\" href=\"#\">Terms\n          </a>.\n        </p></DialogContent></Dialog>\n</template>\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-13.html",
          "target": "components/ui/dialog-13.html",
          "type": "registry:component",
          "content": "<template>\n  <Dialog><DialogTrigger aschild><Button variant=\"outline\">Sign up</Button></DialogTrigger><DialogContent><div class=\"flex flex-col items-center gap-2\"><div class=\"flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><svg class=\"stroke-zinc-800 dark:stroke-zinc-100\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewbox=\"0 0 32 32\" aria-hidden=\"true\"><circle cx=\"16\" cy=\"16\" r=\"12\" fill=\"none\" stroke-width=\"8\" /></svg></div><DialogHeader><DialogTitle class=\"sm:text-center\">Sign up Timkit UI</DialogTitle><DialogDescription class=\"sm:text-center\">We just need a few details to get you started.\n            </DialogDescription></DialogHeader></div><form class=\"space-y-5\"><div class=\"space-y-4\"><div class=\"*:not-first:mt-2\"><Label htmlfor=\"${`${id}-name`}\">Full name</Label><Input id=\"${`${id}-name`}\" placeholder=\"Matt Welsh\" type=\"text\" required /></div><div class=\"*:not-first:mt-2\"><Label htmlfor=\"${`${id}-email`}\">Email</Label><Input id=\"${`${id}-email`}\" placeholder=\"hi@yourcompany.com\" type=\"email\" required /></div><div class=\"*:not-first:mt-2\"><Label htmlfor=\"${`${id}-password`}\">Password</Label><Input id=\"${`${id}-password`}\" placeholder=\"Enter your password\" type=\"password\" required /></div></div><Button type=\"button\" class=\"w-full\">Sign up\n          </Button></form><div class=\"before:bg-border after:bg-border flex items-center gap-3 before:h-px before:flex-1 after:h-px after:flex-1\"><span class=\"text-muted-foreground text-xs\">Or</span></div><Button variant=\"outline\">Continue with Google</Button><p class=\"text-muted-foreground text-center text-xs\">By signing up you agree to our${' '}<a class=\"underline hover:no-underline\" href=\"#\">Terms\n          </a>.\n        </p></DialogContent></Dialog>\n</template>"
        },
        {
          "path": "registry/default/components/dialog/dialog-13.wxml",
          "target": "components/ui/dialog-13/dialog-13.wxml",
          "type": "registry:component",
          "content": "<view>\n  <dialog><dialogtrigger aschild><button variant=\"outline\">Sign up</button></dialogtrigger><dialogcontent><view class=\"flex flex-col items-center gap-2\"><view class=\"flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><svg class=\"stroke-zinc-800 dark:stroke-zinc-100\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewbox=\"0 0 32 32\" aria-hidden=\"true\"><circle cx=\"16\" cy=\"16\" r=\"12\" fill=\"none\" stroke-width=\"8\" /></svg></view><dialogheader><dialogtitle class=\"sm:text-center\">Sign up Timkit UI</dialogtitle><dialogdescription class=\"sm:text-center\">We just need a few details to get you started.\n            </dialogdescription></dialogheader></view><form class=\"space-y-5\"><view class=\"space-y-4\"><view class=\"*:not-first:mt-2\"><label htmlfor=\"{{`${id}-name`}}\">Full name</label><input id=\"{{`${id}-name`}}\" placeholder=\"Matt Welsh\" type=\"text\" required /></view><view class=\"*:not-first:mt-2\"><label htmlfor=\"{{`${id}-email`}}\">Email</label><input id=\"{{`${id}-email`}}\" placeholder=\"hi@yourcompany.com\" type=\"email\" required /></view><view class=\"*:not-first:mt-2\"><label htmlfor=\"{{`${id}-password`}}\">Password</label><input id=\"{{`${id}-password`}}\" placeholder=\"Enter your password\" type=\"password\" required /></view></view><button type=\"button\" class=\"w-full\">Sign up\n          </button></form><view class=\"before:bg-border after:bg-border flex items-center gap-3 before:h-px before:flex-1 after:h-px after:flex-1\"><text class=\"text-muted-foreground text-xs\">Or</text></view><button variant=\"outline\">Continue with Google</button><text class=\"text-muted-foreground text-center text-xs\">By signing up you agree to our{{ ' ' }}<a class=\"underline hover:no-underline\" href=\"#\">Terms\n          </a>.\n        </text></dialogcontent></dialog>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dialog",
          "modal",
          "signup",
          "authentication",
          "form",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dialog-13",
          "group": "dialog",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dialog-13",
              "path": "registry/default/components/dialog/dialog-13.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dialog-13",
              "path": "registry/default/components/dialog/dialog-13.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dialog-13",
              "path": "registry/default/components/dialog/dialog-13.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dialog-13",
              "path": "registry/default/components/dialog/dialog-13.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dialog",
        "title": "Dialog · Full name"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "dialog"
      ]
    },
    {
      "name": "dialog-14",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/checkbox.json",
        "https://ui.timkit.cn/r/dialog.json",
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/dialog/dialog-14.tsx",
          "type": "registry:component",
          "target": "components/ui/dialog-14.tsx",
          "content": "import { useId } from 'react'\nimport {\n  Button,\n  Checkbox,\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n  Input,\n  Label,\n} from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <Dialog>\n      <DialogTrigger asChild>\n        <Button variant=\"outline\">Sign in</Button>\n      </DialogTrigger>\n      <DialogContent>\n        <div className=\"flex flex-col items-center gap-2\">\n          <div\n            className=\"flex size-11 shrink-0 items-center justify-center rounded-full border\"\n            aria-hidden=\"true\"\n          >\n            <svg\n              className=\"stroke-zinc-800 dark:stroke-zinc-100\"\n              xmlns=\"http://www.w3.org/2000/svg\"\n              width=\"20\"\n              height=\"20\"\n              viewBox=\"0 0 32 32\"\n              aria-hidden=\"true\"\n            >\n              <circle cx=\"16\" cy=\"16\" r=\"12\" fill=\"none\" strokeWidth=\"8\" />\n            </svg>\n          </div>\n          <DialogHeader>\n            <DialogTitle className=\"sm:text-center\">Welcome back</DialogTitle>\n            <DialogDescription className=\"sm:text-center\">\n              Enter your credentials to login to your account.\n            </DialogDescription>\n          </DialogHeader>\n        </div>\n\n        <form className=\"space-y-5\">\n          <div className=\"space-y-4\">\n            <div className=\"*:not-first:mt-2\">\n              <Label htmlFor={`${id}-email`}>Email</Label>\n              <Input id={`${id}-email`} placeholder=\"hi@yourcompany.com\" type=\"email\" required />\n            </div>\n            <div className=\"*:not-first:mt-2\">\n              <Label htmlFor={`${id}-password`}>Password</Label>\n              <Input\n                id={`${id}-password`}\n                placeholder=\"Enter your password\"\n                type=\"password\"\n                required\n              />\n            </div>\n          </div>\n          <div className=\"flex justify-between gap-2\">\n            <div className=\"flex items-center gap-2\">\n              <Checkbox id={`${id}-remember`} />\n              <Label htmlFor={`${id}-remember`} className=\"text-muted-foreground font-normal\">\n                Remember me\n              </Label>\n            </div>\n            <a className=\"text-sm underline hover:no-underline\" href=\"#\">\n              Forgot password?\n            </a>\n          </div>\n          <Button type=\"button\" className=\"w-full\">\n            Sign in\n          </Button>\n        </form>\n\n        <div className=\"before:bg-border after:bg-border flex items-center gap-3 before:h-px before:flex-1 after:h-px after:flex-1\">\n          <span className=\"text-muted-foreground text-xs\">Or</span>\n        </div>\n\n        <Button variant=\"outline\">Login with Google</Button>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-14.vue",
          "target": "components/ui/dialog-14.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\nimport { Checkbox } from '@timui/vue';\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from '@timui/vue';\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'dialog-14';\n\n</script>\n\n<template>\n  <Dialog><DialogTrigger as-child><Button variant=\"outline\">Sign in</Button></DialogTrigger><DialogContent><div class=\"flex flex-col items-center gap-2\"><div class=\"flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><svg class=\"stroke-zinc-800 dark:stroke-zinc-100\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 32 32\" aria-hidden=\"true\"><circle cx=\"16\" cy=\"16\" r=\"12\" fill=\"none\" stroke-width=\"8\" /></svg></div><DialogHeader><DialogTitle class=\"sm:text-center\">Welcome back</DialogTitle><DialogDescription class=\"sm:text-center\">Enter your credentials to login to your account.\n            </DialogDescription></DialogHeader></div><form class=\"space-y-5\"><div class=\"space-y-4\"><div class=\"*:not-first:mt-2\"><Label :htmlFor=\"`${id}-email`\">Email</Label><Input :id=\"`${id}-email`\" placeholder=\"hi@yourcompany.com\" type=\"email\" required /></div><div class=\"*:not-first:mt-2\"><Label :htmlFor=\"`${id}-password`\">Password</Label><Input :id=\"`${id}-password`\" placeholder=\"Enter your password\" type=\"password\" required /></div></div><div class=\"flex justify-between gap-2\"><div class=\"flex items-center gap-2\"><Checkbox :id=\"`${id}-remember`\" /><Label :htmlFor=\"`${id}-remember`\" class=\"text-muted-foreground font-normal\">Remember me\n              </Label></div><a class=\"text-sm underline hover:no-underline\" href=\"#\">Forgot password?\n            </a></div><Button type=\"button\" class=\"w-full\">Sign in\n          </Button></form><div class=\"before:bg-border after:bg-border flex items-center gap-3 before:h-px before:flex-1 after:h-px after:flex-1\"><span class=\"text-muted-foreground text-xs\">Or</span></div><Button variant=\"outline\">Login with Google</Button></DialogContent></Dialog>\n</template>\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-14.html",
          "target": "components/ui/dialog-14.html",
          "type": "registry:component",
          "content": "<template>\n  <Dialog><DialogTrigger aschild><Button variant=\"outline\">Sign in</Button></DialogTrigger><DialogContent><div class=\"flex flex-col items-center gap-2\"><div class=\"flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><svg class=\"stroke-zinc-800 dark:stroke-zinc-100\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewbox=\"0 0 32 32\" aria-hidden=\"true\"><circle cx=\"16\" cy=\"16\" r=\"12\" fill=\"none\" stroke-width=\"8\" /></svg></div><DialogHeader><DialogTitle class=\"sm:text-center\">Welcome back</DialogTitle><DialogDescription class=\"sm:text-center\">Enter your credentials to login to your account.\n            </DialogDescription></DialogHeader></div><form class=\"space-y-5\"><div class=\"space-y-4\"><div class=\"*:not-first:mt-2\"><Label htmlfor=\"${`${id}-email`}\">Email</Label><Input id=\"${`${id}-email`}\" placeholder=\"hi@yourcompany.com\" type=\"email\" required /></div><div class=\"*:not-first:mt-2\"><Label htmlfor=\"${`${id}-password`}\">Password</Label><Input id=\"${`${id}-password`}\" placeholder=\"Enter your password\" type=\"password\" required /></div></div><div class=\"flex justify-between gap-2\"><div class=\"flex items-center gap-2\"><Checkbox id=\"${`${id}-remember`}\" /><Label htmlfor=\"${`${id}-remember`}\" class=\"text-muted-foreground font-normal\">Remember me\n              </Label></div><a class=\"text-sm underline hover:no-underline\" href=\"#\">Forgot password?\n            </a></div><Button type=\"button\" class=\"w-full\">Sign in\n          </Button></form><div class=\"before:bg-border after:bg-border flex items-center gap-3 before:h-px before:flex-1 after:h-px after:flex-1\"><span class=\"text-muted-foreground text-xs\">Or</span></div><Button variant=\"outline\">Login with Google</Button></DialogContent></Dialog>\n</template>"
        },
        {
          "path": "registry/default/components/dialog/dialog-14.wxml",
          "target": "components/ui/dialog-14/dialog-14.wxml",
          "type": "registry:component",
          "content": "<view>\n  <dialog><dialogtrigger aschild><button variant=\"outline\">Sign in</button></dialogtrigger><dialogcontent><view class=\"flex flex-col items-center gap-2\"><view class=\"flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><svg class=\"stroke-zinc-800 dark:stroke-zinc-100\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewbox=\"0 0 32 32\" aria-hidden=\"true\"><circle cx=\"16\" cy=\"16\" r=\"12\" fill=\"none\" stroke-width=\"8\" /></svg></view><dialogheader><dialogtitle class=\"sm:text-center\">Welcome back</dialogtitle><dialogdescription class=\"sm:text-center\">Enter your credentials to login to your account.\n            </dialogdescription></dialogheader></view><form class=\"space-y-5\"><view class=\"space-y-4\"><view class=\"*:not-first:mt-2\"><label htmlfor=\"{{`${id}-email`}}\">Email</label><input id=\"{{`${id}-email`}}\" placeholder=\"hi@yourcompany.com\" type=\"email\" required /></view><view class=\"*:not-first:mt-2\"><label htmlfor=\"{{`${id}-password`}}\">Password</label><input id=\"{{`${id}-password`}}\" placeholder=\"Enter your password\" type=\"password\" required /></view></view><view class=\"flex justify-between gap-2\"><view class=\"flex items-center gap-2\"><checkbox id=\"{{`${id}-remember`}}\" /><label htmlfor=\"{{`${id}-remember`}}\" class=\"text-muted-foreground font-normal\">Remember me\n              </label></view><a class=\"text-sm underline hover:no-underline\" href=\"#\">Forgot password?\n            </a></view><button type=\"button\" class=\"w-full\">Sign in\n          </button></form><view class=\"before:bg-border after:bg-border flex items-center gap-3 before:h-px before:flex-1 after:h-px after:flex-1\"><text class=\"text-muted-foreground text-xs\">Or</text></view><button variant=\"outline\">Login with Google</button></dialogcontent></dialog>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dialog",
          "modal",
          "login",
          "authentication",
          "form",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dialog-14",
          "group": "dialog",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dialog-14",
              "path": "registry/default/components/dialog/dialog-14.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dialog-14",
              "path": "registry/default/components/dialog/dialog-14.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dialog-14",
              "path": "registry/default/components/dialog/dialog-14.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dialog-14",
              "path": "registry/default/components/dialog/dialog-14.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dialog",
        "title": "Dialog · Email"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "dialog"
      ]
    },
    {
      "name": "dialog-15",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dialog.json",
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/tooltip.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/dialog/dialog-15.tsx",
          "type": "registry:component",
          "target": "components/ui/dialog-15.tsx",
          "content": "'use client'\n\nimport { useId, useRef, useState } from 'react'\nimport { cn } from '@timui/core'\nimport {\n  Button,\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n  Input,\n  Label,\n  Tooltip,\n  TooltipContent,\n  TooltipProvider,\n  TooltipTrigger,\n} from '@timui/react'\nimport { CheckIcon, CopyIcon, UserRoundPlusIcon } from 'lucide-react'\n\nexport default function Component() {\n  const id = useId()\n  const [emails, setEmails] = useState(['mark@yourcompany.com', 'jane@yourcompany.com', ''])\n  const [copied, setCopied] = useState<boolean>(false)\n  const inputRef = useRef<HTMLInputElement>(null)\n  const lastInputRef = useRef<HTMLInputElement>(null)\n\n  const addEmail = () => {\n    setEmails([...emails, ''])\n  }\n\n  const handleEmailChange = (index: number, value: string) => {\n    const newEmails = [...emails]\n    newEmails[index] = value\n    setEmails(newEmails)\n  }\n\n  const handleCopy = () => {\n    if (inputRef.current) {\n      navigator.clipboard.writeText(inputRef.current.value)\n      setCopied(true)\n      setTimeout(() => setCopied(false), 1500)\n    }\n  }\n\n  return (\n    <Dialog>\n      <DialogTrigger asChild>\n        <Button variant=\"outline\">Invite members</Button>\n      </DialogTrigger>\n      <DialogContent\n        onOpenAutoFocus={(e) => {\n          e.preventDefault()\n          lastInputRef.current?.focus()\n        }}\n      >\n        <div className=\"flex flex-col gap-2\">\n          <div\n            className=\"flex size-11 shrink-0 items-center justify-center rounded-full border\"\n            aria-hidden=\"true\"\n          >\n            <UserRoundPlusIcon className=\"opacity-80\" size={16} />\n          </div>\n          <DialogHeader>\n            <DialogTitle className=\"text-left\">Invite team members</DialogTitle>\n            <DialogDescription className=\"text-left\">\n              Invite teammates to earn free components.\n            </DialogDescription>\n          </DialogHeader>\n        </div>\n\n        <form className=\"space-y-5\">\n          <div className=\"space-y-4\">\n            <div className=\"*:not-first:mt-2\">\n              <Label>Invite via email</Label>\n              <div className=\"space-y-3\">\n                {emails.map((email, index) => (\n                  <Input\n                    key={index}\n                    id={`team-email-${index + 1}`}\n                    placeholder=\"hi@yourcompany.com\"\n                    type=\"email\"\n                    value={email}\n                    onChange={(e) => handleEmailChange(index, e.target.value)}\n                    ref={index === emails.length - 1 ? lastInputRef : undefined}\n                  />\n                ))}\n              </div>\n            </div>\n            <button\n              type=\"button\"\n              onClick={addEmail}\n              className=\"text-sm underline hover:no-underline\"\n            >\n              + Add another\n            </button>\n          </div>\n          <Button type=\"button\" className=\"w-full\">\n            Send invites\n          </Button>\n        </form>\n\n        <hr className=\"my-1 border-t\" />\n\n        <div className=\"*:not-first:mt-2\">\n          <Label htmlFor={id}>Invite via magic link</Label>\n          <div className=\"relative\">\n            <Input\n              ref={inputRef}\n              id={id}\n              className=\"pe-9\"\n              type=\"text\"\n              defaultValue=\"https://ui.timkit.cn/refer/87689\"\n              readOnly\n            />\n            <TooltipProvider delayDuration={0}>\n              <Tooltip>\n                <TooltipTrigger asChild>\n                  <button\n                    onClick={handleCopy}\n                    className=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed\"\n                    aria-label={copied ? 'Copied' : 'Copy to clipboard'}\n                    disabled={copied}\n                  >\n                    <div\n                      className={cn(\n                        'transition-all',\n                        copied ? 'scale-100 opacity-100' : 'scale-0 opacity-0'\n                      )}\n                    >\n                      <CheckIcon className=\"stroke-emerald-500\" size={16} aria-hidden=\"true\" />\n                    </div>\n                    <div\n                      className={cn(\n                        'absolute transition-all',\n                        copied ? 'scale-0 opacity-0' : 'scale-100 opacity-100'\n                      )}\n                    >\n                      <CopyIcon size={16} aria-hidden=\"true\" />\n                    </div>\n                  </button>\n                </TooltipTrigger>\n                <TooltipContent className=\"px-2 py-1 text-xs\">Copy to clipboard</TooltipContent>\n              </Tooltip>\n            </TooltipProvider>\n          </div>\n        </div>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-15.vue",
          "target": "components/ui/dialog-15.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { cn } from '@timui/core';\nimport { CheckIcon, CopyIcon, UserRoundPlusIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from '@timui/vue';\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\nimport { Tooltip } from '@timui/vue';\nimport { TooltipContent } from '@timui/vue';\nimport { TooltipProvider } from '@timui/vue';\nimport { TooltipTrigger } from '@timui/vue';\n\nconst id = 'dialog-15';\nconst emails = ref(['mark@yourcompany.com', 'jane@yourcompany.com', '']);\nconst copied = ref(false);\nconst magicLink = ref('https://ui.timkit.cn/refer/87689');\n\nfunction addEmail() {\n  emails.value = [...emails.value, ''];\n}\n\nfunction handleEmailChange(index: number, value: string) {\n  const nextEmails = [...emails.value];\n  nextEmails[index] = value;\n  emails.value = nextEmails;\n}\n\nasync function handleCopy() {\n  try {\n    await navigator.clipboard.writeText(magicLink.value);\n    copied.value = true;\n    window.setTimeout(() => {\n      copied.value = false;\n    }, 1500);\n  } catch {\n    copied.value = false;\n  }\n}\n</script>\n\n<template>\n  <Dialog>\n    <DialogTrigger as-child>\n      <Button variant=\"outline\">Invite members</Button>\n    </DialogTrigger>\n    <DialogContent>\n      <div class=\"flex flex-col gap-2\">\n        <div class=\"flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\">\n          <UserRoundPlusIcon class=\"opacity-80\" :size=\"16\" />\n        </div>\n        <DialogHeader>\n          <DialogTitle class=\"text-left\">Invite team members</DialogTitle>\n          <DialogDescription class=\"text-left\">Invite teammates to earn free components.</DialogDescription>\n        </DialogHeader>\n      </div>\n\n      <form class=\"space-y-5\">\n        <div class=\"space-y-4\">\n          <div class=\"*:not-first:mt-2\">\n            <Label>Invite via email</Label>\n            <div class=\"space-y-3\">\n              <Input\n                v-for=\"(email, index) in emails\"\n                :key=\"index\"\n                :id=\"`team-email-${index + 1}`\"\n                placeholder=\"hi@yourcompany.com\"\n                type=\"email\"\n                :model-value=\"email\"\n                @update:modelValue=\"(value) => handleEmailChange(index, String(value ?? ''))\"\n              />\n            </div>\n          </div>\n          <button type=\"button\" @click=\"addEmail\" class=\"text-sm underline hover:no-underline\">+ Add another</button>\n        </div>\n        <Button type=\"button\" class=\"w-full\">Send invites</Button>\n      </form>\n\n      <hr class=\"my-1 border-t\" />\n\n      <div class=\"*:not-first:mt-2\">\n        <Label :htmlFor=\"id\">Invite via magic link</Label>\n        <div class=\"relative\">\n          <Input :id=\"id\" class=\"pe-9\" type=\"text\" v-model=\"magicLink\" readOnly />\n          <TooltipProvider :delayDuration=\"0\">\n            <Tooltip>\n              <TooltipTrigger as-child>\n                <button\n                  @click=\"handleCopy\"\n                  class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed\"\n                  :aria-label=\"copied ? 'Copied' : 'Copy to clipboard'\"\n                  :disabled=\"copied\"\n                >\n                  <div :class=\"cn('transition-all', copied ? 'scale-100 opacity-100' : 'scale-0 opacity-0')\">\n                    <CheckIcon class=\"stroke-emerald-500\" :size=\"16\" aria-hidden=\"true\" />\n                  </div>\n                  <div :class=\"cn('absolute transition-all', copied ? 'scale-0 opacity-0' : 'scale-100 opacity-100')\">\n                    <CopyIcon :size=\"16\" aria-hidden=\"true\" />\n                  </div>\n                </button>\n              </TooltipTrigger>\n              <TooltipContent class=\"px-2 py-1 text-xs\">Copy to clipboard</TooltipContent>\n            </Tooltip>\n          </TooltipProvider>\n        </div>\n      </div>\n    </DialogContent>\n  </Dialog>\n</template>\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-15.html",
          "target": "components/ui/dialog-15.html",
          "type": "registry:component",
          "content": "<template>\n  <Dialog><DialogTrigger aschild><Button variant=\"outline\">Invite members</Button></DialogTrigger><DialogContent onopenautofocus=\"${(e) => {\n          e.preventDefault()\n          lastInputRef.current?.focus()\n        }}\"><div class=\"flex flex-col gap-2\"><div class=\"flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><UserRoundPlusIcon class=\"opacity-80\" size=\"${16}\" /></div><DialogHeader><DialogTitle class=\"text-left\">Invite team members</DialogTitle><DialogDescription class=\"text-left\">Invite teammates to earn free components.\n            </DialogDescription></DialogHeader></div><form class=\"space-y-5\"><div class=\"space-y-4\"><div class=\"*:not-first:mt-2\"><Label>Invite via email</Label><div class=\"space-y-3\"><!-- Loop emails -->\n<Input key=\"${index}\" id=\"${`team-email-${index + 1}`}\" placeholder=\"hi@yourcompany.com\" type=\"email\" value=\"${email}\" onchange=\"${(e) => handleEmailChange(index, e.target.value)}\" ref=\"${index === emails.length - 1 ? lastInputRef : undefined}\" />\n<!-- End Loop --></div></div><button type=\"button\" on-click=\"${addEmail}\" class=\"text-sm underline hover:no-underline\">+ Add another\n            </button></div><Button type=\"button\" class=\"w-full\">Send invites\n          </Button></form><hr class=\"my-1 border-t\" /><div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Invite via magic link</Label><div class=\"relative\"><Input ref=\"${inputRef}\" id=\"${id}\" class=\"pe-9\" type=\"text\" default-value=\"https://ui.timkit.cn/refer/87689\" readonly /><TooltipProvider delayduration=\"${0}\"><Tooltip><TooltipTrigger aschild><button on-click=\"${handleCopy}\" class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed\" aria-label=\"${copied ? 'Copied' : 'Copy to clipboard'}\" disabled=\"${copied}\"><div class=\"${cn(\n                        'transition-all',\n                        copied ? 'scale-100 opacity-100' : 'scale-0 opacity-0'\n                      )}\"><CheckIcon class=\"stroke-emerald-500\" size=\"${16}\" aria-hidden=\"true\" /></div><div class=\"${cn(\n                        'absolute transition-all',\n                        copied ? 'scale-0 opacity-0' : 'scale-100 opacity-100'\n                      )}\"><CopyIcon size=\"${16}\" aria-hidden=\"true\" /></div></button></TooltipTrigger><TooltipContent class=\"px-2 py-1 text-xs\">Copy to clipboard</TooltipContent></Tooltip></TooltipProvider></div></div></DialogContent></Dialog>\n</template>"
        },
        {
          "path": "registry/default/components/dialog/dialog-15.wxml",
          "target": "components/ui/dialog-15/dialog-15.wxml",
          "type": "registry:component",
          "content": "<view>\n  <dialog><dialogtrigger aschild><button variant=\"outline\">Invite members</button></dialogtrigger><dialogcontent onopenautofocus=\"{{(e) => {\n          e.preventDefault()\n          lastInputRef.current?.focus()\n        }}}\"><view class=\"flex flex-col gap-2\"><view class=\"flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><userroundplusicon class=\"opacity-80\" size=\"{{16}}\" /></view><dialogheader><dialogtitle class=\"text-left\">Invite team members</dialogtitle><dialogdescription class=\"text-left\">Invite teammates to earn free components.\n            </dialogdescription></dialogheader></view><form class=\"space-y-5\"><view class=\"space-y-4\"><view class=\"*:not-first:mt-2\"><label>Invite via email</label><view class=\"space-y-3\"><input wx:for=\"{{emails}}\" wx:for-item=\"email\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{index}}\" id=\"{{`team-email-${index + 1}`}}\" placeholder=\"hi@yourcompany.com\" type=\"email\" value=\"{{email}}\" onchange=\"{{(e) => handleEmailChange(index, e.target.value)}}\" ref=\"{{index === emails.length - 1 ? lastInputRef : undefined}}\" /></view></view><button type=\"button\" bindtap=\"addEmail\" class=\"text-sm underline hover:no-underline\">+ Add another\n            </button></view><button type=\"button\" class=\"w-full\">Send invites\n          </button></form><hr class=\"my-1 border-t\" /><view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Invite via magic link</label><view class=\"relative\"><input ref=\"{{inputRef}}\" id=\"{{id}}\" class=\"pe-9\" type=\"text\" default-value=\"https://ui.timkit.cn/refer/87689\" readonly /><tooltipprovider delayduration=\"{{0}}\"><tooltip><tooltiptrigger aschild><button bindtap=\"handleCopy\" class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed\" aria-label=\"{{copied ? 'Copied' : 'Copy to clipboard'}}\" disabled=\"{{copied}}\"><view class=\"{{cn(\n                        'transition-all',\n                        copied ? 'scale-100 opacity-100' : 'scale-0 opacity-0'\n                      )}}\"><checkicon class=\"stroke-emerald-500\" size=\"{{16}}\" aria-hidden=\"true\" /></view><view class=\"{{cn(\n                        'absolute transition-all',\n                        copied ? 'scale-0 opacity-0' : 'scale-100 opacity-100'\n                      )}}\"><copyicon size=\"{{16}}\" aria-hidden=\"true\" /></view></button></tooltiptrigger><tooltipcontent class=\"px-2 py-1 text-xs\">Copy to clipboard</tooltipcontent></tooltip></tooltipprovider></view></view></dialogcontent></dialog>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dialog",
          "modal",
          "form",
          "user",
          "team",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dialog-15",
          "group": "dialog",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dialog-15",
              "path": "registry/default/components/dialog/dialog-15.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dialog-15",
              "path": "registry/default/components/dialog/dialog-15.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dialog-15",
              "path": "registry/default/components/dialog/dialog-15.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dialog-15",
              "path": "registry/default/components/dialog/dialog-15.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dialog",
        "title": "Dialog · Invite via email"
      },
      "dependencies": [
        "@timui/core",
        "@timui/react"
      ],
      "categories": [
        "dialog"
      ]
    },
    {
      "name": "dialog-16",
      "type": "registry:component",
      "dependencies": [
        "@timui/react",
        "react-payment-inputs",
        "react-payment-inputs/images"
      ],
      "devDependencies": [
        "@types/react-payment-inputs"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/checkbox.json",
        "https://ui.timkit.cn/r/dialog.json",
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/dialog/dialog-16.tsx",
          "type": "registry:component",
          "target": "components/ui/dialog-16.tsx",
          "content": "'use client'\n\nimport { useId } from 'react'\nimport {\n  Button,\n  Checkbox,\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n  Input,\n  Label,\n} from '@timui/react'\nimport { CreditCardIcon, WalletIcon } from 'lucide-react'\nimport { usePaymentInputs } from 'react-payment-inputs'\nimport images, { type CardImages } from 'react-payment-inputs/images'\n\nexport default function Component() {\n  const id = useId()\n  const { meta, getCardNumberProps, getExpiryDateProps, getCVCProps, getCardImageProps } =\n    usePaymentInputs()\n\n  return (\n    <Dialog>\n      <DialogTrigger asChild>\n        <Button variant=\"outline\">Card details</Button>\n      </DialogTrigger>\n      <DialogContent>\n        <div className=\"flex flex-col gap-2\">\n          <div\n            className=\"flex size-11 shrink-0 items-center justify-center rounded-full border\"\n            aria-hidden=\"true\"\n          >\n            <WalletIcon className=\"opacity-80\" size={16} />\n          </div>\n          <DialogHeader>\n            <DialogTitle className=\"text-left\">Update your card</DialogTitle>\n            <DialogDescription className=\"text-left\">\n              Your new card will replace your current card.\n            </DialogDescription>\n          </DialogHeader>\n        </div>\n\n        <form className=\"space-y-5\">\n          <div className=\"space-y-4\">\n            <div className=\"*:not-first:mt-2\">\n              <Label htmlFor={`name-${id}`}>Name on card</Label>\n              <Input id={`name-${id}`} type=\"text\" required />\n            </div>\n            <div className=\"*:not-first:mt-2\">\n              <Label htmlFor={`number-${id}`}>Card Number</Label>\n              <div className=\"relative\">\n                <Input\n                  {...getCardNumberProps()}\n                  id={`number-${id}`}\n                  className=\"peer pe-9 [direction:inherit]\"\n                />\n                <div className=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 peer-disabled:opacity-50\">\n                  {meta.cardType ? (\n                    <svg\n                      className=\"overflow-hidden rounded-sm\"\n                      {...getCardImageProps({\n                        images: images as unknown as CardImages,\n                      })}\n                      width={20}\n                    />\n                  ) : (\n                    <CreditCardIcon size={16} aria-hidden=\"true\" />\n                  )}\n                </div>\n              </div>\n            </div>\n            <div className=\"flex gap-4\">\n              <div className=\"flex-1 space-y-2\">\n                <Label htmlFor={`expiry-${id}`}>Expiry date</Label>\n                <Input\n                  className=\"[direction:inherit]\"\n                  {...getExpiryDateProps()}\n                  id={`expiry-${id}`}\n                />\n              </div>\n              <div className=\"flex-1 space-y-2\">\n                <Label htmlFor={`cvc-${id}`}>CVC</Label>\n                <Input className=\"[direction:inherit]\" {...getCVCProps()} id={`cvc-${id}`} />\n              </div>\n            </div>\n          </div>\n          <div className=\"flex items-center gap-2\">\n            <Checkbox id={`primary-${id}`} />\n            <Label htmlFor={`primary-${id}`} className=\"text-muted-foreground font-normal\">\n              Set as default payment method\n            </Label>\n          </div>\n          <Button type=\"button\" className=\"w-full\">\n            Update card\n          </Button>\n        </form>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-16.vue",
          "target": "components/ui/dialog-16.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport { CreditCardIcon, WalletIcon } from 'lucide-vue-next'\nimport { Button } from '@timui/vue'\nimport { Checkbox } from '@timui/vue'\nimport {\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n} from '@timui/vue'\nimport { Input } from '@timui/vue'\nimport { Label } from '@timui/vue'\n\nconst id = 'dialog-16'\nconst cardNumber = ref('')\nconst expiry = ref('')\nconst cvc = ref('')\n\nfunction formatCardNumber(value: string) {\n  const digits = value.replace(/\\D/g, '').slice(0, 19)\n  return digits.replace(/(.{4})/g, '$1 ').trim()\n}\n\nfunction formatExpiry(value: string) {\n  const digits = value.replace(/\\D/g, '').slice(0, 4)\n  if (digits.length <= 2) return digits\n  return `${digits.slice(0, 2)}/${digits.slice(2)}`\n}\n\nfunction detectCardType(value: string) {\n  const digits = value.replace(/\\D/g, '')\n  if (/^4/.test(digits)) return 'visa'\n  if (/^(5[1-5]|2[2-7])/.test(digits)) return 'mastercard'\n  if (/^3[47]/.test(digits)) return 'amex'\n  if (/^6(011|5)/.test(digits)) return 'discover'\n  return null\n}\n\nconst cardType = computed(() => detectCardType(cardNumber.value))\nconst cardTypeLabel = computed(() => {\n  if (!cardType.value) return ''\n  if (cardType.value === 'mastercard') return 'MC'\n  if (cardType.value === 'discover') return 'DISC'\n  return cardType.value.toUpperCase()\n})\n\nfunction onCardNumberChange(value: string | number) {\n  cardNumber.value = formatCardNumber(String(value ?? ''))\n}\n\nfunction onExpiryChange(value: string | number) {\n  expiry.value = formatExpiry(String(value ?? ''))\n}\n\nfunction onCvcChange(value: string | number) {\n  cvc.value = String(value ?? '').replace(/\\D/g, '').slice(0, 4)\n}\n</script>\n\n<template>\n  <Dialog>\n    <DialogTrigger as-child>\n      <Button variant=\"outline\">Card details</Button>\n    </DialogTrigger>\n\n    <DialogContent>\n      <div class=\"flex flex-col gap-2\">\n        <div class=\"flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\">\n          <WalletIcon class=\"opacity-80\" :size=\"16\" />\n        </div>\n        <DialogHeader>\n          <DialogTitle class=\"text-left\">Update your card</DialogTitle>\n          <DialogDescription class=\"text-left\">Your new card will replace your current card.</DialogDescription>\n        </DialogHeader>\n      </div>\n\n      <form class=\"space-y-5\" @submit.prevent>\n        <div class=\"space-y-4\">\n          <div class=\"*:not-first:mt-2\">\n            <Label :htmlFor=\"`name-${id}`\">Name on card</Label>\n            <Input :id=\"`name-${id}`\" type=\"text\" required autocomplete=\"cc-name\" />\n          </div>\n\n          <div class=\"*:not-first:mt-2\">\n            <Label :htmlFor=\"`number-${id}`\">Card Number</Label>\n            <div class=\"relative\">\n              <Input\n                :id=\"`number-${id}`\"\n                class=\"peer pe-9 [direction:inherit]\"\n                inputmode=\"numeric\"\n                autocomplete=\"cc-number\"\n                :modelValue=\"cardNumber\"\n                @update:modelValue=\"onCardNumberChange\"\n              />\n              <div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 peer-disabled:opacity-50\">\n                <span v-if=\"cardTypeLabel\" class=\"text-[10px] font-medium tracking-wide\">{{ cardTypeLabel }}</span>\n                <CreditCardIcon v-else :size=\"16\" aria-hidden=\"true\" />\n              </div>\n            </div>\n          </div>\n\n          <div class=\"flex gap-4\">\n            <div class=\"flex-1 space-y-2\">\n              <Label :htmlFor=\"`expiry-${id}`\">Expiry date</Label>\n              <Input\n                class=\"[direction:inherit]\"\n                :id=\"`expiry-${id}`\"\n                inputmode=\"numeric\"\n                autocomplete=\"cc-exp\"\n                placeholder=\"MM/YY\"\n                :modelValue=\"expiry\"\n                @update:modelValue=\"onExpiryChange\"\n              />\n            </div>\n            <div class=\"flex-1 space-y-2\">\n              <Label :htmlFor=\"`cvc-${id}`\">CVC</Label>\n              <Input\n                class=\"[direction:inherit]\"\n                :id=\"`cvc-${id}`\"\n                inputmode=\"numeric\"\n                autocomplete=\"cc-csc\"\n                :modelValue=\"cvc\"\n                @update:modelValue=\"onCvcChange\"\n              />\n            </div>\n          </div>\n        </div>\n\n        <div class=\"flex items-center gap-2\">\n          <Checkbox :id=\"`primary-${id}`\" />\n          <Label :htmlFor=\"`primary-${id}`\" class=\"text-muted-foreground font-normal\">\n            Set as default payment method\n          </Label>\n        </div>\n\n        <Button type=\"button\" class=\"w-full\">Update card</Button>\n      </form>\n    </DialogContent>\n  </Dialog>\n</template>\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-16.html",
          "target": "components/ui/dialog-16.html",
          "type": "registry:component",
          "content": "<template>\n  <Dialog><DialogTrigger aschild><Button variant=\"outline\">Card details</Button></DialogTrigger><DialogContent><div class=\"flex flex-col gap-2\"><div class=\"flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><WalletIcon class=\"opacity-80\" size=\"${16}\" /></div><DialogHeader><DialogTitle class=\"text-left\">Update your card</DialogTitle><DialogDescription class=\"text-left\">Your new card will replace your current card.\n            </DialogDescription></DialogHeader></div><form class=\"space-y-5\"><div class=\"space-y-4\"><div class=\"*:not-first:mt-2\"><Label htmlfor=\"${`name-${id}`}\">Name on card</Label><Input id=\"${`name-${id}`}\" type=\"text\" required /></div><div class=\"*:not-first:mt-2\"><Label htmlfor=\"${`number-${id}`}\">Card Number</Label><div class=\"relative\"><Input id=\"${`number-${id}`}\" class=\"peer pe-9 [direction:inherit]\" /><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 peer-disabled:opacity-50\"><!-- if meta.cardType -->\n<svg class=\"overflow-hidden rounded-sm\" width=\"${20}\" />\n<!-- else -->\n<CreditCardIcon size=\"${16}\" aria-hidden=\"true\" />\n<!-- endif --></div></div></div><div class=\"flex gap-4\"><div class=\"flex-1 space-y-2\"><Label htmlfor=\"${`expiry-${id}`}\">Expiry date</Label><Input class=\"[direction:inherit]\" id=\"${`expiry-${id}`}\" /></div><div class=\"flex-1 space-y-2\"><Label htmlfor=\"${`cvc-${id}`}\">CVC</Label><Input class=\"[direction:inherit]\" id=\"${`cvc-${id}`}\" /></div></div></div><div class=\"flex items-center gap-2\"><Checkbox id=\"${`primary-${id}`}\" /><Label htmlfor=\"${`primary-${id}`}\" class=\"text-muted-foreground font-normal\">Set as default payment method\n            </Label></div><Button type=\"button\" class=\"w-full\">Update card\n          </Button></form></DialogContent></Dialog>\n</template>"
        },
        {
          "path": "registry/default/components/dialog/dialog-16.wxml",
          "target": "components/ui/dialog-16/dialog-16.wxml",
          "type": "registry:component",
          "content": "<view>\n  <dialog><dialogtrigger aschild><button variant=\"outline\">Card details</button></dialogtrigger><dialogcontent><view class=\"flex flex-col gap-2\"><view class=\"flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><walleticon class=\"opacity-80\" size=\"{{16}}\" /></view><dialogheader><dialogtitle class=\"text-left\">Update your card</dialogtitle><dialogdescription class=\"text-left\">Your new card will replace your current card.\n            </dialogdescription></dialogheader></view><form class=\"space-y-5\"><view class=\"space-y-4\"><view class=\"*:not-first:mt-2\"><label htmlfor=\"{{`name-${id}`}}\">Name on card</label><input id=\"{{`name-${id}`}}\" type=\"text\" required /></view><view class=\"*:not-first:mt-2\"><label htmlfor=\"{{`number-${id}`}}\">Card Number</label><view class=\"relative\"><input id=\"{{`number-${id}`}}\" class=\"peer pe-9 [direction:inherit]\" /><view class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 peer-disabled:opacity-50\"><block wx:if=\"{{meta.cardType}}\">\n<svg class=\"overflow-hidden rounded-sm\" width=\"{{20}}\" />\n</block>\n<block wx:else>\n<creditcardicon size=\"{{16}}\" aria-hidden=\"true\" />\n</block></view></view></view><view class=\"flex gap-4\"><view class=\"flex-1 space-y-2\"><label htmlfor=\"{{`expiry-${id}`}}\">Expiry date</label><input class=\"[direction:inherit]\" id=\"{{`expiry-${id}`}}\" /></view><view class=\"flex-1 space-y-2\"><label htmlfor=\"{{`cvc-${id}`}}\">CVC</label><input class=\"[direction:inherit]\" id=\"{{`cvc-${id}`}}\" /></view></view></view><view class=\"flex items-center gap-2\"><checkbox id=\"{{`primary-${id}`}}\" /><label htmlfor=\"{{`primary-${id}`}}\" class=\"text-muted-foreground font-normal\">Set as default payment method\n            </label></view><button type=\"button\" class=\"w-full\">Update card\n          </button></form></dialogcontent></dialog>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dialog",
          "modal",
          "checkout",
          "payment",
          "credit card",
          "form",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dialog-16",
          "group": "dialog",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dialog-16",
              "path": "registry/default/components/dialog/dialog-16.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dialog-16",
              "path": "registry/default/components/dialog/dialog-16.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dialog-16",
              "path": "registry/default/components/dialog/dialog-16.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dialog-16",
              "path": "registry/default/components/dialog/dialog-16.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react",
              "react-payment-inputs",
              "react-payment-inputs/images"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dialog",
        "title": "Dialog · Name on card"
      },
      "categories": [
        "dialog"
      ]
    },
    {
      "name": "dialog-17",
      "type": "registry:component",
      "dependencies": [
        "@timui/react",
        "react-payment-inputs",
        "react-payment-inputs/images"
      ],
      "devDependencies": [
        "@types/react-payment-inputs"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/badge.json",
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dialog.json",
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/radio-group.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/dialog/dialog-17.tsx",
          "type": "registry:component",
          "target": "components/ui/dialog-17.tsx",
          "content": "'use client'\n\nimport { useEffect, useId, useRef, useState } from 'react'\nimport {\n  Badge,\n  Button,\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n  Input,\n  Label,\n  RadioGroup,\n  RadioGroupItem,\n} from '@timui/react'\nimport { CreditCardIcon, StoreIcon } from 'lucide-react'\nimport { usePaymentInputs } from 'react-payment-inputs'\nimport images, { type CardImages } from 'react-payment-inputs/images'\n\nexport default function Component() {\n  const id = useId()\n  const { meta, getCardNumberProps, getExpiryDateProps, getCVCProps, getCardImageProps } =\n    usePaymentInputs()\n  const couponInputRef = useRef<HTMLInputElement>(null)\n  const [showCouponInput, setShowCouponInput] = useState(false)\n  const [couponCode, setCouponCode] = useState('')\n\n  // Auto-focus the coupon input when it's shown\n  useEffect(() => {\n    if (showCouponInput && couponInputRef.current) {\n      couponInputRef.current.focus()\n    }\n  }, [showCouponInput])\n\n  return (\n    <Dialog>\n      <DialogTrigger asChild>\n        <Button variant=\"outline\">Checkout</Button>\n      </DialogTrigger>\n      <DialogContent>\n        <div className=\"mb-2 flex flex-col gap-2\">\n          <div\n            className=\"flex size-11 shrink-0 items-center justify-center rounded-full border\"\n            aria-hidden=\"true\"\n          >\n            <StoreIcon className=\"opacity-80\" size={16} />\n          </div>\n          <DialogHeader>\n            <DialogTitle className=\"text-left\">Confirm and pay</DialogTitle>\n            <DialogDescription className=\"text-left\">\n              Pay securely and cancel any time.\n            </DialogDescription>\n          </DialogHeader>\n        </div>\n\n        <form className=\"space-y-5\">\n          <div className=\"space-y-4\">\n            <RadioGroup className=\"grid-cols-2\" defaultValue=\"yearly\">\n              {/* Monthly */}\n              <label className=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex cursor-pointer flex-col gap-1 rounded-md border px-4 py-3 shadow-xs transition-[color,box-shadow] outline-none has-focus-visible:ring-[3px]\">\n                <RadioGroupItem\n                  id=\"radio-monthly\"\n                  value=\"monthly\"\n                  className=\"sr-only after:absolute after:inset-0\"\n                />\n                <p className=\"text-foreground text-sm font-medium\">Monthly</p>\n                <p className=\"text-muted-foreground text-sm\">$32/month</p>\n              </label>\n              {/* Yearly */}\n              <label className=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex cursor-pointer flex-col gap-1 rounded-md border px-4 py-3 shadow-xs transition-[color,box-shadow] outline-none has-focus-visible:ring-[3px]\">\n                <RadioGroupItem\n                  id=\"radio-yearly\"\n                  value=\"yearly\"\n                  className=\"sr-only after:absolute after:inset-0\"\n                />\n                <div className=\"inline-flex items-start justify-between gap-2\">\n                  <p className=\"text-foreground text-sm font-medium\">Yearly</p>\n                  <Badge>Popular</Badge>\n                </div>\n                <p className=\"text-muted-foreground text-sm\">$320/month</p>\n              </label>\n            </RadioGroup>\n            <div className=\"*:not-first:mt-2\">\n              <Label htmlFor={`name-${id}`}>Name on card</Label>\n              <Input id={`name-${id}`} type=\"text\" required />\n            </div>\n            <div className=\"*:not-first:mt-2\">\n              <legend className=\"text-foreground text-sm font-medium\">Card Details</legend>\n              <div className=\"rounded-md shadow-xs\">\n                <div className=\"relative focus-within:z-10\">\n                  <Input\n                    className=\"peer rounded-b-none pe-9 shadow-none [direction:inherit]\"\n                    {...getCardNumberProps()}\n                  />\n                  <div className=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 peer-disabled:opacity-50\">\n                    {meta.cardType ? (\n                      <svg\n                        className=\"overflow-hidden rounded-sm\"\n                        {...getCardImageProps({\n                          images: images as unknown as CardImages,\n                        })}\n                        width={20}\n                      />\n                    ) : (\n                      <CreditCardIcon size={16} aria-hidden=\"true\" />\n                    )}\n                  </div>\n                </div>\n                <div className=\"-mt-px flex\">\n                  <div className=\"min-w-0 flex-1 focus-within:z-10\">\n                    <Input\n                      className=\"rounded-e-none rounded-t-none shadow-none [direction:inherit]\"\n                      {...getExpiryDateProps()}\n                    />\n                  </div>\n                  <div className=\"-ms-px min-w-0 flex-1 focus-within:z-10\">\n                    <Input\n                      className=\"rounded-s-none rounded-t-none shadow-none [direction:inherit]\"\n                      {...getCVCProps()}\n                    />\n                  </div>\n                </div>\n              </div>\n            </div>\n            {!showCouponInput ? (\n              <button\n                type=\"button\"\n                onClick={() => setShowCouponInput(true)}\n                className=\"text-sm underline hover:no-underline\"\n              >\n                + Add coupon\n              </button>\n            ) : (\n              <div className=\"*:not-first:mt-2\">\n                <Label htmlFor={`coupon-${id}`}>Coupon code</Label>\n                <Input\n                  id={`coupon-${id}`}\n                  ref={couponInputRef}\n                  placeholder=\"Enter your code\"\n                  value={couponCode}\n                  onChange={(e) => setCouponCode(e.target.value)}\n                />\n              </div>\n            )}\n          </div>\n          <Button type=\"button\" className=\"w-full\">\n            Subscribe\n          </Button>\n        </form>\n\n        <p className=\"text-muted-foreground text-center text-xs\">\n          Payments are non-refundable. Cancel anytime.\n        </p>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-17.vue",
          "target": "components/ui/dialog-17.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { CreditCardIcon, StoreIcon } from 'lucide-vue-next';\nimport { Badge } from '@timui/vue';\nimport { Button } from '@timui/vue';\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from '@timui/vue';\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\nimport { RadioGroup } from '@timui/vue';\nimport { RadioGroupItem } from '@timui/vue';\n\nconst id = 'dialog-17';\nconst showCouponInput = ref(false);\nconst couponCode = ref('');\n</script>\n\n<template>\n  <Dialog>\n    <DialogTrigger as-child>\n      <Button variant=\"outline\">Checkout</Button>\n    </DialogTrigger>\n    <DialogContent>\n      <div class=\"mb-2 flex flex-col gap-2\">\n        <div class=\"flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\">\n          <StoreIcon class=\"opacity-80\" :size=\"16\" />\n        </div>\n        <DialogHeader>\n          <DialogTitle class=\"text-left\">Confirm and pay</DialogTitle>\n          <DialogDescription class=\"text-left\">Pay securely and cancel any time.</DialogDescription>\n        </DialogHeader>\n      </div>\n\n      <form class=\"space-y-5\">\n        <div class=\"space-y-4\">\n          <RadioGroup class=\"grid-cols-2\" default-value=\"yearly\">\n            <label class=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex cursor-pointer flex-col gap-1 rounded-md border px-4 py-3 shadow-xs transition-[color,box-shadow] outline-none has-focus-visible:ring-[3px]\">\n              <RadioGroupItem id=\"radio-monthly\" value=\"monthly\" class=\"sr-only after:absolute after:inset-0\" />\n              <p class=\"text-foreground text-sm font-medium\">Monthly</p>\n              <p class=\"text-muted-foreground text-sm\">$32/month</p>\n            </label>\n            <label class=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex cursor-pointer flex-col gap-1 rounded-md border px-4 py-3 shadow-xs transition-[color,box-shadow] outline-none has-focus-visible:ring-[3px]\">\n              <RadioGroupItem id=\"radio-yearly\" value=\"yearly\" class=\"sr-only after:absolute after:inset-0\" />\n              <div class=\"inline-flex items-start justify-between gap-2\">\n                <p class=\"text-foreground text-sm font-medium\">Yearly</p>\n                <Badge>Popular</Badge>\n              </div>\n              <p class=\"text-muted-foreground text-sm\">$320/month</p>\n            </label>\n          </RadioGroup>\n\n          <div class=\"*:not-first:mt-2\">\n            <Label :htmlFor=\"`name-${id}`\">Name on card</Label>\n            <Input :id=\"`name-${id}`\" type=\"text\" required />\n          </div>\n\n          <div class=\"*:not-first:mt-2\">\n            <legend class=\"text-foreground text-sm font-medium\">Card Details</legend>\n            <div class=\"rounded-md shadow-xs\">\n              <div class=\"relative focus-within:z-10\">\n                <Input class=\"peer rounded-b-none pe-9 shadow-none\" placeholder=\"Card number\" />\n                <div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 peer-disabled:opacity-50\">\n                  <CreditCardIcon :size=\"16\" aria-hidden=\"true\" />\n                </div>\n              </div>\n              <div class=\"-mt-px flex\">\n                <div class=\"min-w-0 flex-1 focus-within:z-10\">\n                  <Input class=\"rounded-e-none rounded-t-none shadow-none\" placeholder=\"MM/YY\" />\n                </div>\n                <div class=\"-ms-px min-w-0 flex-1 focus-within:z-10\">\n                  <Input class=\"rounded-s-none rounded-t-none shadow-none\" placeholder=\"CVC\" />\n                </div>\n              </div>\n            </div>\n          </div>\n\n          <template v-if=\"!showCouponInput\">\n            <button type=\"button\" @click=\"showCouponInput = true\" class=\"text-sm underline hover:no-underline\">+ Add coupon</button>\n          </template>\n          <template v-else>\n            <div class=\"*:not-first:mt-2\">\n              <Label :htmlFor=\"`coupon-${id}`\">Coupon code</Label>\n              <Input :id=\"`coupon-${id}`\" placeholder=\"Enter your code\" v-model=\"couponCode\" />\n            </div>\n          </template>\n        </div>\n\n        <Button type=\"button\" class=\"w-full\">Subscribe</Button>\n      </form>\n\n      <p class=\"text-muted-foreground text-center text-xs\">Payments are non-refundable. Cancel anytime.</p>\n    </DialogContent>\n  </Dialog>\n</template>\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-17.html",
          "target": "components/ui/dialog-17.html",
          "type": "registry:component",
          "content": "<template>\n  <Dialog><DialogTrigger aschild><Button variant=\"outline\">Checkout</Button></DialogTrigger><DialogContent><div class=\"mb-2 flex flex-col gap-2\"><div class=\"flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><StoreIcon class=\"opacity-80\" size=\"${16}\" /></div><DialogHeader><DialogTitle class=\"text-left\">Confirm and pay</DialogTitle><DialogDescription class=\"text-left\">Pay securely and cancel any time.\n            </DialogDescription></DialogHeader></div><form class=\"space-y-5\"><div class=\"space-y-4\"><RadioGroup class=\"grid-cols-2\" default-value=\"yearly\"><label class=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex cursor-pointer flex-col gap-1 rounded-md border px-4 py-3 shadow-xs transition-[color,box-shadow] outline-none has-focus-visible:ring-[3px]\"><RadioGroupItem id=\"radio-monthly\" value=\"monthly\" class=\"sr-only after:absolute after:inset-0\" /><p class=\"text-foreground text-sm font-medium\">Monthly</p><p class=\"text-muted-foreground text-sm\">$32/month</p></label><label class=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex cursor-pointer flex-col gap-1 rounded-md border px-4 py-3 shadow-xs transition-[color,box-shadow] outline-none has-focus-visible:ring-[3px]\"><RadioGroupItem id=\"radio-yearly\" value=\"yearly\" class=\"sr-only after:absolute after:inset-0\" /><div class=\"inline-flex items-start justify-between gap-2\"><p class=\"text-foreground text-sm font-medium\">Yearly</p><Badge>Popular</Badge></div><p class=\"text-muted-foreground text-sm\">$320/month</p></label></RadioGroup><div class=\"*:not-first:mt-2\"><Label htmlfor=\"${`name-${id}`}\">Name on card</Label><Input id=\"${`name-${id}`}\" type=\"text\" required /></div><div class=\"*:not-first:mt-2\"><legend class=\"text-foreground text-sm font-medium\">Card Details</legend><div class=\"rounded-md shadow-xs\"><div class=\"relative focus-within:z-10\"><Input class=\"peer rounded-b-none pe-9 shadow-none [direction:inherit]\" /><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 peer-disabled:opacity-50\"><!-- if meta.cardType -->\n<svg class=\"overflow-hidden rounded-sm\" width=\"${20}\" />\n<!-- else -->\n<CreditCardIcon size=\"${16}\" aria-hidden=\"true\" />\n<!-- endif --></div></div><div class=\"-mt-px flex\"><div class=\"min-w-0 flex-1 focus-within:z-10\"><Input class=\"rounded-e-none rounded-t-none shadow-none [direction:inherit]\" /></div><div class=\"-ms-px min-w-0 flex-1 focus-within:z-10\"><Input class=\"rounded-s-none rounded-t-none shadow-none [direction:inherit]\" /></div></div></div></div><!-- if !showCouponInput -->\n<button type=\"button\" on-click=\"${() => setShowCouponInput(true)}\" class=\"text-sm underline hover:no-underline\">+ Add coupon\n              </button>\n<!-- else -->\n<div class=\"*:not-first:mt-2\"><Label htmlfor=\"${`coupon-${id}`}\">Coupon code</Label><Input id=\"${`coupon-${id}`}\" ref=\"${couponInputRef}\" placeholder=\"Enter your code\" value=\"${couponCode}\" onchange=\"${(e) => setCouponCode(e.target.value)}\" /></div>\n<!-- endif --></div><Button type=\"button\" class=\"w-full\">Subscribe\n          </Button></form><p class=\"text-muted-foreground text-center text-xs\">Payments are non-refundable. Cancel anytime.\n        </p></DialogContent></Dialog>\n</template>"
        },
        {
          "path": "registry/default/components/dialog/dialog-17.wxml",
          "target": "components/ui/dialog-17/dialog-17.wxml",
          "type": "registry:component",
          "content": "<view>\n  <dialog><dialogtrigger aschild><button variant=\"outline\">Checkout</button></dialogtrigger><dialogcontent><view class=\"mb-2 flex flex-col gap-2\"><view class=\"flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><storeicon class=\"opacity-80\" size=\"{{16}}\" /></view><dialogheader><dialogtitle class=\"text-left\">Confirm and pay</dialogtitle><dialogdescription class=\"text-left\">Pay securely and cancel any time.\n            </dialogdescription></dialogheader></view><form class=\"space-y-5\"><view class=\"space-y-4\"><radiogroup class=\"grid-cols-2\" default-value=\"yearly\"><label class=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex cursor-pointer flex-col gap-1 rounded-md border px-4 py-3 shadow-xs transition-[color,box-shadow] outline-none has-focus-visible:ring-[3px]\"><radiogroupitem id=\"radio-monthly\" value=\"monthly\" class=\"sr-only after:absolute after:inset-0\" /><text class=\"text-foreground text-sm font-medium\">Monthly</text><text class=\"text-muted-foreground text-sm\">$32/month</text></label><label class=\"border-input has-data-[state=checked]:border-primary/50 has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative flex cursor-pointer flex-col gap-1 rounded-md border px-4 py-3 shadow-xs transition-[color,box-shadow] outline-none has-focus-visible:ring-[3px]\"><radiogroupitem id=\"radio-yearly\" value=\"yearly\" class=\"sr-only after:absolute after:inset-0\" /><view class=\"inline-flex items-start justify-between gap-2\"><text class=\"text-foreground text-sm font-medium\">Yearly</text><badge>Popular</badge></view><text class=\"text-muted-foreground text-sm\">$320/month</text></label></radiogroup><view class=\"*:not-first:mt-2\"><label htmlfor=\"{{`name-${id}`}}\">Name on card</label><input id=\"{{`name-${id}`}}\" type=\"text\" required /></view><view class=\"*:not-first:mt-2\"><legend class=\"text-foreground text-sm font-medium\">Card Details</legend><view class=\"rounded-md shadow-xs\"><view class=\"relative focus-within:z-10\"><input class=\"peer rounded-b-none pe-9 shadow-none [direction:inherit]\" /><view class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 peer-disabled:opacity-50\"><block wx:if=\"{{meta.cardType}}\">\n<svg class=\"overflow-hidden rounded-sm\" width=\"{{20}}\" />\n</block>\n<block wx:else>\n<creditcardicon size=\"{{16}}\" aria-hidden=\"true\" />\n</block></view></view><view class=\"-mt-px flex\"><view class=\"min-w-0 flex-1 focus-within:z-10\"><input class=\"rounded-e-none rounded-t-none shadow-none [direction:inherit]\" /></view><view class=\"-ms-px min-w-0 flex-1 focus-within:z-10\"><input class=\"rounded-s-none rounded-t-none shadow-none [direction:inherit]\" /></view></view></view></view><block wx:if=\"{{!showCouponInput}}\">\n<button type=\"button\" bindtap=\"setShowCouponInput(true)\" class=\"text-sm underline hover:no-underline\">+ Add coupon\n              </button>\n</block>\n<block wx:else>\n<view class=\"*:not-first:mt-2\"><label htmlfor=\"{{`coupon-${id}`}}\">Coupon code</label><input id=\"{{`coupon-${id}`}}\" ref=\"{{couponInputRef}}\" placeholder=\"Enter your code\" value=\"{{couponCode}}\" onchange=\"{{(e) => setCouponCode(e.target.value)}}\" /></view>\n</block></view><button type=\"button\" class=\"w-full\">Subscribe\n          </button></form><text class=\"text-muted-foreground text-center text-xs\">Payments are non-refundable. Cancel anytime.\n        </text></dialogcontent></dialog>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dialog",
          "modal",
          "checkout",
          "payment",
          "credit card",
          "form",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dialog-17",
          "group": "dialog",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dialog-17",
              "path": "registry/default/components/dialog/dialog-17.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dialog-17",
              "path": "registry/default/components/dialog/dialog-17.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dialog-17",
              "path": "registry/default/components/dialog/dialog-17.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dialog-17",
              "path": "registry/default/components/dialog/dialog-17.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react",
              "react-payment-inputs",
              "react-payment-inputs/images"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dialog",
        "title": "Dialog · Name on card"
      },
      "categories": [
        "dialog"
      ]
    },
    {
      "name": "dialog-18",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dialog.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/radio-group.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/dialog/dialog-18.tsx",
          "type": "registry:component",
          "target": "components/ui/dialog-18.tsx",
          "content": "import { useId } from 'react'\nimport {\n  Button,\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n  Label,\n  RadioGroup,\n  RadioGroupItem,\n} from '@timui/react'\nimport { CheckIcon, RefreshCcwIcon } from 'lucide-react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <Dialog>\n      <DialogTrigger asChild>\n        <Button variant=\"outline\">Change plan</Button>\n      </DialogTrigger>\n      <DialogContent>\n        <div className=\"mb-2 flex flex-col gap-2\">\n          <div\n            className=\"flex size-11 shrink-0 items-center justify-center rounded-full border\"\n            aria-hidden=\"true\"\n          >\n            <RefreshCcwIcon className=\"opacity-80\" size={16} />\n          </div>\n          <DialogHeader>\n            <DialogTitle className=\"text-left\">Change your plan</DialogTitle>\n            <DialogDescription className=\"text-left\">\n              Pick one of the following plans.\n            </DialogDescription>\n          </DialogHeader>\n        </div>\n\n        <form className=\"space-y-5\">\n          <RadioGroup className=\"gap-2\" defaultValue=\"2\">\n            {/* Radio card #1 */}\n            <div className=\"border-input has-data-[state=checked]:border-primary/50 has-data-[state=checked]:bg-accent relative flex w-full items-center gap-2 rounded-md border px-4 py-3 shadow-xs outline-none\">\n              <RadioGroupItem\n                value=\"1\"\n                id={`${id}-1`}\n                aria-describedby={`${id}-1-description`}\n                className=\"order-1 after:absolute after:inset-0\"\n              />\n              <div className=\"grid grow gap-1\">\n                <Label htmlFor={`${id}-1`}>Essential</Label>\n                <p id={`${id}-1-description`} className=\"text-muted-foreground text-xs\">\n                  $4 per member/month\n                </p>\n              </div>\n            </div>\n            {/* Radio card #2 */}\n            <div className=\"border-input has-data-[state=checked]:border-primary/50 has-data-[state=checked]:bg-accent relative flex w-full items-center gap-2 rounded-md border px-4 py-3 shadow-xs outline-none\">\n              <RadioGroupItem\n                value=\"2\"\n                id={`${id}-2`}\n                aria-describedby={`${id}-2-description`}\n                className=\"order-1 after:absolute after:inset-0\"\n              />\n              <div className=\"grid grow gap-1\">\n                <Label htmlFor={`${id}-2`}>Standard</Label>\n                <p id={`${id}-2-description`} className=\"text-muted-foreground text-xs\">\n                  $19 per member/month\n                </p>\n              </div>\n            </div>\n            {/* Radio card #3 */}\n            <div className=\"border-input has-data-[state=checked]:border-primary/50 has-data-[state=checked]:bg-accent relative flex w-full items-center gap-2 rounded-md border px-4 py-3 shadow-xs outline-none\">\n              <RadioGroupItem\n                value=\"3\"\n                id={`${id}-3`}\n                aria-describedby={`${id}-3-description`}\n                className=\"order-1 after:absolute after:inset-0\"\n              />\n              <div className=\"grid grow gap-1\">\n                <Label htmlFor={`${id}-3`}>Enterprise</Label>\n                <p id={`${id}-3-description`} className=\"text-muted-foreground text-xs\">\n                  $32 per member/month\n                </p>\n              </div>\n            </div>\n          </RadioGroup>\n\n          <div className=\"space-y-3\">\n            <p>\n              <strong className=\"text-sm font-medium\">Features include:</strong>\n            </p>\n            <ul className=\"text-muted-foreground space-y-2 text-sm\">\n              <li className=\"flex gap-2\">\n                <CheckIcon size={16} className=\"text-primary mt-0.5 shrink-0\" aria-hidden=\"true\" />\n                Create unlimited projects.\n              </li>\n              <li className=\"flex gap-2\">\n                <CheckIcon size={16} className=\"text-primary mt-0.5 shrink-0\" aria-hidden=\"true\" />\n                Remove watermarks.\n              </li>\n              <li className=\"flex gap-2\">\n                <CheckIcon size={16} className=\"text-primary mt-0.5 shrink-0\" aria-hidden=\"true\" />\n                Add unlimited users and free viewers.\n              </li>\n              <li className=\"flex gap-2\">\n                <CheckIcon size={16} className=\"text-primary mt-0.5 shrink-0\" aria-hidden=\"true\" />\n                Upload unlimited files.\n              </li>\n              <li className=\"flex gap-2\">\n                <CheckIcon size={16} className=\"text-primary mt-0.5 shrink-0\" aria-hidden=\"true\" />\n                7-day money back guarantee.\n              </li>\n              <li className=\"flex gap-2\">\n                <CheckIcon size={16} className=\"text-primary mt-0.5 shrink-0\" aria-hidden=\"true\" />\n                Advanced permissions.\n              </li>\n            </ul>\n          </div>\n\n          <div className=\"grid gap-2\">\n            <Button type=\"button\" className=\"w-full\">\n              Change plan\n            </Button>\n            <DialogClose asChild>\n              <Button type=\"button\" variant=\"ghost\" className=\"w-full\">\n                Cancel\n              </Button>\n            </DialogClose>\n          </div>\n        </form>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-18.vue",
          "target": "components/ui/dialog-18.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { CheckIcon, RefreshCcwIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { Dialog, DialogClose, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from '@timui/vue';\nimport { Label } from '@timui/vue';\nimport { RadioGroup } from '@timui/vue';\nimport { RadioGroupItem } from '@timui/vue';\n\n\n\n\n\nconst id = 'dialog-18';\n\n</script>\n\n<template>\n  <Dialog><DialogTrigger as-child><Button variant=\"outline\">Change plan</Button></DialogTrigger><DialogContent><div class=\"mb-2 flex flex-col gap-2\"><div class=\"flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><RefreshCcwIcon class=\"opacity-80\" :size=\"16\" /></div><DialogHeader><DialogTitle class=\"text-left\">Change your plan</DialogTitle><DialogDescription class=\"text-left\">Pick one of the following plans.\n            </DialogDescription></DialogHeader></div><form class=\"space-y-5\"><RadioGroup class=\"gap-2\" default-value=\"2\"><div class=\"border-input has-data-[state=checked]:border-primary/50 has-data-[state=checked]:bg-accent relative flex w-full items-center gap-2 rounded-md border px-4 py-3 shadow-xs outline-none\"><RadioGroupItem value=\"1\" :id=\"`${id}-1`\" :aria-describedby=\"`${id}-1-description`\" class=\"order-1 after:absolute after:inset-0\" /><div class=\"grid grow gap-1\"><Label :htmlFor=\"`${id}-1`\">Essential</Label><p :id=\"`${id}-1-description`\" class=\"text-muted-foreground text-xs\">$4 per member/month\n                </p></div></div><div class=\"border-input has-data-[state=checked]:border-primary/50 has-data-[state=checked]:bg-accent relative flex w-full items-center gap-2 rounded-md border px-4 py-3 shadow-xs outline-none\"><RadioGroupItem value=\"2\" :id=\"`${id}-2`\" :aria-describedby=\"`${id}-2-description`\" class=\"order-1 after:absolute after:inset-0\" /><div class=\"grid grow gap-1\"><Label :htmlFor=\"`${id}-2`\">Standard</Label><p :id=\"`${id}-2-description`\" class=\"text-muted-foreground text-xs\">$19 per member/month\n                </p></div></div><div class=\"border-input has-data-[state=checked]:border-primary/50 has-data-[state=checked]:bg-accent relative flex w-full items-center gap-2 rounded-md border px-4 py-3 shadow-xs outline-none\"><RadioGroupItem value=\"3\" :id=\"`${id}-3`\" :aria-describedby=\"`${id}-3-description`\" class=\"order-1 after:absolute after:inset-0\" /><div class=\"grid grow gap-1\"><Label :htmlFor=\"`${id}-3`\">Enterprise</Label><p :id=\"`${id}-3-description`\" class=\"text-muted-foreground text-xs\">$32 per member/month\n                </p></div></div></RadioGroup><div class=\"space-y-3\"><p><strong class=\"text-sm font-medium\">Features include:</strong></p><ul class=\"text-muted-foreground space-y-2 text-sm\"><li class=\"flex gap-2\"><CheckIcon :size=\"16\" class=\"text-primary mt-0.5 shrink-0\" aria-hidden=\"true\" />Create unlimited projects.\n              </li><li class=\"flex gap-2\"><CheckIcon :size=\"16\" class=\"text-primary mt-0.5 shrink-0\" aria-hidden=\"true\" />Remove watermarks.\n              </li><li class=\"flex gap-2\"><CheckIcon :size=\"16\" class=\"text-primary mt-0.5 shrink-0\" aria-hidden=\"true\" />Add unlimited users and free viewers.\n              </li><li class=\"flex gap-2\"><CheckIcon :size=\"16\" class=\"text-primary mt-0.5 shrink-0\" aria-hidden=\"true\" />Upload unlimited files.\n              </li><li class=\"flex gap-2\"><CheckIcon :size=\"16\" class=\"text-primary mt-0.5 shrink-0\" aria-hidden=\"true\" />7-day money back guarantee.\n              </li><li class=\"flex gap-2\"><CheckIcon :size=\"16\" class=\"text-primary mt-0.5 shrink-0\" aria-hidden=\"true\" />Advanced permissions.\n              </li></ul></div><div class=\"grid gap-2\"><Button type=\"button\" class=\"w-full\">Change plan\n            </Button><DialogClose as-child><Button type=\"button\" variant=\"ghost\" class=\"w-full\">Cancel\n              </Button></DialogClose></div></form></DialogContent></Dialog>\n</template>\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-18.html",
          "target": "components/ui/dialog-18.html",
          "type": "registry:component",
          "content": "<template>\n  <Dialog><DialogTrigger aschild><Button variant=\"outline\">Change plan</Button></DialogTrigger><DialogContent><div class=\"mb-2 flex flex-col gap-2\"><div class=\"flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><RefreshCcwIcon class=\"opacity-80\" size=\"${16}\" /></div><DialogHeader><DialogTitle class=\"text-left\">Change your plan</DialogTitle><DialogDescription class=\"text-left\">Pick one of the following plans.\n            </DialogDescription></DialogHeader></div><form class=\"space-y-5\"><RadioGroup class=\"gap-2\" default-value=\"2\"><div class=\"border-input has-data-[state=checked]:border-primary/50 has-data-[state=checked]:bg-accent relative flex w-full items-center gap-2 rounded-md border px-4 py-3 shadow-xs outline-none\"><RadioGroupItem value=\"1\" id=\"${`${id}-1`}\" aria-describedby=\"${`${id}-1-description`}\" class=\"order-1 after:absolute after:inset-0\" /><div class=\"grid grow gap-1\"><Label htmlfor=\"${`${id}-1`}\">Essential</Label><p id=\"${`${id}-1-description`}\" class=\"text-muted-foreground text-xs\">$4 per member/month\n                </p></div></div><div class=\"border-input has-data-[state=checked]:border-primary/50 has-data-[state=checked]:bg-accent relative flex w-full items-center gap-2 rounded-md border px-4 py-3 shadow-xs outline-none\"><RadioGroupItem value=\"2\" id=\"${`${id}-2`}\" aria-describedby=\"${`${id}-2-description`}\" class=\"order-1 after:absolute after:inset-0\" /><div class=\"grid grow gap-1\"><Label htmlfor=\"${`${id}-2`}\">Standard</Label><p id=\"${`${id}-2-description`}\" class=\"text-muted-foreground text-xs\">$19 per member/month\n                </p></div></div><div class=\"border-input has-data-[state=checked]:border-primary/50 has-data-[state=checked]:bg-accent relative flex w-full items-center gap-2 rounded-md border px-4 py-3 shadow-xs outline-none\"><RadioGroupItem value=\"3\" id=\"${`${id}-3`}\" aria-describedby=\"${`${id}-3-description`}\" class=\"order-1 after:absolute after:inset-0\" /><div class=\"grid grow gap-1\"><Label htmlfor=\"${`${id}-3`}\">Enterprise</Label><p id=\"${`${id}-3-description`}\" class=\"text-muted-foreground text-xs\">$32 per member/month\n                </p></div></div></RadioGroup><div class=\"space-y-3\"><p><strong class=\"text-sm font-medium\">Features include:</strong></p><ul class=\"text-muted-foreground space-y-2 text-sm\"><li class=\"flex gap-2\"><CheckIcon size=\"${16}\" class=\"text-primary mt-0.5 shrink-0\" aria-hidden=\"true\" />Create unlimited projects.\n              </li><li class=\"flex gap-2\"><CheckIcon size=\"${16}\" class=\"text-primary mt-0.5 shrink-0\" aria-hidden=\"true\" />Remove watermarks.\n              </li><li class=\"flex gap-2\"><CheckIcon size=\"${16}\" class=\"text-primary mt-0.5 shrink-0\" aria-hidden=\"true\" />Add unlimited users and free viewers.\n              </li><li class=\"flex gap-2\"><CheckIcon size=\"${16}\" class=\"text-primary mt-0.5 shrink-0\" aria-hidden=\"true\" />Upload unlimited files.\n              </li><li class=\"flex gap-2\"><CheckIcon size=\"${16}\" class=\"text-primary mt-0.5 shrink-0\" aria-hidden=\"true\" />7-day money back guarantee.\n              </li><li class=\"flex gap-2\"><CheckIcon size=\"${16}\" class=\"text-primary mt-0.5 shrink-0\" aria-hidden=\"true\" />Advanced permissions.\n              </li></ul></div><div class=\"grid gap-2\"><Button type=\"button\" class=\"w-full\">Change plan\n            </Button><DialogClose aschild><Button type=\"button\" variant=\"ghost\" class=\"w-full\">Cancel\n              </Button></DialogClose></div></form></DialogContent></Dialog>\n</template>"
        },
        {
          "path": "registry/default/components/dialog/dialog-18.wxml",
          "target": "components/ui/dialog-18/dialog-18.wxml",
          "type": "registry:component",
          "content": "<view>\n  <dialog><dialogtrigger aschild><button variant=\"outline\">Change plan</button></dialogtrigger><dialogcontent><view class=\"mb-2 flex flex-col gap-2\"><view class=\"flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><refreshccwicon class=\"opacity-80\" size=\"{{16}}\" /></view><dialogheader><dialogtitle class=\"text-left\">Change your plan</dialogtitle><dialogdescription class=\"text-left\">Pick one of the following plans.\n            </dialogdescription></dialogheader></view><form class=\"space-y-5\"><radiogroup class=\"gap-2\" default-value=\"2\"><view class=\"border-input has-data-[state=checked]:border-primary/50 has-data-[state=checked]:bg-accent relative flex w-full items-center gap-2 rounded-md border px-4 py-3 shadow-xs outline-none\"><radiogroupitem value=\"1\" id=\"{{`${id}-1`}}\" aria-describedby=\"{{`${id}-1-description`}}\" class=\"order-1 after:absolute after:inset-0\" /><view class=\"grid grow gap-1\"><label htmlfor=\"{{`${id}-1`}}\">Essential</label><text id=\"{{`${id}-1-description`}}\" class=\"text-muted-foreground text-xs\">$4 per member/month\n                </text></view></view><view class=\"border-input has-data-[state=checked]:border-primary/50 has-data-[state=checked]:bg-accent relative flex w-full items-center gap-2 rounded-md border px-4 py-3 shadow-xs outline-none\"><radiogroupitem value=\"2\" id=\"{{`${id}-2`}}\" aria-describedby=\"{{`${id}-2-description`}}\" class=\"order-1 after:absolute after:inset-0\" /><view class=\"grid grow gap-1\"><label htmlfor=\"{{`${id}-2`}}\">Standard</label><text id=\"{{`${id}-2-description`}}\" class=\"text-muted-foreground text-xs\">$19 per member/month\n                </text></view></view><view class=\"border-input has-data-[state=checked]:border-primary/50 has-data-[state=checked]:bg-accent relative flex w-full items-center gap-2 rounded-md border px-4 py-3 shadow-xs outline-none\"><radiogroupitem value=\"3\" id=\"{{`${id}-3`}}\" aria-describedby=\"{{`${id}-3-description`}}\" class=\"order-1 after:absolute after:inset-0\" /><view class=\"grid grow gap-1\"><label htmlfor=\"{{`${id}-3`}}\">Enterprise</label><text id=\"{{`${id}-3-description`}}\" class=\"text-muted-foreground text-xs\">$32 per member/month\n                </text></view></view></radiogroup><view class=\"space-y-3\"><text><strong class=\"text-sm font-medium\">Features include:</strong></text><ul class=\"text-muted-foreground space-y-2 text-sm\"><li class=\"flex gap-2\"><checkicon size=\"{{16}}\" class=\"text-primary mt-0.5 shrink-0\" aria-hidden=\"true\" />Create unlimited projects.\n              </li><li class=\"flex gap-2\"><checkicon size=\"{{16}}\" class=\"text-primary mt-0.5 shrink-0\" aria-hidden=\"true\" />Remove watermarks.\n              </li><li class=\"flex gap-2\"><checkicon size=\"{{16}}\" class=\"text-primary mt-0.5 shrink-0\" aria-hidden=\"true\" />Add unlimited users and free viewers.\n              </li><li class=\"flex gap-2\"><checkicon size=\"{{16}}\" class=\"text-primary mt-0.5 shrink-0\" aria-hidden=\"true\" />Upload unlimited files.\n              </li><li class=\"flex gap-2\"><checkicon size=\"{{16}}\" class=\"text-primary mt-0.5 shrink-0\" aria-hidden=\"true\" />7-day money back guarantee.\n              </li><li class=\"flex gap-2\"><checkicon size=\"{{16}}\" class=\"text-primary mt-0.5 shrink-0\" aria-hidden=\"true\" />Advanced permissions.\n              </li></ul></view><view class=\"grid gap-2\"><button type=\"button\" class=\"w-full\">Change plan\n            </button><dialogclose aschild><button type=\"button\" variant=\"ghost\" class=\"w-full\">Cancel\n              </button></dialogclose></view></form></dialogcontent></dialog>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dialog",
          "modal",
          "user",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dialog-18",
          "group": "dialog",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dialog-18",
              "path": "registry/default/components/dialog/dialog-18.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dialog-18",
              "path": "registry/default/components/dialog/dialog-18.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dialog-18",
              "path": "registry/default/components/dialog/dialog-18.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dialog-18",
              "path": "registry/default/components/dialog/dialog-18.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dialog",
        "title": "Dialog · Essential"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "dialog"
      ]
    },
    {
      "name": "dialog-19",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dialog.json",
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/textarea.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/dialog/dialog-19.tsx",
          "type": "registry:component",
          "target": "components/ui/dialog-19.tsx",
          "content": "'use client'\n\nimport { useId, useState } from 'react'\nimport {\n  Button,\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n  Input,\n  Label,\n  Textarea,\n} from '@timui/react'\nimport { CheckIcon, ImagePlusIcon, XIcon } from 'lucide-react'\n\nimport { useCharacterLimit } from '@/registry/default/hooks/use-character-limit'\nimport { useFileUpload } from '@/registry/default/hooks/use-file-upload'\n\n// Pretend we have initial image files\nconst initialBgImage = [\n  {\n    name: 'profile-bg.jpg',\n    size: 1528737,\n    type: 'image/jpeg',\n    url: '/profile-bg.jpg',\n    id: 'profile-bg-123456789',\n  },\n]\n\nconst initialAvatarImage = [\n  {\n    name: 'avatar-72-01.jpg',\n    size: 1528737,\n    type: 'image/jpeg',\n    url: '/avatar-72-01.jpg',\n    id: 'avatar-123456789',\n  },\n]\n\nexport default function Component() {\n  const id = useId()\n\n  const maxLength = 180\n  const {\n    value,\n    characterCount,\n    handleChange,\n    maxLength: limit,\n  } = useCharacterLimit({\n    maxLength,\n    initialValue:\n      'Hey, I am Margaret, a web developer who loves turning ideas into amazing websites!',\n  })\n\n  return (\n    <Dialog>\n      <DialogTrigger asChild>\n        <Button variant=\"outline\">Edit profile</Button>\n      </DialogTrigger>\n      <DialogContent className=\"flex flex-col gap-0 overflow-y-visible p-0 sm:max-w-lg [&>button:last-child]:top-3.5\">\n        <DialogHeader className=\"contents space-y-0 text-left\">\n          <DialogTitle className=\"border-b px-6 py-4 text-base\">Edit profile</DialogTitle>\n        </DialogHeader>\n        <DialogDescription className=\"sr-only\">\n          Make changes to your profile here. You can change your photo and set a username.\n        </DialogDescription>\n        <div className=\"overflow-y-auto\">\n          <ProfileBg />\n          <Avatar />\n          <div className=\"px-6 pt-4 pb-6\">\n            <form className=\"space-y-4\">\n              <div className=\"flex flex-col gap-4 sm:flex-row\">\n                <div className=\"flex-1 space-y-2\">\n                  <Label htmlFor={`${id}-first-name`}>First name</Label>\n                  <Input\n                    id={`${id}-first-name`}\n                    placeholder=\"Matt\"\n                    defaultValue=\"Margaret\"\n                    type=\"text\"\n                    required\n                  />\n                </div>\n                <div className=\"flex-1 space-y-2\">\n                  <Label htmlFor={`${id}-last-name`}>Last name</Label>\n                  <Input\n                    id={`${id}-last-name`}\n                    placeholder=\"Welsh\"\n                    defaultValue=\"Villard\"\n                    type=\"text\"\n                    required\n                  />\n                </div>\n              </div>\n              <div className=\"*:not-first:mt-2\">\n                <Label htmlFor={`${id}-username`}>Username</Label>\n                <div className=\"relative\">\n                  <Input\n                    id={`${id}-username`}\n                    className=\"peer pe-9\"\n                    placeholder=\"Username\"\n                    defaultValue=\"margaret-villard-69\"\n                    type=\"text\"\n                    required\n                  />\n                  <div className=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 peer-disabled:opacity-50\">\n                    <CheckIcon size={16} className=\"text-emerald-500\" aria-hidden=\"true\" />\n                  </div>\n                </div>\n              </div>\n              <div className=\"*:not-first:mt-2\">\n                <Label htmlFor={`${id}-website`}>Website</Label>\n                <div className=\"flex rounded-md shadow-xs\">\n                  <span className=\"border-input bg-background text-muted-foreground -z-10 inline-flex items-center rounded-s-md border px-3 text-sm\">\n                    https://\n                  </span>\n                  <Input\n                    id={`${id}-website`}\n                    className=\"-ms-px rounded-s-none shadow-none\"\n                    placeholder=\"yourwebsite.com\"\n                    defaultValue=\"www.margaret.com\"\n                    type=\"text\"\n                  />\n                </div>\n              </div>\n              <div className=\"*:not-first:mt-2\">\n                <Label htmlFor={`${id}-bio`}>Biography</Label>\n                <Textarea\n                  id={`${id}-bio`}\n                  placeholder=\"Write a few sentences about yourself\"\n                  defaultValue={value}\n                  maxLength={maxLength}\n                  onChange={handleChange}\n                  aria-describedby={`${id}-description`}\n                />\n                <p\n                  id={`${id}-description`}\n                  className=\"text-muted-foreground mt-2 text-right text-xs\"\n                  role=\"status\"\n                  aria-live=\"polite\"\n                >\n                  <span className=\"tabular-nums\">{limit - characterCount}</span> characters left\n                </p>\n              </div>\n            </form>\n          </div>\n        </div>\n        <DialogFooter className=\"border-t px-6 py-4\">\n          <DialogClose asChild>\n            <Button type=\"button\" variant=\"outline\">\n              Cancel\n            </Button>\n          </DialogClose>\n          <DialogClose asChild>\n            <Button type=\"button\">Save changes</Button>\n          </DialogClose>\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  )\n}\n\nfunction ProfileBg() {\n  const [{ files }, { removeFile, openFileDialog, getInputProps }] = useFileUpload({\n    accept: 'image/*',\n    initialFiles: initialBgImage,\n  })\n\n  const currentImage = files[0]?.preview || null\n\n  return (\n    <div className=\"h-32\">\n      <div className=\"bg-muted relative flex size-full items-center justify-center overflow-hidden\">\n        {currentImage && (\n          <img\n            className=\"size-full object-cover\"\n            src={currentImage}\n            alt={files[0]?.preview ? 'Preview of uploaded image' : 'Default profile background'}\n            width={512}\n            height={96}\n          />\n        )}\n        <div className=\"absolute inset-0 flex items-center justify-center gap-2\">\n          <button\n            type=\"button\"\n            className=\"focus-visible:border-ring focus-visible:ring-ring/50 z-50 flex size-10 cursor-pointer items-center justify-center rounded-full bg-black/60 text-white transition-[color,box-shadow] outline-none hover:bg-black/80 focus-visible:ring-[3px]\"\n            onClick={openFileDialog}\n            aria-label={currentImage ? 'Change image' : 'Upload image'}\n          >\n            <ImagePlusIcon size={16} aria-hidden=\"true\" />\n          </button>\n          {currentImage && (\n            <button\n              type=\"button\"\n              className=\"focus-visible:border-ring focus-visible:ring-ring/50 z-50 flex size-10 cursor-pointer items-center justify-center rounded-full bg-black/60 text-white transition-[color,box-shadow] outline-none hover:bg-black/80 focus-visible:ring-[3px]\"\n              onClick={() => removeFile(files[0]?.id)}\n              aria-label=\"Remove image\"\n            >\n              <XIcon size={16} aria-hidden=\"true\" />\n            </button>\n          )}\n        </div>\n      </div>\n      <input {...getInputProps()} className=\"sr-only\" aria-label=\"Upload image file\" />\n    </div>\n  )\n}\n\nfunction Avatar() {\n  const [{ files }, { openFileDialog, getInputProps }] = useFileUpload({\n    accept: 'image/*',\n    initialFiles: initialAvatarImage,\n  })\n\n  const currentImage = files[0]?.preview || null\n\n  return (\n    <div className=\"-mt-10 px-6\">\n      <div className=\"border-background bg-muted relative flex size-20 items-center justify-center overflow-hidden rounded-full border-4 shadow-xs shadow-black/10\">\n        {currentImage && (\n          <img\n            src={currentImage}\n            className=\"size-full object-cover\"\n            width={80}\n            height={80}\n            alt=\"Profile image\"\n          />\n        )}\n        <button\n          type=\"button\"\n          className=\"focus-visible:border-ring focus-visible:ring-ring/50 absolute flex size-8 cursor-pointer items-center justify-center rounded-full bg-black/60 text-white transition-[color,box-shadow] outline-none hover:bg-black/80 focus-visible:ring-[3px]\"\n          onClick={openFileDialog}\n          aria-label=\"Change profile picture\"\n        >\n          <ImagePlusIcon size={16} aria-hidden=\"true\" />\n        </button>\n        <input {...getInputProps()} className=\"sr-only\" aria-label=\"Upload profile picture\" />\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/hooks/use-character-limit.ts",
          "type": "registry:hook",
          "target": "components/ui/dialog-19/use-character-limit.ts",
          "content": "'use client'\n\nimport { ChangeEvent, useState } from 'react'\n\ntype UseCharacterLimitProps = {\n  maxLength: number\n  initialValue?: string\n}\n\nexport function useCharacterLimit({ maxLength, initialValue = '' }: UseCharacterLimitProps) {\n  const [value, setValue] = useState(initialValue)\n  const [characterCount, setCharacterCount] = useState(initialValue.length)\n\n  const handleChange = (e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {\n    const newValue = e.target.value\n    if (newValue.length <= maxLength) {\n      setValue(newValue)\n      setCharacterCount(newValue.length)\n    }\n  }\n\n  return {\n    value,\n    characterCount,\n    handleChange,\n    maxLength,\n  }\n}\n"
        },
        {
          "path": "registry/default/hooks/use-file-upload.ts",
          "type": "registry:hook",
          "target": "components/ui/dialog-19/use-file-upload.ts",
          "content": "'use client'\n\nimport type React from 'react'\nimport {\n  useCallback,\n  useRef,\n  useState,\n  type ChangeEvent,\n  type DragEvent,\n  type InputHTMLAttributes,\n} from 'react'\n\nexport type FileMetadata = {\n  name: string\n  size: number\n  type: string\n  url: string\n  id: string\n}\n\nexport type FileWithPreview = {\n  file: File | FileMetadata\n  id: string\n  preview?: string\n}\n\nexport type FileUploadOptions = {\n  maxFiles?: number // Only used when multiple is true, defaults to Infinity\n  maxSize?: number // in bytes\n  accept?: string\n  multiple?: boolean // Defaults to false\n  initialFiles?: FileMetadata[]\n  onFilesChange?: (files: FileWithPreview[]) => void // Callback when files change\n  onFilesAdded?: (addedFiles: FileWithPreview[]) => void // Callback when new files are added\n}\n\nexport type FileUploadState = {\n  files: FileWithPreview[]\n  isDragging: boolean\n  errors: string[]\n}\n\nexport type FileUploadActions = {\n  addFiles: (files: FileList | File[]) => void\n  removeFile: (id: string) => void\n  clearFiles: () => void\n  clearErrors: () => void\n  handleDragEnter: (e: DragEvent<HTMLElement>) => void\n  handleDragLeave: (e: DragEvent<HTMLElement>) => void\n  handleDragOver: (e: DragEvent<HTMLElement>) => void\n  handleDrop: (e: DragEvent<HTMLElement>) => void\n  handleFileChange: (e: ChangeEvent<HTMLInputElement>) => void\n  openFileDialog: () => void\n  getInputProps: (\n    props?: InputHTMLAttributes<HTMLInputElement>\n  ) => InputHTMLAttributes<HTMLInputElement> & {\n    ref: React.Ref<HTMLInputElement>\n  }\n}\n\nexport const useFileUpload = (\n  options: FileUploadOptions = {}\n): [FileUploadState, FileUploadActions] => {\n  const {\n    maxFiles = Infinity,\n    maxSize = Infinity,\n    accept = '*',\n    multiple = false,\n    initialFiles = [],\n    onFilesChange,\n    onFilesAdded,\n  } = options\n\n  const [state, setState] = useState<FileUploadState>({\n    files: initialFiles.map((file) => ({\n      file,\n      id: file.id,\n      preview: file.url,\n    })),\n    isDragging: false,\n    errors: [],\n  })\n\n  const inputRef = useRef<HTMLInputElement>(null)\n\n  const validateFile = useCallback(\n    (file: File | FileMetadata): string | null => {\n      if (file instanceof File) {\n        if (file.size > maxSize) {\n          return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n        }\n      } else {\n        if (file.size > maxSize) {\n          return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n        }\n      }\n\n      if (accept !== '*') {\n        const acceptedTypes = accept.split(',').map((type) => type.trim())\n        const fileType = file instanceof File ? file.type || '' : file.type\n        const fileExtension = `.${file instanceof File ? file.name.split('.').pop() : file.name.split('.').pop()}`\n\n        const isAccepted = acceptedTypes.some((type) => {\n          if (type.startsWith('.')) {\n            return fileExtension.toLowerCase() === type.toLowerCase()\n          }\n          if (type.endsWith('/*')) {\n            const baseType = type.split('/')[0]\n            return fileType.startsWith(`${baseType}/`)\n          }\n          return fileType === type\n        })\n\n        if (!isAccepted) {\n          return `File \"${file instanceof File ? file.name : file.name}\" is not an accepted file type.`\n        }\n      }\n\n      return null\n    },\n    [accept, maxSize]\n  )\n\n  const createPreview = useCallback((file: File | FileMetadata): string | undefined => {\n    if (file instanceof File) {\n      return URL.createObjectURL(file)\n    }\n    return file.url\n  }, [])\n\n  const generateUniqueId = useCallback((file: File | FileMetadata): string => {\n    if (file instanceof File) {\n      return `${file.name}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`\n    }\n    return file.id\n  }, [])\n\n  const clearFiles = useCallback(() => {\n    setState((prev) => {\n      // Clean up object URLs\n      prev.files.forEach((file) => {\n        if (file.preview && file.file instanceof File && file.file.type.startsWith('image/')) {\n          URL.revokeObjectURL(file.preview)\n        }\n      })\n\n      if (inputRef.current) {\n        inputRef.current.value = ''\n      }\n\n      const newState = {\n        ...prev,\n        files: [],\n        errors: [],\n      }\n\n      onFilesChange?.(newState.files)\n      return newState\n    })\n  }, [onFilesChange])\n\n  const addFiles = useCallback(\n    (newFiles: FileList | File[]) => {\n      if (!newFiles || newFiles.length === 0) return\n\n      const newFilesArray = Array.from(newFiles)\n      const errors: string[] = []\n\n      // Clear existing errors when new files are uploaded\n      setState((prev) => ({ ...prev, errors: [] }))\n\n      // In single file mode, clear existing files first\n      if (!multiple) {\n        clearFiles()\n      }\n\n      // Check if adding these files would exceed maxFiles (only in multiple mode)\n      if (\n        multiple &&\n        maxFiles !== Infinity &&\n        state.files.length + newFilesArray.length > maxFiles\n      ) {\n        errors.push(`You can only upload a maximum of ${maxFiles} files.`)\n        setState((prev) => ({ ...prev, errors }))\n        return\n      }\n\n      const validFiles: FileWithPreview[] = []\n\n      newFilesArray.forEach((file) => {\n        // Only check for duplicates if multiple files are allowed\n        if (multiple) {\n          const isDuplicate = state.files.some(\n            (existingFile) =>\n              existingFile.file.name === file.name && existingFile.file.size === file.size\n          )\n\n          // Skip duplicate files silently\n          if (isDuplicate) {\n            return\n          }\n        }\n\n        // Check file size\n        if (file.size > maxSize) {\n          errors.push(\n            multiple\n              ? `Some files exceed the maximum size of ${formatBytes(maxSize)}.`\n              : `File exceeds the maximum size of ${formatBytes(maxSize)}.`\n          )\n          return\n        }\n\n        const error = validateFile(file)\n        if (error) {\n          errors.push(error)\n        } else {\n          validFiles.push({\n            file,\n            id: generateUniqueId(file),\n            preview: createPreview(file),\n          })\n        }\n      })\n\n      // Only update state if we have valid files to add\n      if (validFiles.length > 0) {\n        // Call the onFilesAdded callback with the newly added valid files\n        onFilesAdded?.(validFiles)\n\n        setState((prev) => {\n          const newFiles = !multiple ? validFiles : [...prev.files, ...validFiles]\n          onFilesChange?.(newFiles)\n          return {\n            ...prev,\n            files: newFiles,\n            errors,\n          }\n        })\n      } else if (errors.length > 0) {\n        setState((prev) => ({\n          ...prev,\n          errors,\n        }))\n      }\n\n      // Reset input value after handling files\n      if (inputRef.current) {\n        inputRef.current.value = ''\n      }\n    },\n    [\n      state.files,\n      maxFiles,\n      multiple,\n      maxSize,\n      validateFile,\n      createPreview,\n      generateUniqueId,\n      clearFiles,\n      onFilesChange,\n      onFilesAdded,\n    ]\n  )\n\n  const removeFile = useCallback(\n    (id: string) => {\n      setState((prev) => {\n        const fileToRemove = prev.files.find((file) => file.id === id)\n        if (\n          fileToRemove &&\n          fileToRemove.preview &&\n          fileToRemove.file instanceof File &&\n          fileToRemove.file.type.startsWith('image/')\n        ) {\n          URL.revokeObjectURL(fileToRemove.preview)\n        }\n\n        const newFiles = prev.files.filter((file) => file.id !== id)\n        onFilesChange?.(newFiles)\n\n        return {\n          ...prev,\n          files: newFiles,\n          errors: [],\n        }\n      })\n    },\n    [onFilesChange]\n  )\n\n  const clearErrors = useCallback(() => {\n    setState((prev) => ({\n      ...prev,\n      errors: [],\n    }))\n  }, [])\n\n  const handleDragEnter = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n    setState((prev) => ({ ...prev, isDragging: true }))\n  }, [])\n\n  const handleDragLeave = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n\n    if (e.currentTarget.contains(e.relatedTarget as Node)) {\n      return\n    }\n\n    setState((prev) => ({ ...prev, isDragging: false }))\n  }, [])\n\n  const handleDragOver = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n  }, [])\n\n  const handleDrop = useCallback(\n    (e: DragEvent<HTMLElement>) => {\n      e.preventDefault()\n      e.stopPropagation()\n      setState((prev) => ({ ...prev, isDragging: false }))\n\n      // Don't process files if the input is disabled\n      if (inputRef.current?.disabled) {\n        return\n      }\n\n      if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n        // In single file mode, only use the first file\n        if (!multiple) {\n          const file = e.dataTransfer.files[0]\n          addFiles([file])\n        } else {\n          addFiles(e.dataTransfer.files)\n        }\n      }\n    },\n    [addFiles, multiple]\n  )\n\n  const handleFileChange = useCallback(\n    (e: ChangeEvent<HTMLInputElement>) => {\n      if (e.target.files && e.target.files.length > 0) {\n        addFiles(e.target.files)\n      }\n    },\n    [addFiles]\n  )\n\n  const openFileDialog = useCallback(() => {\n    if (inputRef.current) {\n      inputRef.current.click()\n    }\n  }, [])\n\n  const getInputProps = useCallback(\n    (props: InputHTMLAttributes<HTMLInputElement> = {}) => {\n      return {\n        ...props,\n        type: 'file' as const,\n        onChange: handleFileChange,\n        accept: props.accept || accept,\n        multiple: props.multiple !== undefined ? props.multiple : multiple,\n        ref: inputRef,\n      }\n    },\n    [accept, multiple, handleFileChange]\n  )\n\n  return [\n    state,\n    {\n      addFiles,\n      removeFile,\n      clearFiles,\n      clearErrors,\n      handleDragEnter,\n      handleDragLeave,\n      handleDragOver,\n      handleDrop,\n      handleFileChange,\n      openFileDialog,\n      getInputProps,\n    },\n  ]\n}\n\n// Helper function to format bytes to human-readable format\nexport const formatBytes = (bytes: number, decimals = 2): string => {\n  if (bytes === 0) return '0 Bytes'\n\n  const k = 1024\n  const dm = decimals < 0 ? 0 : decimals\n  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']\n\n  const i = Math.floor(Math.log(bytes) / Math.log(k))\n\n  return Number.parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + sizes[i]\n}\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-19.vue",
          "target": "components/ui/dialog-19.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, ref } from 'vue';\nimport { CheckIcon, ImagePlusIcon, XIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n} from '@timui/vue';\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\nimport { Textarea } from '@timui/vue';\nimport { useCharacterLimit } from '@/registry/default/hooks/use-character-limit-vue';\nimport { useFileUpload } from '@/registry/default/hooks/use-file-upload-vue';\n\nconst initialBgImage = [\n  {\n    name: 'profile-bg.jpg',\n    size: 1528737,\n    type: 'image/jpeg',\n    url: '/profile-bg.jpg',\n    id: 'profile-bg-123456789',\n  },\n];\n\nconst initialAvatarImage = [\n  {\n    name: 'avatar-72-01.jpg',\n    size: 1528737,\n    type: 'image/jpeg',\n    url: '/avatar-72-01.jpg',\n    id: 'avatar-123456789',\n  },\n];\n\nconst id = 'dialog-19';\n\nconst firstName = ref('Margaret');\nconst lastName = ref('Villard');\nconst username = ref('margaret-villard-69');\nconst website = ref('www.margaret.com');\n\nconst maxLength = 180;\nconst {\n  value,\n  characterCount,\n  maxLength: limit,\n} = useCharacterLimit({\n  maxLength,\n  initialValue: 'Hey, I am Margaret, a web developer who loves turning ideas into amazing websites!',\n});\n\nconst [{ files: bgFiles }, { removeFile: removeBgFile, openFileDialog: openBgDialog, getInputProps: getBgInputProps }] = useFileUpload({\n  accept: 'image/*',\n  initialFiles: initialBgImage,\n});\n\nconst [{ files: avatarFiles }, { openFileDialog: openAvatarDialog, getInputProps: getAvatarInputProps }] = useFileUpload({\n  accept: 'image/*',\n  initialFiles: initialAvatarImage,\n});\n\nconst currentBgImage = computed(() => bgFiles.value[0]?.preview ?? null);\nconst currentAvatarImage = computed(() => avatarFiles.value[0]?.preview ?? null);\n\nfunction removeCurrentBgImage() {\n  const imageId = bgFiles.value[0]?.id;\n  if (imageId) {\n    removeBgFile(imageId);\n  }\n}\n</script>\n\n<template>\n  <Dialog>\n    <DialogTrigger as-child>\n      <Button variant=\"outline\">Edit profile</Button>\n    </DialogTrigger>\n    <DialogContent class=\"flex flex-col gap-0 overflow-y-visible p-0 sm:max-w-lg [&>button:last-child]:top-3.5\">\n      <DialogHeader class=\"contents space-y-0 text-left\">\n        <DialogTitle class=\"border-b px-6 py-4 text-base\">Edit profile</DialogTitle>\n      </DialogHeader>\n      <DialogDescription class=\"sr-only\">\n        Make changes to your profile here. You can change your photo and set a username.\n      </DialogDescription>\n\n      <div class=\"overflow-y-auto\">\n        <div class=\"h-32\">\n          <div class=\"bg-muted relative flex size-full items-center justify-center overflow-hidden\">\n            <img\n              v-if=\"currentBgImage\"\n              class=\"size-full object-cover\"\n              :src=\"currentBgImage\"\n              :alt=\"currentBgImage ? 'Preview of uploaded image' : 'Default profile background'\"\n              :width=\"512\"\n              :height=\"96\"\n            />\n            <div class=\"absolute inset-0 flex items-center justify-center gap-2\">\n              <button\n                type=\"button\"\n                class=\"focus-visible:border-ring focus-visible:ring-ring/50 z-50 flex size-10 cursor-pointer items-center justify-center rounded-full bg-black/60 text-white transition-[color,box-shadow] outline-none hover:bg-black/80 focus-visible:ring-[3px]\"\n                @click=\"openBgDialog\"\n                :aria-label=\"currentBgImage ? 'Change image' : 'Upload image'\"\n              >\n                <ImagePlusIcon :size=\"16\" aria-hidden=\"true\" />\n              </button>\n              <button\n                v-if=\"currentBgImage\"\n                type=\"button\"\n                class=\"focus-visible:border-ring focus-visible:ring-ring/50 z-50 flex size-10 cursor-pointer items-center justify-center rounded-full bg-black/60 text-white transition-[color,box-shadow] outline-none hover:bg-black/80 focus-visible:ring-[3px]\"\n                @click=\"removeCurrentBgImage\"\n                aria-label=\"Remove image\"\n              >\n                <XIcon :size=\"16\" aria-hidden=\"true\" />\n              </button>\n            </div>\n          </div>\n          <input v-bind=\"getBgInputProps()\" class=\"sr-only\" aria-label=\"Upload image file\" />\n        </div>\n\n        <div class=\"-mt-10 px-6\">\n          <div class=\"border-background bg-muted relative flex size-20 items-center justify-center overflow-hidden rounded-full border-4 shadow-xs shadow-black/10\">\n            <img\n              v-if=\"currentAvatarImage\"\n              :src=\"currentAvatarImage\"\n              class=\"size-full object-cover\"\n              :width=\"80\"\n              :height=\"80\"\n              alt=\"Profile image\"\n            />\n            <button\n              type=\"button\"\n              class=\"focus-visible:border-ring focus-visible:ring-ring/50 absolute flex size-8 cursor-pointer items-center justify-center rounded-full bg-black/60 text-white transition-[color,box-shadow] outline-none hover:bg-black/80 focus-visible:ring-[3px]\"\n              @click=\"openAvatarDialog\"\n              aria-label=\"Change profile picture\"\n            >\n              <ImagePlusIcon :size=\"16\" aria-hidden=\"true\" />\n            </button>\n            <input v-bind=\"getAvatarInputProps()\" class=\"sr-only\" aria-label=\"Upload profile picture\" />\n          </div>\n        </div>\n\n        <div class=\"px-6 pt-4 pb-6\">\n          <form class=\"space-y-4\">\n            <div class=\"flex flex-col gap-4 sm:flex-row\">\n              <div class=\"flex-1 space-y-2\">\n                <Label :htmlFor=\"`${id}-first-name`\">First name</Label>\n                <Input :id=\"`${id}-first-name`\" v-model=\"firstName\" placeholder=\"Matt\" type=\"text\" required />\n              </div>\n              <div class=\"flex-1 space-y-2\">\n                <Label :htmlFor=\"`${id}-last-name`\">Last name</Label>\n                <Input :id=\"`${id}-last-name`\" v-model=\"lastName\" placeholder=\"Welsh\" type=\"text\" required />\n              </div>\n            </div>\n\n            <div class=\"*:not-first:mt-2\">\n              <Label :htmlFor=\"`${id}-username`\">Username</Label>\n              <div class=\"relative\">\n                <Input\n                  :id=\"`${id}-username`\"\n                  v-model=\"username\"\n                  class=\"peer pe-9\"\n                  placeholder=\"Username\"\n                  type=\"text\"\n                  required\n                />\n                <div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 peer-disabled:opacity-50\">\n                  <CheckIcon :size=\"16\" class=\"text-emerald-500\" aria-hidden=\"true\" />\n                </div>\n              </div>\n            </div>\n\n            <div class=\"*:not-first:mt-2\">\n              <Label :htmlFor=\"`${id}-website`\">Website</Label>\n              <div class=\"flex rounded-md shadow-xs\">\n                <span class=\"border-input bg-background text-muted-foreground -z-10 inline-flex items-center rounded-s-md border px-3 text-sm\">\n                  https://\n                </span>\n                <Input\n                  :id=\"`${id}-website`\"\n                  v-model=\"website\"\n                  class=\"-ms-px rounded-s-none shadow-none\"\n                  placeholder=\"yourwebsite.com\"\n                  type=\"text\"\n                />\n              </div>\n            </div>\n\n            <div class=\"*:not-first:mt-2\">\n              <Label :htmlFor=\"`${id}-bio`\">Biography</Label>\n              <Textarea\n                :id=\"`${id}-bio`\"\n                v-model=\"value\"\n                placeholder=\"Write a few sentences about yourself\"\n                :maxLength=\"maxLength\"\n                :aria-describedby=\"`${id}-description`\"\n              />\n              <p :id=\"`${id}-description`\" class=\"text-muted-foreground mt-2 text-right text-xs\" role=\"status\" aria-live=\"polite\">\n                <span class=\"tabular-nums\">{{ limit - characterCount }}</span> characters left\n              </p>\n            </div>\n          </form>\n        </div>\n      </div>\n\n      <DialogFooter class=\"border-t px-6 py-4\">\n        <DialogClose as-child>\n          <Button type=\"button\" variant=\"outline\">Cancel</Button>\n        </DialogClose>\n        <DialogClose as-child>\n          <Button type=\"button\">Save changes</Button>\n        </DialogClose>\n      </DialogFooter>\n    </DialogContent>\n  </Dialog>\n</template>\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-19.html",
          "target": "components/ui/dialog-19.html",
          "type": "registry:component",
          "content": "<template>\n  <Dialog><DialogTrigger aschild><Button variant=\"outline\">Edit profile</Button></DialogTrigger><DialogContent class=\"flex flex-col gap-0 overflow-y-visible p-0 sm:max-w-lg [&>button:last-child]:top-3.5\"><DialogHeader class=\"contents space-y-0 text-left\"><DialogTitle class=\"border-b px-6 py-4 text-base\">Edit profile</DialogTitle></DialogHeader><DialogDescription class=\"sr-only\">Make changes to your profile here. You can change your photo and set a username.\n        </DialogDescription><div class=\"overflow-y-auto\"><ProfileBg /><Avatar /><div class=\"px-6 pt-4 pb-6\"><form class=\"space-y-4\"><div class=\"flex flex-col gap-4 sm:flex-row\"><div class=\"flex-1 space-y-2\"><Label htmlfor=\"${`${id}-first-name`}\">First name</Label><Input id=\"${`${id}-first-name`}\" placeholder=\"Matt\" default-value=\"Margaret\" type=\"text\" required /></div><div class=\"flex-1 space-y-2\"><Label htmlfor=\"${`${id}-last-name`}\">Last name</Label><Input id=\"${`${id}-last-name`}\" placeholder=\"Welsh\" default-value=\"Villard\" type=\"text\" required /></div></div><div class=\"*:not-first:mt-2\"><Label htmlfor=\"${`${id}-username`}\">Username</Label><div class=\"relative\"><Input id=\"${`${id}-username`}\" class=\"peer pe-9\" placeholder=\"Username\" default-value=\"margaret-villard-69\" type=\"text\" required /><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 peer-disabled:opacity-50\"><CheckIcon size=\"${16}\" class=\"text-emerald-500\" aria-hidden=\"true\" /></div></div></div><div class=\"*:not-first:mt-2\"><Label htmlfor=\"${`${id}-website`}\">Website</Label><div class=\"flex rounded-md shadow-xs\"><span class=\"border-input bg-background text-muted-foreground -z-10 inline-flex items-center rounded-s-md border px-3 text-sm\">https://\n                  </span><Input id=\"${`${id}-website`}\" class=\"-ms-px rounded-s-none shadow-none\" placeholder=\"yourwebsite.com\" default-value=\"www.margaret.com\" type=\"text\" /></div></div><div class=\"*:not-first:mt-2\"><Label htmlfor=\"${`${id}-bio`}\">Biography</Label><Textarea id=\"${`${id}-bio`}\" placeholder=\"Write a few sentences about yourself\" default-value=\"${value}\" maxlength=\"${maxLength}\" onchange=\"${handleChange}\" aria-describedby=\"${`${id}-description`}\" /><p id=\"${`${id}-description`}\" class=\"text-muted-foreground mt-2 text-right text-xs\" role=\"status\" aria-live=\"polite\"><span class=\"tabular-nums\">${limit - characterCount}</span>characters left\n                </p></div></form></div></div><DialogFooter class=\"border-t px-6 py-4\"><DialogClose aschild><Button type=\"button\" variant=\"outline\">Cancel\n            </Button></DialogClose><DialogClose aschild><Button type=\"button\">Save changes</Button></DialogClose></DialogFooter></DialogContent></Dialog>\n</template>"
        },
        {
          "path": "registry/default/components/dialog/dialog-19.wxml",
          "target": "components/ui/dialog-19/dialog-19.wxml",
          "type": "registry:component",
          "content": "<view>\n  <dialog><dialogtrigger aschild><button variant=\"outline\">Edit profile</button></dialogtrigger><dialogcontent class=\"flex flex-col gap-0 overflow-y-visible p-0 sm:max-w-lg [&>button:last-child]:top-3.5\"><dialogheader class=\"contents space-y-0 text-left\"><dialogtitle class=\"border-b px-6 py-4 text-base\">Edit profile</dialogtitle></dialogheader><dialogdescription class=\"sr-only\">Make changes to your profile here. You can change your photo and set a username.\n        </dialogdescription><view class=\"overflow-y-auto\"><profilebg /><avatar /><view class=\"px-6 pt-4 pb-6\"><form class=\"space-y-4\"><view class=\"flex flex-col gap-4 sm:flex-row\"><view class=\"flex-1 space-y-2\"><label htmlfor=\"{{`${id}-first-name`}}\">First name</label><input id=\"{{`${id}-first-name`}}\" placeholder=\"Matt\" default-value=\"Margaret\" type=\"text\" required /></view><view class=\"flex-1 space-y-2\"><label htmlfor=\"{{`${id}-last-name`}}\">Last name</label><input id=\"{{`${id}-last-name`}}\" placeholder=\"Welsh\" default-value=\"Villard\" type=\"text\" required /></view></view><view class=\"*:not-first:mt-2\"><label htmlfor=\"{{`${id}-username`}}\">Username</label><view class=\"relative\"><input id=\"{{`${id}-username`}}\" class=\"peer pe-9\" placeholder=\"Username\" default-value=\"margaret-villard-69\" type=\"text\" required /><view class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 peer-disabled:opacity-50\"><checkicon size=\"{{16}}\" class=\"text-emerald-500\" aria-hidden=\"true\" /></view></view></view><view class=\"*:not-first:mt-2\"><label htmlfor=\"{{`${id}-website`}}\">Website</label><view class=\"flex rounded-md shadow-xs\"><text class=\"border-input bg-background text-muted-foreground -z-10 inline-flex items-center rounded-s-md border px-3 text-sm\">https://\n                  </text><input id=\"{{`${id}-website`}}\" class=\"-ms-px rounded-s-none shadow-none\" placeholder=\"yourwebsite.com\" default-value=\"www.margaret.com\" type=\"text\" /></view></view><view class=\"*:not-first:mt-2\"><label htmlfor=\"{{`${id}-bio`}}\">Biography</label><textarea id=\"{{`${id}-bio`}}\" placeholder=\"Write a few sentences about yourself\" default-value=\"{{value}}\" maxlength=\"{{maxLength}}\" onchange=\"{{handleChange}}\" aria-describedby=\"{{`${id}-description`}}\" /><text id=\"{{`${id}-description`}}\" class=\"text-muted-foreground mt-2 text-right text-xs\" role=\"status\" aria-live=\"polite\"><text class=\"tabular-nums\">{{ limit - characterCount }}</text>characters left\n                </text></view></form></view></view><dialogfooter class=\"border-t px-6 py-4\"><dialogclose aschild><button type=\"button\" variant=\"outline\">Cancel\n            </button></dialogclose><dialogclose aschild><button type=\"button\">Save changes</button></dialogclose></dialogfooter></dialogcontent></dialog>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dialog",
          "modal",
          "user",
          "profile",
          "image",
          "avatar",
          "form",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dialog-19",
          "group": "dialog",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dialog-19",
              "path": "registry/default/components/dialog/dialog-19.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dialog-19",
              "path": "registry/default/components/dialog/dialog-19.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dialog-19",
              "path": "registry/default/components/dialog/dialog-19.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dialog-19",
              "path": "registry/default/components/dialog/dialog-19.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dialog",
        "title": "Dialog · First name"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "dialog"
      ]
    },
    {
      "name": "dialog-20",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dialog.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/dialog/dialog-20.tsx",
          "type": "registry:component",
          "target": "components/ui/dialog-20.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { cn } from '@timui/core'\nimport {\n  Button,\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n} from '@timui/react'\nimport { ArrowRightIcon } from 'lucide-react'\n\nexport default function Component() {\n  const [step, setStep] = useState(1)\n\n  const stepContent = [\n    {\n      title: 'Welcome to Timkit UI',\n      description:\n        'Discover a powerful collection of components designed to enhance your development workflow.',\n    },\n    {\n      title: 'Customizable Components',\n      description:\n        'Each component is fully customizable and built with modern web standards in mind.',\n    },\n    {\n      title: 'Ready to Start?',\n      description: 'Begin building amazing interfaces with our comprehensive component library.',\n    },\n    {\n      title: 'Get Support',\n      description:\n        'Access our extensive documentation and community resources to make the most of Timkit UI.',\n    },\n  ]\n\n  const totalSteps = stepContent.length\n\n  const handleContinue = () => {\n    if (step < totalSteps) {\n      setStep(step + 1)\n    }\n  }\n\n  return (\n    <Dialog\n      onOpenChange={(open) => {\n        if (open) setStep(1)\n      }}\n    >\n      <DialogTrigger asChild>\n        <Button variant=\"outline\">Onboarding</Button>\n      </DialogTrigger>\n      <DialogContent className=\"gap-0 p-0 [&>button:last-child]:text-white\">\n        <div className=\"p-2\">\n          <img\n            className=\"w-full rounded-md\"\n            src=\"/dialog-content.png\"\n            width={382}\n            height={216}\n            alt=\"dialog\"\n          />\n        </div>\n        <div className=\"space-y-6 px-6 pt-3 pb-6\">\n          <DialogHeader>\n            <DialogTitle>{stepContent[step - 1].title}</DialogTitle>\n            <DialogDescription>{stepContent[step - 1].description}</DialogDescription>\n          </DialogHeader>\n          <div className=\"flex flex-col justify-between gap-4 sm:flex-row sm:items-center\">\n            <div className=\"flex justify-center space-x-1.5 max-sm:order-1\">\n              {[...Array(totalSteps)].map((_, index) => (\n                <div\n                  key={index}\n                  className={cn(\n                    'bg-primary size-1.5 rounded-full',\n                    index + 1 === step ? 'bg-primary' : 'opacity-20'\n                  )}\n                />\n              ))}\n            </div>\n            <DialogFooter>\n              <DialogClose asChild>\n                <Button type=\"button\" variant=\"ghost\">\n                  Skip\n                </Button>\n              </DialogClose>\n              {step < totalSteps ? (\n                <Button className=\"group\" type=\"button\" onClick={handleContinue}>\n                  Next\n                  <ArrowRightIcon\n                    className=\"-me-1 opacity-60 transition-transform group-hover:translate-x-0.5\"\n                    size={16}\n                    aria-hidden=\"true\"\n                  />\n                </Button>\n              ) : (\n                <DialogClose asChild>\n                  <Button type=\"button\">Okay</Button>\n                </DialogClose>\n              )}\n            </DialogFooter>\n          </div>\n        </div>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-20.vue",
          "target": "components/ui/dialog-20.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport { cn } from '@timui/core'\nimport { ArrowRightIcon } from 'lucide-vue-next'\nimport { Button } from '@timui/vue'\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n} from '@timui/vue'\n\nconst step = ref(1)\n\nconst stepContent = [\n  {\n    title: 'Welcome to Timkit UI',\n    description:\n      'Discover a powerful collection of components designed to enhance your development workflow.',\n  },\n  {\n    title: 'Customizable Components',\n    description: 'Each component is fully customizable and built with modern web standards in mind.',\n  },\n  {\n    title: 'Ready to Start?',\n    description: 'Begin building amazing interfaces with our comprehensive component library.',\n  },\n  {\n    title: 'Get Support',\n    description:\n      'Access our extensive documentation and community resources to make the most of Timkit UI.',\n  },\n]\n\nconst totalSteps = computed(() => stepContent.length)\n\nconst handleContinue = () => {\n  if (step.value < totalSteps.value) step.value += 1\n}\n\nconst handleOpenChange = (open: boolean) => {\n  if (open) step.value = 1\n}\n</script>\n\n<template>\n  <Dialog @update:open=\"handleOpenChange\">\n    <DialogTrigger as-child>\n      <Button variant=\"outline\">Onboarding</Button>\n    </DialogTrigger>\n    <DialogContent class=\"gap-0 p-0 [&>button:last-child]:text-white\">\n      <div class=\"p-2\">\n        <img class=\"w-full rounded-md\" src=\"/dialog-content.png\" :width=\"382\" :height=\"216\" alt=\"dialog\" />\n      </div>\n      <div class=\"space-y-6 px-6 pt-3 pb-6\">\n        <DialogHeader>\n          <DialogTitle>{{ stepContent[step - 1].title }}</DialogTitle>\n          <DialogDescription>{{ stepContent[step - 1].description }}</DialogDescription>\n        </DialogHeader>\n        <div class=\"flex flex-col justify-between gap-4 sm:flex-row sm:items-center\">\n          <div class=\"flex justify-center space-x-1.5 max-sm:order-1\">\n            <div\n              v-for=\"(_, index) in totalSteps\"\n              :key=\"index\"\n              :class=\"\n                cn('bg-primary size-1.5 rounded-full', index + 1 === step ? 'bg-primary' : 'opacity-20')\n              \"\n            />\n          </div>\n          <DialogFooter>\n            <DialogClose as-child>\n              <Button type=\"button\" variant=\"ghost\">Skip</Button>\n            </DialogClose>\n            <template v-if=\"step < totalSteps\">\n              <Button class=\"group\" type=\"button\" @click=\"handleContinue\">\n                Next\n                <ArrowRightIcon\n                  class=\"-me-1 opacity-60 transition-transform group-hover:translate-x-0.5\"\n                  :size=\"16\"\n                  aria-hidden=\"true\"\n                />\n              </Button>\n            </template>\n            <template v-else>\n              <DialogClose as-child>\n                <Button type=\"button\">Okay</Button>\n              </DialogClose>\n            </template>\n          </DialogFooter>\n        </div>\n      </div>\n    </DialogContent>\n  </Dialog>\n</template>\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-20.html",
          "target": "components/ui/dialog-20.html",
          "type": "registry:component",
          "content": "<template>\n  <Dialog on-open-change=\"${(open) => {\n        if (open) setStep(1)\n      }}\"><DialogTrigger aschild><Button variant=\"outline\">Onboarding</Button></DialogTrigger><DialogContent class=\"gap-0 p-0 [&>button:last-child]:text-white\"><div class=\"p-2\"><img class=\"w-full rounded-md\" src=\"/dialog-content.png\" width=\"${382}\" height=\"${216}\" alt=\"dialog\" /></div><div class=\"space-y-6 px-6 pt-3 pb-6\"><DialogHeader><DialogTitle>${stepContent[step - 1].title}</DialogTitle><DialogDescription>${stepContent[step - 1].description}</DialogDescription></DialogHeader><div class=\"flex flex-col justify-between gap-4 sm:flex-row sm:items-center\"><div class=\"flex justify-center space-x-1.5 max-sm:order-1\"><!-- Loop [...Array(totalSteps)] -->\n<div key=\"${index}\" class=\"${cn(\n                    'bg-primary size-1.5 rounded-full',\n                    index + 1 === step ? 'bg-primary' : 'opacity-20'\n                  )}\" />\n<!-- End Loop --></div><DialogFooter><DialogClose aschild><Button type=\"button\" variant=\"ghost\">Skip\n                </Button></DialogClose><!-- if step < totalSteps -->\n<Button class=\"group\" type=\"button\" on-click=\"${handleContinue}\">Next\n                  <ArrowRightIcon class=\"-me-1 opacity-60 transition-transform group-hover:translate-x-0.5\" size=\"${16}\" aria-hidden=\"true\" /></Button>\n<!-- else -->\n<DialogClose aschild><Button type=\"button\">Okay</Button></DialogClose>\n<!-- endif --></DialogFooter></div></div></DialogContent></Dialog>\n</template>"
        },
        {
          "path": "registry/default/components/dialog/dialog-20.wxml",
          "target": "components/ui/dialog-20/dialog-20.wxml",
          "type": "registry:component",
          "content": "<view>\n  <dialog bindchange=\"{\n        if (open) setStep(1)\n      }\"><dialogtrigger aschild><button variant=\"outline\">Onboarding</button></dialogtrigger><dialogcontent class=\"gap-0 p-0 [&>button:last-child]:text-white\"><view class=\"p-2\"><image class=\"w-full rounded-md\" src=\"/dialog-content.png\" width=\"{{382}}\" height=\"{{216}}\" alt=\"dialog\" /></view><view class=\"space-y-6 px-6 pt-3 pb-6\"><dialogheader><dialogtitle>{{ stepContent[step - 1].title }}</dialogtitle><dialogdescription>{{ stepContent[step - 1].description }}</dialogdescription></dialogheader><view class=\"flex flex-col justify-between gap-4 sm:flex-row sm:items-center\"><view class=\"flex justify-center space-x-1.5 max-sm:order-1\"><div wx:for=\"{{[...Array(totalSteps)]}}\" wx:for-item=\"_\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{index}}\" class=\"{{cn(\n                    'bg-primary size-1.5 rounded-full',\n                    index + 1 === step ? 'bg-primary' : 'opacity-20'\n                  )}}\" /></view><dialogfooter><dialogclose aschild><button type=\"button\" variant=\"ghost\">Skip\n                </button></dialogclose><block wx:if=\"{{step < totalSteps}}\">\n<button class=\"group\" type=\"button\" bindtap=\"handleContinue\">Next\n                  <arrowrighticon class=\"-me-1 opacity-60 transition-transform group-hover:translate-x-0.5\" size=\"{{16}}\" aria-hidden=\"true\" /></button>\n</block>\n<block wx:else>\n<dialogclose aschild><button type=\"button\">Okay</button></dialogclose>\n</block></dialogfooter></view></view></dialogcontent></dialog>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dialog",
          "modal",
          "onboarding",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dialog-20",
          "group": "dialog",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dialog-20",
              "path": "registry/default/components/dialog/dialog-20.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dialog-20",
              "path": "registry/default/components/dialog/dialog-20.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dialog-20",
              "path": "registry/default/components/dialog/dialog-20.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dialog-20",
              "path": "registry/default/components/dialog/dialog-20.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dialog",
        "title": "Dialog · Dismissible"
      },
      "dependencies": [
        "@timui/core",
        "@timui/react"
      ],
      "categories": [
        "dialog"
      ]
    },
    {
      "name": "dialog-21",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/command.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/dialog/dialog-21.tsx",
          "type": "registry:component",
          "target": "components/ui/dialog-21.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport {\n  CommandDialog,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandItem,\n  CommandList,\n  CommandSeparator,\n  CommandShortcut,\n} from '@timui/react'\nimport {\n  ArrowUpRightIcon,\n  CircleFadingPlusIcon,\n  FileInputIcon,\n  FolderPlusIcon,\n  SearchIcon,\n} from 'lucide-react'\n\nexport default function Component() {\n  const [open, setOpen] = React.useState(false)\n\n  React.useEffect(() => {\n    const down = (e: KeyboardEvent) => {\n      if (e.key === 'k' && (e.metaKey || e.ctrlKey)) {\n        e.preventDefault()\n        setOpen((open) => !open)\n      }\n    }\n\n    document.addEventListener('keydown', down)\n    return () => document.removeEventListener('keydown', down)\n  }, [])\n\n  return (\n    <>\n      <button\n        className=\"border-input bg-background text-foreground placeholder:text-muted-foreground/70 focus-visible:border-ring focus-visible:ring-ring/50 inline-flex h-9 w-fit rounded-md border px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px]\"\n        onClick={() => setOpen(true)}\n      >\n        <span className=\"flex grow items-center\">\n          <SearchIcon\n            className=\"text-muted-foreground/80 -ms-1 me-3\"\n            size={16}\n            aria-hidden=\"true\"\n          />\n          <span className=\"text-muted-foreground/70 font-normal\">Search</span>\n        </span>\n        <kbd className=\"bg-background text-muted-foreground/70 ms-12 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">\n          ⌘K\n        </kbd>\n      </button>\n      <CommandDialog open={open} onOpenChange={setOpen}>\n        <CommandInput placeholder=\"Type a command or search...\" />\n        <CommandList>\n          <CommandEmpty>No results found.</CommandEmpty>\n          <CommandGroup heading=\"Quick start\">\n            <CommandItem>\n              <FolderPlusIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n              <span>New folder</span>\n              <CommandShortcut className=\"justify-center\">⌘N</CommandShortcut>\n            </CommandItem>\n            <CommandItem>\n              <FileInputIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n              <span>Import document</span>\n              <CommandShortcut className=\"justify-center\">⌘I</CommandShortcut>\n            </CommandItem>\n            <CommandItem>\n              <CircleFadingPlusIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n              <span>Add block</span>\n              <CommandShortcut className=\"justify-center\">⌘B</CommandShortcut>\n            </CommandItem>\n          </CommandGroup>\n          <CommandSeparator />\n          <CommandGroup heading=\"Navigation\">\n            <CommandItem>\n              <ArrowUpRightIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n              <span>Go to dashboard</span>\n            </CommandItem>\n            <CommandItem>\n              <ArrowUpRightIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n              <span>Go to apps</span>\n            </CommandItem>\n            <CommandItem>\n              <ArrowUpRightIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n              <span>Go to connections</span>\n            </CommandItem>\n          </CommandGroup>\n        </CommandList>\n      </CommandDialog>\n    </>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-21.vue",
          "target": "components/ui/dialog-21.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { ArrowUpRightIcon, CircleFadingPlusIcon, FileInputIcon, FolderPlusIcon, SearchIcon } from 'lucide-vue-next';\nimport { CommandDialog } from '@timui/vue';\nimport { CommandEmpty } from '@timui/vue';\nimport { CommandGroup } from '@timui/vue';\nimport { CommandInput } from '@timui/vue';\nimport { CommandItem } from '@timui/vue';\nimport { CommandList } from '@timui/vue';\nimport { CommandSeparator } from '@timui/vue';\nimport { CommandShortcut } from '@timui/vue';\n\n\n\nconst open = ref(false);\n\n\nfunction setOpen(next: typeof open.value | ((prev: typeof open.value) => typeof open.value)) {\n  open.value = typeof next === 'function'\n    ? (next as (prev: typeof open.value) => typeof open.value)(open.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <button class=\"border-input bg-background text-foreground placeholder:text-muted-foreground/70 focus-visible:border-ring focus-visible:ring-ring/50 inline-flex h-9 w-fit rounded-md border px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px]\" @click=\"setOpen(true)\"><span class=\"flex grow items-center\"><SearchIcon class=\"text-muted-foreground/80 -ms-1 me-3\" :size=\"16\" aria-hidden=\"true\" /><span class=\"text-muted-foreground/70 font-normal\">Search</span></span><kbd class=\"bg-background text-muted-foreground/70 ms-12 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">⌘K\n        </kbd></button><CommandDialog :open=\"open\" @update:open=\"setOpen\"><CommandInput placeholder=\"Type a command or search...\" /><CommandList><CommandEmpty>No results found.</CommandEmpty><CommandGroup heading=\"Quick start\"><CommandItem><FolderPlusIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" /><span>New folder</span><CommandShortcut class=\"justify-center\">⌘N</CommandShortcut></CommandItem><CommandItem><FileInputIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Import document</span><CommandShortcut class=\"justify-center\">⌘I</CommandShortcut></CommandItem><CommandItem><CircleFadingPlusIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Add block</span><CommandShortcut class=\"justify-center\">⌘B</CommandShortcut></CommandItem></CommandGroup><CommandSeparator /><CommandGroup heading=\"Navigation\"><CommandItem><ArrowUpRightIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Go to dashboard</span></CommandItem><CommandItem><ArrowUpRightIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Go to apps</span></CommandItem><CommandItem><ArrowUpRightIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Go to connections</span></CommandItem></CommandGroup></CommandList></CommandDialog>\n</template>\n"
        },
        {
          "path": "registry/default/components/dialog/dialog-21.html",
          "target": "components/ui/dialog-21.html",
          "type": "registry:component",
          "content": "<template>\n  <button class=\"border-input bg-background text-foreground placeholder:text-muted-foreground/70 focus-visible:border-ring focus-visible:ring-ring/50 inline-flex h-9 w-fit rounded-md border px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px]\" on-click=\"${() => setOpen(true)}\"><span class=\"flex grow items-center\"><SearchIcon class=\"text-muted-foreground/80 -ms-1 me-3\" size=\"${16}\" aria-hidden=\"true\" /><span class=\"text-muted-foreground/70 font-normal\">Search</span></span><kbd class=\"bg-background text-muted-foreground/70 ms-12 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">⌘K\n        </kbd></button><CommandDialog open=\"${open}\" on-open-change=\"${setOpen}\"><CommandInput placeholder=\"Type a command or search...\" /><CommandList><CommandEmpty>No results found.</CommandEmpty><CommandGroup heading=\"Quick start\"><CommandItem><FolderPlusIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" /><span>New folder</span><CommandShortcut class=\"justify-center\">⌘N</CommandShortcut></CommandItem><CommandItem><FileInputIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Import document</span><CommandShortcut class=\"justify-center\">⌘I</CommandShortcut></CommandItem><CommandItem><CircleFadingPlusIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Add block</span><CommandShortcut class=\"justify-center\">⌘B</CommandShortcut></CommandItem></CommandGroup><CommandSeparator /><CommandGroup heading=\"Navigation\"><CommandItem><ArrowUpRightIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Go to dashboard</span></CommandItem><CommandItem><ArrowUpRightIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Go to apps</span></CommandItem><CommandItem><ArrowUpRightIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Go to connections</span></CommandItem></CommandGroup></CommandList></CommandDialog>\n</template>"
        },
        {
          "path": "registry/default/components/dialog/dialog-21.wxml",
          "target": "components/ui/dialog-21/dialog-21.wxml",
          "type": "registry:component",
          "content": "<view>\n  <button class=\"border-input bg-background text-foreground placeholder:text-muted-foreground/70 focus-visible:border-ring focus-visible:ring-ring/50 inline-flex h-9 w-fit rounded-md border px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px]\" bindtap=\"setOpen(true)\"><text class=\"flex grow items-center\"><searchicon class=\"text-muted-foreground/80 -ms-1 me-3\" size=\"{{16}}\" aria-hidden=\"true\" /><text class=\"text-muted-foreground/70 font-normal\">Search</text></text><kbd class=\"bg-background text-muted-foreground/70 ms-12 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">⌘K\n        </kbd></button><commanddialog open=\"{{open}}\" bindchange=\"setOpen\"><commandinput placeholder=\"Type a command or search...\" /><commandlist><commandempty>No results found.</commandempty><commandgroup heading=\"Quick start\"><commanditem><folderplusicon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" /><text>New folder</text><commandshortcut class=\"justify-center\">⌘N</commandshortcut></commanditem><commanditem><fileinputicon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" /><text>Import document</text><commandshortcut class=\"justify-center\">⌘I</commandshortcut></commanditem><commanditem><circlefadingplusicon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" /><text>Add block</text><commandshortcut class=\"justify-center\">⌘B</commandshortcut></commanditem></commandgroup><commandseparator /><commandgroup heading=\"Navigation\"><commanditem><arrowuprighticon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" /><text>Go to dashboard</text></commanditem><commanditem><arrowuprighticon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" /><text>Go to apps</text></commanditem><commanditem><arrowuprighticon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" /><text>Go to connections</text></commanditem></commandgroup></commandlist></commanddialog>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dialog",
          "modal",
          "command",
          "combobox",
          "popover",
          "search",
          "radix",
          "autocomplete",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dialog-21",
          "group": "dialog",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dialog-21",
              "path": "registry/default/components/dialog/dialog-21.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dialog-21",
              "path": "registry/default/components/dialog/dialog-21.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dialog-21",
              "path": "registry/default/components/dialog/dialog-21.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dialog-21",
              "path": "registry/default/components/dialog/dialog-21.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dialog",
        "title": "Dialog · Interactive State"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "dialog"
      ]
    },
    {
      "name": "accordion-01",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/accordion.json"
      ],
      "files": [
        {
          "path": "registry/default/components/accordion/accordion-01.tsx",
          "type": "registry:component",
          "target": "components/ui/accordion-01.tsx",
          "content": "import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@timui/react'\n\nconst items = [\n  {\n    id: '1',\n    title: 'What makes Timkit UI different?',\n    content:\n      'Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.',\n  },\n  {\n    id: '2',\n    title: 'How can I customize the components?',\n    content:\n      'Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.',\n  },\n  {\n    id: '3',\n    title: 'Is Timkit UI optimized for performance?',\n    content:\n      'Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.',\n  },\n  {\n    id: '4',\n    title: 'How accessible are the components?',\n    content:\n      'All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.',\n  },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"space-y-4\">\n      <h2 className=\"text-xl font-bold\">W/ chevron</h2>\n      <Accordion type=\"single\" collapsible className=\"w-full\" defaultValue=\"3\">\n        {items.map((item) => (\n          <AccordionItem value={item.id} key={item.id} className=\"py-2\">\n            <AccordionTrigger className=\"py-2 text-[15px] leading-6 hover:no-underline\">\n              {item.title}\n            </AccordionTrigger>\n            <AccordionContent className=\"text-muted-foreground pb-2\">\n              {item.content}\n            </AccordionContent>\n          </AccordionItem>\n        ))}\n      </Accordion>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-01.vue",
          "target": "components/ui/accordion-01.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Accordion } from '@timui/vue';\nimport { AccordionContent } from '@timui/vue';\nimport { AccordionItem } from '@timui/vue';\nimport { AccordionTrigger } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: '1',\n    title: 'What makes Timkit UI different?',\n    content:\n      'Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.',\n  },\n  {\n    id: '2',\n    title: 'How can I customize the components?',\n    content:\n      'Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.',\n  },\n  {\n    id: '3',\n    title: 'Is Timkit UI optimized for performance?',\n    content:\n      'Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.',\n  },\n  {\n    id: '4',\n    title: 'How accessible are the components?',\n    content:\n      'All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.',\n  },\n]\n\n</script>\n\n<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">W/ chevron</h2><Accordion type=\"single\" collapsible class=\"w-full\" default-value=\"3\"><AccordionItem v-for=\"(item, index) in items\" :value=\"item.id\" :key=\"item.id\" class=\"py-2\"><AccordionTrigger class=\"py-2 text-[15px] leading-6 hover:no-underline\">{{ item.title }}</AccordionTrigger><AccordionContent class=\"text-muted-foreground pb-2\">{{ item.content }}</AccordionContent></AccordionItem></Accordion></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-01.html",
          "target": "components/ui/accordion-01.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">W/ chevron</h2><Accordion type=\"single\" collapsible class=\"w-full\" default-value=\"3\"><!-- Loop items -->\n<AccordionItem value=\"${item.id}\" key=\"${item.id}\" class=\"py-2\"><AccordionTrigger class=\"py-2 text-[15px] leading-6 hover:no-underline\">${item.title}</AccordionTrigger><AccordionContent class=\"text-muted-foreground pb-2\">${item.content}</AccordionContent></AccordionItem>\n<!-- End Loop --></Accordion></div>\n</template>"
        },
        {
          "path": "registry/default/components/accordion/accordion-01.wxml",
          "target": "components/ui/accordion-01/accordion-01.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-4\"><h2 class=\"text-xl font-bold\">W/ chevron</h2><accordion type=\"single\" collapsible class=\"w-full\" default-value=\"3\"><accordionitem wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" value=\"{{item.id}}\" key=\"{{item.id}}\" class=\"py-2\"><accordiontrigger class=\"py-2 text-[15px] leading-6 hover:no-underline\">{{ item.title }}</accordiontrigger><accordioncontent class=\"text-muted-foreground pb-2\">{{ item.content }}</accordioncontent></accordionitem></accordion></view>\n</view>"
        },
        {
          "path": "registry/default/components/accordion/accordion-01.json",
          "target": "components/ui/accordion-01/accordion-01.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {\n    \"accordion\": \"../../ui/accordion\",\n    \"accordion-item\": \"../../ui/accordion-item/index\"\n  }\n}"
        },
        {
          "path": "registry/default/components/accordion/accordion-01.js",
          "target": "components/ui/accordion-01/accordion-01.js",
          "type": "registry:component",
          "content": "Component({\n  data: {\n    value: \"3\",\n    items: [\n  {\n    \"id\": \"1\",\n    \"title\": \"What makes Timkit UI different?\",\n    \"content\": \"Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.\"\n  },\n  {\n    \"id\": \"2\",\n    \"title\": \"How can I customize the components?\",\n    \"content\": \"Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.\"\n  },\n  {\n    \"id\": \"3\",\n    \"title\": \"Is Timkit UI optimized for performance?\",\n    \"content\": \"Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.\"\n  },\n  {\n    \"id\": \"4\",\n    \"title\": \"How accessible are the components?\",\n    \"content\": \"All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.\"\n  }\n]\n  },\n  methods: {\n    handleValueChange(e) {\n      this.setData({ value: e.detail.value })\n    },\n    toggleCollapsible(e) {\n      const itemIndex = e.currentTarget.dataset.itemIndex\n      const collapsibleIndex = e.currentTarget.dataset.collapsibleIndex\n      const items = this.data.items.slice()\n      const collapsible = items[itemIndex]?.collapsibles?.[collapsibleIndex]\n      if (!collapsible) return\n      collapsible.open = !collapsible.open\n      this.setData({ items })\n    }\n  }\n})"
        }
      ],
      "meta": {
        "tags": [
          "accordion",
          "radix"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "accordion-01",
          "group": "accordion",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "accordion-01",
              "path": "registry/default/components/accordion/accordion-01.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "accordion-01",
              "path": "registry/default/components/accordion/accordion-01.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "accordion-01",
              "path": "registry/default/components/accordion/accordion-01.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "accordion-01",
              "path": "registry/default/components/accordion/accordion-01.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "accordion",
        "title": "Accordion · With chevron"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "accordion"
      ]
    },
    {
      "name": "accordion-02",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/accordion.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/accordion/accordion-02.tsx",
          "type": "registry:component",
          "target": "components/ui/accordion-02.tsx",
          "content": "import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@timui/react'\nimport { PlusIcon } from 'lucide-react'\n\nconst items = [\n  {\n    id: '1',\n    title: 'What makes Timkit UI different?',\n    content:\n      'Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.',\n  },\n  {\n    id: '2',\n    title: 'How can I customize the components?',\n    content:\n      'Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.',\n  },\n  {\n    id: '3',\n    title: 'Is Timkit UI optimized for performance?',\n    content:\n      'Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.',\n  },\n  {\n    id: '4',\n    title: 'How accessible are the components?',\n    content:\n      'All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.',\n  },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"space-y-4\">\n      <h2 className=\"text-xl font-bold\">W/ plus-minus</h2>\n      <Accordion type=\"single\" collapsible className=\"w-full\" defaultValue=\"3\">\n        {items.map((item) => (\n          <AccordionItem value={item.id} key={item.id} className=\"py-2\">\n            <AccordionTrigger\n              className=\"py-2 text-[15px] leading-6 hover:no-underline [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\"\n              icon={\n                <PlusIcon\n                  size={16}\n                  className=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\"\n                  aria-hidden=\"true\"\n                />\n              }\n            >\n              {item.title}\n            </AccordionTrigger>\n            <AccordionContent className=\"text-muted-foreground pb-2\">\n              {item.content}\n            </AccordionContent>\n          </AccordionItem>\n        ))}\n      </Accordion>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-02.vue",
          "target": "components/ui/accordion-02.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { PlusIcon } from 'lucide-vue-next'\nimport { Accordion } from '@timui/vue'\nimport { AccordionContent } from '@timui/vue'\nimport { AccordionItem } from '@timui/vue'\nimport { AccordionTrigger } from '@timui/vue'\n\nconst items = [\n  {\n    id: '1',\n    title: 'What makes Timkit UI different?',\n    content:\n      'Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.',\n  },\n  {\n    id: '2',\n    title: 'How can I customize the components?',\n    content:\n      'Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.',\n  },\n  {\n    id: '3',\n    title: 'Is Timkit UI optimized for performance?',\n    content:\n      'Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.',\n  },\n  {\n    id: '4',\n    title: 'How accessible are the components?',\n    content:\n      'All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.',\n  },\n]\n</script>\n\n<template>\n  <div class=\"space-y-4\">\n    <h2 class=\"text-xl font-bold\">W/ plus-minus</h2>\n    <Accordion type=\"single\" collapsible class=\"w-full\" default-value=\"3\">\n      <AccordionItem v-for=\"item in items\" :key=\"item.id\" :value=\"item.id\" class=\"py-2\">\n        <AccordionTrigger\n          class=\"py-2 text-[15px] leading-6 hover:no-underline [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\"\n        >\n          <template #icon>\n            <PlusIcon\n              :size=\"16\"\n              class=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\"\n              aria-hidden=\"true\"\n            />\n          </template>\n          {{ item.title }}\n        </AccordionTrigger>\n        <AccordionContent class=\"text-muted-foreground pb-2\">\n          {{ item.content }}\n        </AccordionContent>\n      </AccordionItem>\n    </Accordion>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-02.html",
          "target": "components/ui/accordion-02.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">W/ plus-minus</h2><Accordion type=\"single\" collapsible class=\"w-full\" default-value=\"3\"><!-- Loop items -->\n<AccordionItem value=\"${item.id}\" key=\"${item.id}\" class=\"py-2\"><AccordionTrigger class=\"py-2 text-[15px] leading-6 hover:no-underline [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\" icon=\"${<PlusIcon\n                  size={16}\n                  className=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\"\n                  aria-hidden=\"true\"\n                />}\">${item.title}</AccordionTrigger><AccordionContent class=\"text-muted-foreground pb-2\">${item.content}</AccordionContent></AccordionItem>\n<!-- End Loop --></Accordion></div>\n</template>"
        },
        {
          "path": "registry/default/components/accordion/accordion-02.wxml",
          "target": "components/ui/accordion-02/accordion-02.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-4\"><h2 class=\"text-xl font-bold\">W/ plus-minus</h2><accordion type=\"single\" collapsible class=\"w-full\" default-value=\"3\"><accordionitem wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" value=\"{{item.id}}\" key=\"{{item.id}}\" class=\"py-2\"><accordiontrigger class=\"py-2 text-[15px] leading-6 hover:no-underline [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\" icon=\"{{<PlusIcon\n                  size={16}\n                  className=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\"\n                  aria-hidden=\"true\"\n                />}}\">{{ item.title }}</accordiontrigger><accordioncontent class=\"text-muted-foreground pb-2\">{{ item.content }}</accordioncontent></accordionitem></accordion></view>\n</view>"
        },
        {
          "path": "registry/default/components/accordion/accordion-02.json",
          "target": "components/ui/accordion-02/accordion-02.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {\n    \"accordion\": \"../../ui/accordion\",\n    \"accordion-item\": \"../../ui/accordion-item/index\"\n  }\n}"
        },
        {
          "path": "registry/default/components/accordion/accordion-02.js",
          "target": "components/ui/accordion-02/accordion-02.js",
          "type": "registry:component",
          "content": "Component({\n  data: {\n    value: \"3\",\n    items: [\n  {\n    \"id\": \"1\",\n    \"title\": \"What makes Timkit UI different?\",\n    \"content\": \"Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.\"\n  },\n  {\n    \"id\": \"2\",\n    \"title\": \"How can I customize the components?\",\n    \"content\": \"Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.\"\n  },\n  {\n    \"id\": \"3\",\n    \"title\": \"Is Timkit UI optimized for performance?\",\n    \"content\": \"Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.\"\n  },\n  {\n    \"id\": \"4\",\n    \"title\": \"How accessible are the components?\",\n    \"content\": \"All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.\"\n  }\n]\n  },\n  methods: {\n    handleValueChange(e) {\n      this.setData({ value: e.detail.value })\n    },\n    toggleCollapsible(e) {\n      const itemIndex = e.currentTarget.dataset.itemIndex\n      const collapsibleIndex = e.currentTarget.dataset.collapsibleIndex\n      const items = this.data.items.slice()\n      const collapsible = items[itemIndex]?.collapsibles?.[collapsibleIndex]\n      if (!collapsible) return\n      collapsible.open = !collapsible.open\n      this.setData({ items })\n    }\n  }\n})"
        }
      ],
      "meta": {
        "tags": [
          "accordion",
          "radix"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "accordion-02",
          "group": "accordion",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "accordion-02",
              "path": "registry/default/components/accordion/accordion-02.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "accordion-02",
              "path": "registry/default/components/accordion/accordion-02.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "accordion-02",
              "path": "registry/default/components/accordion/accordion-02.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "accordion-02",
              "path": "registry/default/components/accordion/accordion-02.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "accordion",
        "title": "Accordion · With plus-minus"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "accordion"
      ]
    },
    {
      "name": "accordion-03",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/accordion.json"
      ],
      "files": [
        {
          "path": "registry/default/components/accordion/accordion-03.tsx",
          "type": "registry:component",
          "target": "components/ui/accordion-03.tsx",
          "content": "import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@timui/react'\n\nconst items = [\n  {\n    id: '1',\n    title: 'What makes Timkit UI different?',\n    content:\n      'Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.',\n  },\n  {\n    id: '2',\n    title: 'How can I customize the components?',\n    content:\n      'Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.',\n  },\n  {\n    id: '3',\n    title: 'Is Timkit UI optimized for performance?',\n    content:\n      'Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.',\n  },\n  {\n    id: '4',\n    title: 'How accessible are the components?',\n    content:\n      'All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.',\n  },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"space-y-4\">\n      <h2 className=\"text-xl font-bold\">W/ left chevron</h2>\n      <Accordion type=\"single\" collapsible className=\"w-full\" defaultValue=\"3\">\n        {items.map((item) => (\n          <AccordionItem value={item.id} key={item.id} className=\"py-2\">\n            <AccordionTrigger className=\"justify-start gap-3 py-2 text-[15px] leading-6 hover:no-underline [&>svg]:-order-1\">\n              {item.title}\n            </AccordionTrigger>\n            <AccordionContent className=\"text-muted-foreground ps-7 pb-2\">\n              {item.content}\n            </AccordionContent>\n          </AccordionItem>\n        ))}\n      </Accordion>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-03.vue",
          "target": "components/ui/accordion-03.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Accordion } from '@timui/vue';\nimport { AccordionContent } from '@timui/vue';\nimport { AccordionItem } from '@timui/vue';\nimport { AccordionTrigger } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: '1',\n    title: 'What makes Timkit UI different?',\n    content:\n      'Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.',\n  },\n  {\n    id: '2',\n    title: 'How can I customize the components?',\n    content:\n      'Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.',\n  },\n  {\n    id: '3',\n    title: 'Is Timkit UI optimized for performance?',\n    content:\n      'Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.',\n  },\n  {\n    id: '4',\n    title: 'How accessible are the components?',\n    content:\n      'All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.',\n  },\n]\n\n</script>\n\n<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">W/ left chevron</h2><Accordion type=\"single\" collapsible class=\"w-full\" default-value=\"3\"><AccordionItem v-for=\"(item, index) in items\" :value=\"item.id\" :key=\"item.id\" class=\"py-2\"><AccordionTrigger class=\"justify-start gap-3 py-2 text-[15px] leading-6 hover:no-underline [&>svg]:-order-1\">{{ item.title }}</AccordionTrigger><AccordionContent class=\"text-muted-foreground ps-7 pb-2\">{{ item.content }}</AccordionContent></AccordionItem></Accordion></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-03.html",
          "target": "components/ui/accordion-03.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">W/ left chevron</h2><Accordion type=\"single\" collapsible class=\"w-full\" default-value=\"3\"><!-- Loop items -->\n<AccordionItem value=\"${item.id}\" key=\"${item.id}\" class=\"py-2\"><AccordionTrigger class=\"justify-start gap-3 py-2 text-[15px] leading-6 hover:no-underline [&>svg]:-order-1\">${item.title}</AccordionTrigger><AccordionContent class=\"text-muted-foreground ps-7 pb-2\">${item.content}</AccordionContent></AccordionItem>\n<!-- End Loop --></Accordion></div>\n</template>"
        },
        {
          "path": "registry/default/components/accordion/accordion-03.wxml",
          "target": "components/ui/accordion-03/accordion-03.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-4\"><h2 class=\"text-xl font-bold\">W/ left chevron</h2><accordion type=\"single\" collapsible class=\"w-full\" default-value=\"3\"><accordionitem wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" value=\"{{item.id}}\" key=\"{{item.id}}\" class=\"py-2\"><accordiontrigger class=\"justify-start gap-3 py-2 text-[15px] leading-6 hover:no-underline [&>svg]:-order-1\">{{ item.title }}</accordiontrigger><accordioncontent class=\"text-muted-foreground ps-7 pb-2\">{{ item.content }}</accordioncontent></accordionitem></accordion></view>\n</view>"
        },
        {
          "path": "registry/default/components/accordion/accordion-03.json",
          "target": "components/ui/accordion-03/accordion-03.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {\n    \"accordion\": \"../../ui/accordion\",\n    \"accordion-item\": \"../../ui/accordion-item/index\"\n  }\n}"
        },
        {
          "path": "registry/default/components/accordion/accordion-03.js",
          "target": "components/ui/accordion-03/accordion-03.js",
          "type": "registry:component",
          "content": "Component({\n  data: {\n    value: \"3\",\n    items: [\n  {\n    \"id\": \"1\",\n    \"title\": \"What makes Timkit UI different?\",\n    \"content\": \"Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.\"\n  },\n  {\n    \"id\": \"2\",\n    \"title\": \"How can I customize the components?\",\n    \"content\": \"Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.\"\n  },\n  {\n    \"id\": \"3\",\n    \"title\": \"Is Timkit UI optimized for performance?\",\n    \"content\": \"Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.\"\n  },\n  {\n    \"id\": \"4\",\n    \"title\": \"How accessible are the components?\",\n    \"content\": \"All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.\"\n  }\n]\n  },\n  methods: {\n    handleValueChange(e) {\n      this.setData({ value: e.detail.value })\n    },\n    toggleCollapsible(e) {\n      const itemIndex = e.currentTarget.dataset.itemIndex\n      const collapsibleIndex = e.currentTarget.dataset.collapsibleIndex\n      const items = this.data.items.slice()\n      const collapsible = items[itemIndex]?.collapsibles?.[collapsibleIndex]\n      if (!collapsible) return\n      collapsible.open = !collapsible.open\n      this.setData({ items })\n    }\n  }\n})"
        }
      ],
      "meta": {
        "tags": [
          "accordion",
          "radix"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "accordion-03",
          "group": "accordion",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "accordion-03",
              "path": "registry/default/components/accordion/accordion-03.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "accordion-03",
              "path": "registry/default/components/accordion/accordion-03.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "accordion-03",
              "path": "registry/default/components/accordion/accordion-03.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "accordion-03",
              "path": "registry/default/components/accordion/accordion-03.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "accordion",
        "title": "Accordion · With left chevron"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "accordion"
      ]
    },
    {
      "name": "accordion-04",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/accordion.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/accordion/accordion-04.tsx",
          "type": "registry:component",
          "target": "components/ui/accordion-04.tsx",
          "content": "import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@timui/react'\nimport { PlusIcon } from 'lucide-react'\n\nconst items = [\n  {\n    id: '1',\n    title: 'What makes Timkit UI different?',\n    content:\n      'Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.',\n  },\n  {\n    id: '2',\n    title: 'How can I customize the components?',\n    content:\n      'Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.',\n  },\n  {\n    id: '3',\n    title: 'Is Timkit UI optimized for performance?',\n    content:\n      'Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.',\n  },\n  {\n    id: '4',\n    title: 'How accessible are the components?',\n    content:\n      'All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.',\n  },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"space-y-4\">\n      <h2 className=\"text-xl font-bold\">W/ left plus-minus</h2>\n      <Accordion type=\"single\" collapsible className=\"w-full\" defaultValue=\"3\">\n        {items.map((item) => (\n          <AccordionItem value={item.id} key={item.id} className=\"py-2\">\n            <div className=\"flex\">\n              <AccordionTrigger\n                showChevron={false}\n                className=\"focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-center gap-4 rounded-md py-2 text-left text-sm text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&>svg]:-order-1 [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\"\n              >\n                {item.title}\n                <PlusIcon\n                  size={16}\n                  className=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\"\n                  aria-hidden=\"true\"\n                />\n              </AccordionTrigger>\n            </div>\n            <AccordionContent className=\"text-muted-foreground ps-7 pb-2\">\n              {item.content}\n            </AccordionContent>\n          </AccordionItem>\n        ))}\n      </Accordion>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-04.vue",
          "target": "components/ui/accordion-04.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { PlusIcon } from 'lucide-vue-next';\nimport { Accordion } from '@timui/vue';\nimport { AccordionContent } from '@timui/vue';\nimport { AccordionItem } from '@timui/vue';\nimport { AccordionTrigger } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: '1',\n    title: 'What makes Timkit UI different?',\n    content:\n      'Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.',\n  },\n  {\n    id: '2',\n    title: 'How can I customize the components?',\n    content:\n      'Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.',\n  },\n  {\n    id: '3',\n    title: 'Is Timkit UI optimized for performance?',\n    content:\n      'Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.',\n  },\n  {\n    id: '4',\n    title: 'How accessible are the components?',\n    content:\n      'All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.',\n  },\n]\n\n</script>\n\n<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">W/ left plus-minus</h2><Accordion type=\"single\" collapsible class=\"w-full\" default-value=\"3\"><AccordionItem v-for=\"(item, index) in items\" :value=\"item.id\" :key=\"item.id\" class=\"py-2\"><div class=\"flex\"><AccordionTrigger :showChevron=\"false\" class=\"focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-center gap-4 rounded-md py-2 text-left text-sm text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&>svg]:-order-1 [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\">{{ item.title }}<PlusIcon :size=\"16\" class=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\" aria-hidden=\"true\" /></AccordionTrigger></div><AccordionContent class=\"text-muted-foreground ps-7 pb-2\">{{ item.content }}</AccordionContent></AccordionItem></Accordion></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-04.html",
          "target": "components/ui/accordion-04.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">W/ left plus-minus</h2><Accordion type=\"single\" collapsible class=\"w-full\" default-value=\"3\"><!-- Loop items -->\n<AccordionItem value=\"${item.id}\" key=\"${item.id}\" class=\"py-2\"><div class=\"flex\"><AccordionTrigger showchevron=\"${false}\" class=\"focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-center gap-4 rounded-md py-2 text-left text-sm text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&>svg]:-order-1 [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\">${item.title}<PlusIcon size=\"${16}\" class=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\" aria-hidden=\"true\" /></AccordionTrigger></div><AccordionContent class=\"text-muted-foreground ps-7 pb-2\">${item.content}</AccordionContent></AccordionItem>\n<!-- End Loop --></Accordion></div>\n</template>"
        },
        {
          "path": "registry/default/components/accordion/accordion-04.wxml",
          "target": "components/ui/accordion-04/accordion-04.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-4\"><h2 class=\"text-xl font-bold\">W/ left plus-minus</h2><accordion type=\"single\" collapsible class=\"w-full\" default-value=\"3\"><accordionitem wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" value=\"{{item.id}}\" key=\"{{item.id}}\" class=\"py-2\"><view class=\"flex\"><accordiontrigger showchevron=\"{{false}}\" class=\"focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-center gap-4 rounded-md py-2 text-left text-sm text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&>svg]:-order-1 [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\">{{ item.title }}<plusicon size=\"{{16}}\" class=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\" aria-hidden=\"true\" /></accordiontrigger></view><accordioncontent class=\"text-muted-foreground ps-7 pb-2\">{{ item.content }}</accordioncontent></accordionitem></accordion></view>\n</view>"
        },
        {
          "path": "registry/default/components/accordion/accordion-04.json",
          "target": "components/ui/accordion-04/accordion-04.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {\n    \"accordion\": \"../../ui/accordion\",\n    \"accordion-item\": \"../../ui/accordion-item/index\"\n  }\n}"
        },
        {
          "path": "registry/default/components/accordion/accordion-04.js",
          "target": "components/ui/accordion-04/accordion-04.js",
          "type": "registry:component",
          "content": "Component({\n  data: {\n    value: \"3\",\n    items: [\n  {\n    \"id\": \"1\",\n    \"title\": \"What makes Timkit UI different?\",\n    \"content\": \"Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.\"\n  },\n  {\n    \"id\": \"2\",\n    \"title\": \"How can I customize the components?\",\n    \"content\": \"Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.\"\n  },\n  {\n    \"id\": \"3\",\n    \"title\": \"Is Timkit UI optimized for performance?\",\n    \"content\": \"Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.\"\n  },\n  {\n    \"id\": \"4\",\n    \"title\": \"How accessible are the components?\",\n    \"content\": \"All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.\"\n  }\n]\n  },\n  methods: {\n    handleValueChange(e) {\n      this.setData({ value: e.detail.value })\n    },\n    toggleCollapsible(e) {\n      const itemIndex = e.currentTarget.dataset.itemIndex\n      const collapsibleIndex = e.currentTarget.dataset.collapsibleIndex\n      const items = this.data.items.slice()\n      const collapsible = items[itemIndex]?.collapsibles?.[collapsibleIndex]\n      if (!collapsible) return\n      collapsible.open = !collapsible.open\n      this.setData({ items })\n    }\n  }\n})"
        }
      ],
      "meta": {
        "tags": [
          "accordion",
          "radix"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "accordion-04",
          "group": "accordion",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "accordion-04",
              "path": "registry/default/components/accordion/accordion-04.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "accordion-04",
              "path": "registry/default/components/accordion/accordion-04.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "accordion-04",
              "path": "registry/default/components/accordion/accordion-04.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "accordion-04",
              "path": "registry/default/components/accordion/accordion-04.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "accordion",
        "title": "Accordion · With left plus-minus"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "accordion"
      ]
    },
    {
      "name": "accordion-05",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/accordion.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/accordion/accordion-05.tsx",
          "type": "registry:component",
          "target": "components/ui/accordion-05.tsx",
          "content": "import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@timui/react'\nimport { AtSignIcon, CommandIcon, EclipseIcon, ZapIcon } from 'lucide-react'\n\nconst items = [\n  {\n    id: '1',\n    icon: CommandIcon,\n    title: 'What makes Timkit UI different?',\n    content:\n      'Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.',\n  },\n  {\n    id: '2',\n    icon: EclipseIcon,\n    title: 'How can I customize the components?',\n    content:\n      'Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.',\n  },\n  {\n    id: '3',\n    icon: ZapIcon,\n    title: 'Is Timkit UI optimized for performance?',\n    content:\n      'Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.',\n  },\n  {\n    id: '4',\n    icon: AtSignIcon,\n    title: 'How accessible are the components?',\n    content:\n      'All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.',\n  },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"space-y-4\">\n      <h2 className=\"text-xl font-bold\">W/ icon and chevron</h2>\n      <Accordion type=\"single\" collapsible className=\"w-full\" defaultValue=\"3\">\n        {items.map((item) => (\n          <AccordionItem value={item.id} key={item.id} className=\"py-2\">\n            <AccordionTrigger className=\"py-2 text-[15px] leading-6 hover:no-underline\">\n              <span className=\"flex items-center gap-3\">\n                <item.icon size={16} className=\"shrink-0 opacity-60\" aria-hidden=\"true\" />\n                <span>{item.title}</span>\n              </span>\n            </AccordionTrigger>\n            <AccordionContent className=\"text-muted-foreground ps-7 pb-2\">\n              {item.content}\n            </AccordionContent>\n          </AccordionItem>\n        ))}\n      </Accordion>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-05.vue",
          "target": "components/ui/accordion-05.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { AtSignIcon, CommandIcon, EclipseIcon, ZapIcon } from 'lucide-vue-next';\nimport { Accordion } from '@timui/vue';\nimport { AccordionContent } from '@timui/vue';\nimport { AccordionItem } from '@timui/vue';\nimport { AccordionTrigger } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: '1',\n    icon: CommandIcon,\n    title: 'What makes Timkit UI different?',\n    content:\n      'Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.',\n  },\n  {\n    id: '2',\n    icon: EclipseIcon,\n    title: 'How can I customize the components?',\n    content:\n      'Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.',\n  },\n  {\n    id: '3',\n    icon: ZapIcon,\n    title: 'Is Timkit UI optimized for performance?',\n    content:\n      'Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.',\n  },\n  {\n    id: '4',\n    icon: AtSignIcon,\n    title: 'How accessible are the components?',\n    content:\n      'All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.',\n  },\n]\n\n</script>\n\n<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">W/ icon and chevron</h2><Accordion type=\"single\" collapsible class=\"w-full\" default-value=\"3\"><AccordionItem v-for=\"(item, index) in items\" :value=\"item.id\" :key=\"item.id\" class=\"py-2\"><AccordionTrigger class=\"py-2 text-[15px] leading-6 hover:no-underline\"><span class=\"flex items-center gap-3\"><item.icon :size=\"16\" class=\"shrink-0 opacity-60\" aria-hidden=\"true\" /><span>{{ item.title }}</span></span></AccordionTrigger><AccordionContent class=\"text-muted-foreground ps-7 pb-2\">{{ item.content }}</AccordionContent></AccordionItem></Accordion></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-05.html",
          "target": "components/ui/accordion-05.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">W/ icon and chevron</h2><Accordion type=\"single\" collapsible class=\"w-full\" default-value=\"3\"><!-- Loop items -->\n<AccordionItem value=\"${item.id}\" key=\"${item.id}\" class=\"py-2\"><AccordionTrigger class=\"py-2 text-[15px] leading-6 hover:no-underline\"><span class=\"flex items-center gap-3\"><item.icon size=\"${16}\" class=\"shrink-0 opacity-60\" aria-hidden=\"true\" /><span>${item.title}</span></span></AccordionTrigger><AccordionContent class=\"text-muted-foreground ps-7 pb-2\">${item.content}</AccordionContent></AccordionItem>\n<!-- End Loop --></Accordion></div>\n</template>"
        },
        {
          "path": "registry/default/components/accordion/accordion-05.wxml",
          "target": "components/ui/accordion-05/accordion-05.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-4\"><h2 class=\"text-xl font-bold\">W/ icon and chevron</h2><accordion type=\"single\" collapsible class=\"w-full\" default-value=\"3\"><accordionitem wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" value=\"{{item.id}}\" key=\"{{item.id}}\" class=\"py-2\"><accordiontrigger class=\"py-2 text-[15px] leading-6 hover:no-underline\"><text class=\"flex items-center gap-3\"><item.icon size=\"{{16}}\" class=\"shrink-0 opacity-60\" aria-hidden=\"true\" /><text>{{ item.title }}</text></text></accordiontrigger><accordioncontent class=\"text-muted-foreground ps-7 pb-2\">{{ item.content }}</accordioncontent></accordionitem></accordion></view>\n</view>"
        },
        {
          "path": "registry/default/components/accordion/accordion-05.json",
          "target": "components/ui/accordion-05/accordion-05.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {\n    \"accordion\": \"../../ui/accordion\",\n    \"accordion-item\": \"../../ui/accordion-item/index\"\n  }\n}"
        },
        {
          "path": "registry/default/components/accordion/accordion-05.js",
          "target": "components/ui/accordion-05/accordion-05.js",
          "type": "registry:component",
          "content": "Component({\n  data: {\n    value: \"3\",\n    items: [\n  {\n    \"id\": \"1\",\n    \"icon\": \"CommandIcon\",\n    \"title\": \"What makes Timkit UI different?\",\n    \"content\": \"Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.\",\n    \"iconLabel\": \"Cmd\"\n  },\n  {\n    \"id\": \"2\",\n    \"icon\": \"EclipseIcon\",\n    \"title\": \"How can I customize the components?\",\n    \"content\": \"Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.\",\n    \"iconLabel\": \"Ecl\"\n  },\n  {\n    \"id\": \"3\",\n    \"icon\": \"ZapIcon\",\n    \"title\": \"Is Timkit UI optimized for performance?\",\n    \"content\": \"Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.\",\n    \"iconLabel\": \"Zap\"\n  },\n  {\n    \"id\": \"4\",\n    \"icon\": \"AtSignIcon\",\n    \"title\": \"How accessible are the components?\",\n    \"content\": \"All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.\",\n    \"iconLabel\": \"@\"\n  }\n]\n  },\n  methods: {\n    handleValueChange(e) {\n      this.setData({ value: e.detail.value })\n    },\n    toggleCollapsible(e) {\n      const itemIndex = e.currentTarget.dataset.itemIndex\n      const collapsibleIndex = e.currentTarget.dataset.collapsibleIndex\n      const items = this.data.items.slice()\n      const collapsible = items[itemIndex]?.collapsibles?.[collapsibleIndex]\n      if (!collapsible) return\n      collapsible.open = !collapsible.open\n      this.setData({ items })\n    }\n  }\n})"
        }
      ],
      "meta": {
        "tags": [
          "accordion",
          "radix"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "accordion-05",
          "group": "accordion",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "accordion-05",
              "path": "registry/default/components/accordion/accordion-05.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "accordion-05",
              "path": "registry/default/components/accordion/accordion-05.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "accordion-05",
              "path": "registry/default/components/accordion/accordion-05.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "accordion-05",
              "path": "registry/default/components/accordion/accordion-05.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "accordion",
        "title": "Accordion · With icon and chevron"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "accordion"
      ]
    },
    {
      "name": "accordion-06",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/accordion.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/accordion/accordion-06.tsx",
          "type": "registry:component",
          "target": "components/ui/accordion-06.tsx",
          "content": "import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@timui/react'\nimport { AtSignIcon, CommandIcon, EclipseIcon, PlusIcon, ZapIcon } from 'lucide-react'\n\nconst items = [\n  {\n    id: '1',\n    icon: CommandIcon,\n    title: 'What makes Timkit UI different?',\n    content:\n      'Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.',\n  },\n  {\n    id: '2',\n    icon: EclipseIcon,\n    title: 'How can I customize the components?',\n    content:\n      'Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.',\n  },\n  {\n    id: '3',\n    icon: ZapIcon,\n    title: 'Is Timkit UI optimized for performance?',\n    content:\n      'Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.',\n  },\n  {\n    id: '4',\n    icon: AtSignIcon,\n    title: 'How accessible are the components?',\n    content:\n      'All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.',\n  },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"space-y-4\">\n      <h2 className=\"text-xl font-bold\">W/ icon and plus-minus</h2>\n      <Accordion type=\"single\" collapsible className=\"w-full\" defaultValue=\"3\">\n        {items.map((item) => (\n          <AccordionItem value={item.id} key={item.id} className=\"py-2\">\n            <div className=\"flex\">\n              <AccordionTrigger\n                showChevron={false}\n                className=\"focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-center justify-between gap-4 rounded-md py-2 text-left text-sm text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\"\n              >\n                <span className=\"flex items-center gap-3\">\n                  <item.icon size={16} className=\"shrink-0 opacity-60\" aria-hidden=\"true\" />\n                  <span>{item.title}</span>\n                </span>\n                <PlusIcon\n                  size={16}\n                  className=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\"\n                  aria-hidden=\"true\"\n                />\n              </AccordionTrigger>\n            </div>\n            <AccordionContent className=\"text-muted-foreground ps-7 pb-2\">\n              {item.content}\n            </AccordionContent>\n          </AccordionItem>\n        ))}\n      </Accordion>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-06.vue",
          "target": "components/ui/accordion-06.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { AtSignIcon, CommandIcon, EclipseIcon, PlusIcon, ZapIcon } from 'lucide-vue-next';\nimport { Accordion } from '@timui/vue';\nimport { AccordionContent } from '@timui/vue';\nimport { AccordionItem } from '@timui/vue';\nimport { AccordionTrigger } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: '1',\n    icon: CommandIcon,\n    title: 'What makes Timkit UI different?',\n    content:\n      'Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.',\n  },\n  {\n    id: '2',\n    icon: EclipseIcon,\n    title: 'How can I customize the components?',\n    content:\n      'Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.',\n  },\n  {\n    id: '3',\n    icon: ZapIcon,\n    title: 'Is Timkit UI optimized for performance?',\n    content:\n      'Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.',\n  },\n  {\n    id: '4',\n    icon: AtSignIcon,\n    title: 'How accessible are the components?',\n    content:\n      'All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.',\n  },\n]\n\n</script>\n\n<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">W/ icon and plus-minus</h2><Accordion type=\"single\" collapsible class=\"w-full\" default-value=\"3\"><AccordionItem v-for=\"(item, index) in items\" :value=\"item.id\" :key=\"item.id\" class=\"py-2\"><div class=\"flex\"><AccordionTrigger :showChevron=\"false\" class=\"focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-center justify-between gap-4 rounded-md py-2 text-left text-sm text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\"><span class=\"flex items-center gap-3\"><item.icon :size=\"16\" class=\"shrink-0 opacity-60\" aria-hidden=\"true\" /><span>{{ item.title }}</span></span><PlusIcon :size=\"16\" class=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\" aria-hidden=\"true\" /></AccordionTrigger></div><AccordionContent class=\"text-muted-foreground ps-7 pb-2\">{{ item.content }}</AccordionContent></AccordionItem></Accordion></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-06.html",
          "target": "components/ui/accordion-06.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">W/ icon and plus-minus</h2><Accordion type=\"single\" collapsible class=\"w-full\" default-value=\"3\"><!-- Loop items -->\n<AccordionItem value=\"${item.id}\" key=\"${item.id}\" class=\"py-2\"><div class=\"flex\"><AccordionTrigger showchevron=\"${false}\" class=\"focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-center justify-between gap-4 rounded-md py-2 text-left text-sm text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\"><span class=\"flex items-center gap-3\"><item.icon size=\"${16}\" class=\"shrink-0 opacity-60\" aria-hidden=\"true\" /><span>${item.title}</span></span><PlusIcon size=\"${16}\" class=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\" aria-hidden=\"true\" /></AccordionTrigger></div><AccordionContent class=\"text-muted-foreground ps-7 pb-2\">${item.content}</AccordionContent></AccordionItem>\n<!-- End Loop --></Accordion></div>\n</template>"
        },
        {
          "path": "registry/default/components/accordion/accordion-06.wxml",
          "target": "components/ui/accordion-06/accordion-06.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-4\"><h2 class=\"text-xl font-bold\">W/ icon and plus-minus</h2><accordion type=\"single\" collapsible class=\"w-full\" default-value=\"3\"><accordionitem wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" value=\"{{item.id}}\" key=\"{{item.id}}\" class=\"py-2\"><view class=\"flex\"><accordiontrigger showchevron=\"{{false}}\" class=\"focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-center justify-between gap-4 rounded-md py-2 text-left text-sm text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\"><text class=\"flex items-center gap-3\"><item.icon size=\"{{16}}\" class=\"shrink-0 opacity-60\" aria-hidden=\"true\" /><text>{{ item.title }}</text></text><plusicon size=\"{{16}}\" class=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\" aria-hidden=\"true\" /></accordiontrigger></view><accordioncontent class=\"text-muted-foreground ps-7 pb-2\">{{ item.content }}</accordioncontent></accordionitem></accordion></view>\n</view>"
        },
        {
          "path": "registry/default/components/accordion/accordion-06.json",
          "target": "components/ui/accordion-06/accordion-06.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {\n    \"accordion\": \"../../ui/accordion\",\n    \"accordion-item\": \"../../ui/accordion-item/index\"\n  }\n}"
        },
        {
          "path": "registry/default/components/accordion/accordion-06.js",
          "target": "components/ui/accordion-06/accordion-06.js",
          "type": "registry:component",
          "content": "Component({\n  data: {\n    value: \"3\",\n    items: [\n  {\n    \"id\": \"1\",\n    \"icon\": \"CommandIcon\",\n    \"title\": \"What makes Timkit UI different?\",\n    \"content\": \"Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.\",\n    \"iconLabel\": \"Cmd\"\n  },\n  {\n    \"id\": \"2\",\n    \"icon\": \"EclipseIcon\",\n    \"title\": \"How can I customize the components?\",\n    \"content\": \"Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.\",\n    \"iconLabel\": \"Ecl\"\n  },\n  {\n    \"id\": \"3\",\n    \"icon\": \"ZapIcon\",\n    \"title\": \"Is Timkit UI optimized for performance?\",\n    \"content\": \"Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.\",\n    \"iconLabel\": \"Zap\"\n  },\n  {\n    \"id\": \"4\",\n    \"icon\": \"AtSignIcon\",\n    \"title\": \"How accessible are the components?\",\n    \"content\": \"All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.\",\n    \"iconLabel\": \"@\"\n  }\n]\n  },\n  methods: {\n    handleValueChange(e) {\n      this.setData({ value: e.detail.value })\n    },\n    toggleCollapsible(e) {\n      const itemIndex = e.currentTarget.dataset.itemIndex\n      const collapsibleIndex = e.currentTarget.dataset.collapsibleIndex\n      const items = this.data.items.slice()\n      const collapsible = items[itemIndex]?.collapsibles?.[collapsibleIndex]\n      if (!collapsible) return\n      collapsible.open = !collapsible.open\n      this.setData({ items })\n    }\n  }\n})"
        }
      ],
      "meta": {
        "tags": [
          "accordion",
          "radix"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "accordion-06",
          "group": "accordion",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "accordion-06",
              "path": "registry/default/components/accordion/accordion-06.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "accordion-06",
              "path": "registry/default/components/accordion/accordion-06.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "accordion-06",
              "path": "registry/default/components/accordion/accordion-06.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "accordion-06",
              "path": "registry/default/components/accordion/accordion-06.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "accordion",
        "title": "Accordion · With icon and plus-minus"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "accordion"
      ]
    },
    {
      "name": "accordion-07",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/accordion.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/accordion/accordion-07.tsx",
          "type": "registry:component",
          "target": "components/ui/accordion-07.tsx",
          "content": "import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@timui/react'\nimport { ChevronDownIcon } from 'lucide-react'\n\nconst items = [\n  {\n    id: '1',\n    title: 'Connected accounts',\n    sub: 'Manage your linked social and work accounts',\n    content:\n      'Connect your accounts from Google, GitHub, or Microsoft to enable single sign-on and streamline your workflow. Connected accounts can be used for quick login and importing your preferences across platforms. You can revoke access to any connected account at any time.',\n  },\n  {\n    id: '2',\n    title: 'Notifications',\n    sub: 'Customize your notification preferences',\n    content:\n      'Choose which updates you want to receive. You can get notifications for: security alerts, billing updates, newsletter and product announcements, usage reports, and scheduled maintenance. Notifications can be delivered via email, SMS, or push notifications on your devices.',\n  },\n  {\n    id: '3',\n    title: '2-step verification',\n    sub: 'Add an extra layer of security to your account',\n    content:\n      'Protect your account with two-factor authentication. You can use authenticator apps like Google Authenticator or Authy, receive SMS codes, or use security keys like YubiKey. We recommend using an authenticator app for the most secure experience.',\n  },\n  {\n    id: '4',\n    title: 'Contact support',\n    sub: \"We're here to help 24/7\",\n    content:\n      'Our support team is available around the ClockIcon to assist you. For billing inquiries, technical issues, or general questions, you can reach us through live chat, email at support@example.com, or schedule a call with our technical team. Premium support is available for enterprise customers.',\n  },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"space-y-4\">\n      <h2 className=\"text-xl font-bold\">W/ sub-header and chevron</h2>\n      <Accordion type=\"single\" collapsible className=\"w-full\" defaultValue=\"3\">\n        {items.map((item) => (\n          <AccordionItem value={item.id} key={item.id} className=\"py-2\">\n            <div className=\"flex\">\n              <AccordionTrigger\n                showChevron={false}\n                className=\"focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-center justify-between rounded-md py-2 text-left text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-[3px] [&[data-state=open]>svg]:rotate-180\"\n              >\n                <span className=\"flex flex-col space-y-1\">\n                  <span>{item.title}</span>\n                  {item.sub && <span className=\"text-sm font-normal\">{item.sub}</span>}\n                </span>\n                <ChevronDownIcon\n                  size={16}\n                  className=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\"\n                  aria-hidden=\"true\"\n                />\n              </AccordionTrigger>\n            </div>\n            <AccordionContent className=\"text-muted-foreground pb-2\">\n              {item.content}\n            </AccordionContent>\n          </AccordionItem>\n        ))}\n      </Accordion>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-07.vue",
          "target": "components/ui/accordion-07.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ChevronDownIcon } from 'lucide-vue-next';\nimport { Accordion } from '@timui/vue';\nimport { AccordionContent } from '@timui/vue';\nimport { AccordionItem } from '@timui/vue';\nimport { AccordionTrigger } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: '1',\n    title: 'Connected accounts',\n    sub: 'Manage your linked social and work accounts',\n    content:\n      'Connect your accounts from Google, GitHub, or Microsoft to enable single sign-on and streamline your workflow. Connected accounts can be used for quick login and importing your preferences across platforms. You can revoke access to any connected account at any time.',\n  },\n  {\n    id: '2',\n    title: 'Notifications',\n    sub: 'Customize your notification preferences',\n    content:\n      'Choose which updates you want to receive. You can get notifications for: security alerts, billing updates, newsletter and product announcements, usage reports, and scheduled maintenance. Notifications can be delivered via email, SMS, or push notifications on your devices.',\n  },\n  {\n    id: '3',\n    title: '2-step verification',\n    sub: 'Add an extra layer of security to your account',\n    content:\n      'Protect your account with two-factor authentication. You can use authenticator apps like Google Authenticator or Authy, receive SMS codes, or use security keys like YubiKey. We recommend using an authenticator app for the most secure experience.',\n  },\n  {\n    id: '4',\n    title: 'Contact support',\n    sub: \"We're here to help 24/7\",\n    content:\n      'Our support team is available around the ClockIcon to assist you. For billing inquiries, technical issues, or general questions, you can reach us through live chat, email at support@example.com, or schedule a call with our technical team. Premium support is available for enterprise customers.',\n  },\n]\n\n</script>\n\n<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">W/ sub-header and chevron</h2><Accordion type=\"single\" collapsible class=\"w-full\" default-value=\"3\"><AccordionItem v-for=\"(item, index) in items\" :value=\"item.id\" :key=\"item.id\" class=\"py-2\"><div class=\"flex\"><AccordionTrigger :showChevron=\"false\" class=\"focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-center justify-between rounded-md py-2 text-left text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-[3px] [&[data-state=open]>svg]:rotate-180\"><span class=\"flex flex-col space-y-1\"><span>{{ item.title }}</span><span v-if=\"item.sub\" class=\"text-sm font-normal\">{{ item.sub }}</span></span><ChevronDownIcon :size=\"16\" class=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\" aria-hidden=\"true\" /></AccordionTrigger></div><AccordionContent class=\"text-muted-foreground pb-2\">{{ item.content }}</AccordionContent></AccordionItem></Accordion></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-07.html",
          "target": "components/ui/accordion-07.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">W/ sub-header and chevron</h2><Accordion type=\"single\" collapsible class=\"w-full\" default-value=\"3\"><!-- Loop items -->\n<AccordionItem value=\"${item.id}\" key=\"${item.id}\" class=\"py-2\"><div class=\"flex\"><AccordionTrigger showchevron=\"${false}\" class=\"focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-center justify-between rounded-md py-2 text-left text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-[3px] [&[data-state=open]>svg]:rotate-180\"><span class=\"flex flex-col space-y-1\"><span>${item.title}</span><!-- if item.sub -->\n<span class=\"text-sm font-normal\">${item.sub}</span>\n<!-- endif --></span><ChevronDownIcon size=\"${16}\" class=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\" aria-hidden=\"true\" /></AccordionTrigger></div><AccordionContent class=\"text-muted-foreground pb-2\">${item.content}</AccordionContent></AccordionItem>\n<!-- End Loop --></Accordion></div>\n</template>"
        },
        {
          "path": "registry/default/components/accordion/accordion-07.wxml",
          "target": "components/ui/accordion-07/accordion-07.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-4\"><h2 class=\"text-xl font-bold\">W/ sub-header and chevron</h2><accordion type=\"single\" collapsible class=\"w-full\" default-value=\"3\"><accordionitem wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" value=\"{{item.id}}\" key=\"{{item.id}}\" class=\"py-2\"><view class=\"flex\"><accordiontrigger showchevron=\"{{false}}\" class=\"focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-center justify-between rounded-md py-2 text-left text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-[3px] [&[data-state=open]>svg]:rotate-180\"><text class=\"flex flex-col space-y-1\"><text>{{ item.title }}</text><text wx:if=\"{{item.sub}}\" class=\"text-sm font-normal\">{{ item.sub }}</text></text><chevrondownicon size=\"{{16}}\" class=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\" aria-hidden=\"true\" /></accordiontrigger></view><accordioncontent class=\"text-muted-foreground pb-2\">{{ item.content }}</accordioncontent></accordionitem></accordion></view>\n</view>"
        },
        {
          "path": "registry/default/components/accordion/accordion-07.json",
          "target": "components/ui/accordion-07/accordion-07.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {\n    \"accordion\": \"../../ui/accordion\",\n    \"accordion-item\": \"../../ui/accordion-item/index\"\n  }\n}"
        },
        {
          "path": "registry/default/components/accordion/accordion-07.js",
          "target": "components/ui/accordion-07/accordion-07.js",
          "type": "registry:component",
          "content": "Component({\n  data: {\n    value: \"3\",\n    items: [\n  {\n    \"id\": \"1\",\n    \"title\": \"Connected accounts\",\n    \"sub\": \"Manage your linked social and work accounts\",\n    \"content\": \"Connect your accounts from Google, GitHub, or Microsoft to enable single sign-on and streamline your workflow. Connected accounts can be used for quick login and importing your preferences across platforms. You can revoke access to any connected account at any time.\"\n  },\n  {\n    \"id\": \"2\",\n    \"title\": \"Notifications\",\n    \"sub\": \"Customize your notification preferences\",\n    \"content\": \"Choose which updates you want to receive. You can get notifications for: security alerts, billing updates, newsletter and product announcements, usage reports, and scheduled maintenance. Notifications can be delivered via email, SMS, or push notifications on your devices.\"\n  },\n  {\n    \"id\": \"3\",\n    \"title\": \"2-step verification\",\n    \"sub\": \"Add an extra layer of security to your account\",\n    \"content\": \"Protect your account with two-factor authentication. You can use authenticator apps like Google Authenticator or Authy, receive SMS codes, or use security keys like YubiKey. We recommend using an authenticator app for the most secure experience.\"\n  },\n  {\n    \"id\": \"4\",\n    \"title\": \"Contact support\",\n    \"sub\": \"We're here to help 24/7\",\n    \"content\": \"Our support team is available around the ClockIcon to assist you. For billing inquiries, technical issues, or general questions, you can reach us through live chat, email at support@example.com, or schedule a call with our technical team. Premium support is available for enterprise customers.\"\n  }\n]\n  },\n  methods: {\n    handleValueChange(e) {\n      this.setData({ value: e.detail.value })\n    },\n    toggleCollapsible(e) {\n      const itemIndex = e.currentTarget.dataset.itemIndex\n      const collapsibleIndex = e.currentTarget.dataset.collapsibleIndex\n      const items = this.data.items.slice()\n      const collapsible = items[itemIndex]?.collapsibles?.[collapsibleIndex]\n      if (!collapsible) return\n      collapsible.open = !collapsible.open\n      this.setData({ items })\n    }\n  }\n})"
        }
      ],
      "meta": {
        "tags": [
          "accordion",
          "radix"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "accordion-07",
          "group": "accordion",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "accordion-07",
              "path": "registry/default/components/accordion/accordion-07.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "accordion-07",
              "path": "registry/default/components/accordion/accordion-07.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "accordion-07",
              "path": "registry/default/components/accordion/accordion-07.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "accordion-07",
              "path": "registry/default/components/accordion/accordion-07.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "accordion",
        "title": "Accordion · With sub-header and chevron"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "accordion"
      ]
    },
    {
      "name": "accordion-08",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/accordion.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/accordion/accordion-08.tsx",
          "type": "registry:component",
          "target": "components/ui/accordion-08.tsx",
          "content": "import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@timui/react'\nimport { PlusIcon } from 'lucide-react'\n\nconst items = [\n  {\n    id: '1',\n    title: 'Connected accounts',\n    sub: 'Manage your linked social and work accounts',\n    content:\n      'Connect your accounts from Google, GitHub, or Microsoft to enable single sign-on and streamline your workflow. Connected accounts can be used for quick login and importing your preferences across platforms. You can revoke access to any connected account at any time.',\n  },\n  {\n    id: '2',\n    title: 'Notifications',\n    sub: 'Customize your notification preferences',\n    content:\n      'Choose which updates you want to receive. You can get notifications for: security alerts, billing updates, newsletter and product announcements, usage reports, and scheduled maintenance. Notifications can be delivered via email, SMS, or push notifications on your devices.',\n  },\n  {\n    id: '3',\n    title: '2-step verification',\n    sub: 'Add an extra layer of security to your account',\n    content:\n      'Protect your account with two-factor authentication. You can use authenticator apps like Google Authenticator or Authy, receive SMS codes, or use security keys like YubiKey. We recommend using an authenticator app for the most secure experience.',\n  },\n  {\n    id: '4',\n    title: 'Contact support',\n    sub: \"We're here to help 24/7\",\n    content:\n      'Our support team is available around the ClockIcon to assist you. For billing inquiries, technical issues, or general questions, you can reach us through live chat, email at support@example.com, or schedule a call with our technical team. Premium support is available for enterprise customers.',\n  },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"space-y-4\">\n      <h2 className=\"text-xl font-bold\">W/ sub-header and plus-minus</h2>\n      <Accordion type=\"single\" collapsible className=\"w-full\" defaultValue=\"3\">\n        {items.map((item) => (\n          <AccordionItem value={item.id} key={item.id} className=\"py-2\">\n            <div className=\"flex\">\n              <AccordionTrigger\n                showChevron={false}\n                className=\"focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-center justify-between rounded-md py-2 text-left text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-[3px] [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\"\n              >\n                <span className=\"flex flex-col space-y-1\">\n                  <span>{item.title}</span>\n                  {item.sub && <span className=\"text-sm font-normal\">{item.sub}</span>}\n                </span>\n                <PlusIcon\n                  size={16}\n                  className=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\"\n                  aria-hidden=\"true\"\n                />\n              </AccordionTrigger>\n            </div>\n            <AccordionContent className=\"text-muted-foreground pb-2\">\n              {item.content}\n            </AccordionContent>\n          </AccordionItem>\n        ))}\n      </Accordion>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-08.vue",
          "target": "components/ui/accordion-08.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { PlusIcon } from 'lucide-vue-next';\nimport { Accordion } from '@timui/vue';\nimport { AccordionContent } from '@timui/vue';\nimport { AccordionItem } from '@timui/vue';\nimport { AccordionTrigger } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: '1',\n    title: 'Connected accounts',\n    sub: 'Manage your linked social and work accounts',\n    content:\n      'Connect your accounts from Google, GitHub, or Microsoft to enable single sign-on and streamline your workflow. Connected accounts can be used for quick login and importing your preferences across platforms. You can revoke access to any connected account at any time.',\n  },\n  {\n    id: '2',\n    title: 'Notifications',\n    sub: 'Customize your notification preferences',\n    content:\n      'Choose which updates you want to receive. You can get notifications for: security alerts, billing updates, newsletter and product announcements, usage reports, and scheduled maintenance. Notifications can be delivered via email, SMS, or push notifications on your devices.',\n  },\n  {\n    id: '3',\n    title: '2-step verification',\n    sub: 'Add an extra layer of security to your account',\n    content:\n      'Protect your account with two-factor authentication. You can use authenticator apps like Google Authenticator or Authy, receive SMS codes, or use security keys like YubiKey. We recommend using an authenticator app for the most secure experience.',\n  },\n  {\n    id: '4',\n    title: 'Contact support',\n    sub: \"We're here to help 24/7\",\n    content:\n      'Our support team is available around the ClockIcon to assist you. For billing inquiries, technical issues, or general questions, you can reach us through live chat, email at support@example.com, or schedule a call with our technical team. Premium support is available for enterprise customers.',\n  },\n]\n\n</script>\n\n<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">W/ sub-header and plus-minus</h2><Accordion type=\"single\" collapsible class=\"w-full\" default-value=\"3\"><AccordionItem v-for=\"(item, index) in items\" :value=\"item.id\" :key=\"item.id\" class=\"py-2\"><div class=\"flex\"><AccordionTrigger :showChevron=\"false\" class=\"focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-center justify-between rounded-md py-2 text-left text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-[3px] [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\"><span class=\"flex flex-col space-y-1\"><span>{{ item.title }}</span><span v-if=\"item.sub\" class=\"text-sm font-normal\">{{ item.sub }}</span></span><PlusIcon :size=\"16\" class=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\" aria-hidden=\"true\" /></AccordionTrigger></div><AccordionContent class=\"text-muted-foreground pb-2\">{{ item.content }}</AccordionContent></AccordionItem></Accordion></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-08.html",
          "target": "components/ui/accordion-08.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">W/ sub-header and plus-minus</h2><Accordion type=\"single\" collapsible class=\"w-full\" default-value=\"3\"><!-- Loop items -->\n<AccordionItem value=\"${item.id}\" key=\"${item.id}\" class=\"py-2\"><div class=\"flex\"><AccordionTrigger showchevron=\"${false}\" class=\"focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-center justify-between rounded-md py-2 text-left text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-[3px] [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\"><span class=\"flex flex-col space-y-1\"><span>${item.title}</span><!-- if item.sub -->\n<span class=\"text-sm font-normal\">${item.sub}</span>\n<!-- endif --></span><PlusIcon size=\"${16}\" class=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\" aria-hidden=\"true\" /></AccordionTrigger></div><AccordionContent class=\"text-muted-foreground pb-2\">${item.content}</AccordionContent></AccordionItem>\n<!-- End Loop --></Accordion></div>\n</template>"
        },
        {
          "path": "registry/default/components/accordion/accordion-08.wxml",
          "target": "components/ui/accordion-08/accordion-08.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-4\"><h2 class=\"text-xl font-bold\">W/ sub-header and plus-minus</h2><accordion type=\"single\" collapsible class=\"w-full\" default-value=\"3\"><accordionitem wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" value=\"{{item.id}}\" key=\"{{item.id}}\" class=\"py-2\"><view class=\"flex\"><accordiontrigger showchevron=\"{{false}}\" class=\"focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-center justify-between rounded-md py-2 text-left text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-[3px] [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\"><text class=\"flex flex-col space-y-1\"><text>{{ item.title }}</text><text wx:if=\"{{item.sub}}\" class=\"text-sm font-normal\">{{ item.sub }}</text></text><plusicon size=\"{{16}}\" class=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\" aria-hidden=\"true\" /></accordiontrigger></view><accordioncontent class=\"text-muted-foreground pb-2\">{{ item.content }}</accordioncontent></accordionitem></accordion></view>\n</view>"
        },
        {
          "path": "registry/default/components/accordion/accordion-08.json",
          "target": "components/ui/accordion-08/accordion-08.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {\n    \"accordion\": \"../../ui/accordion\",\n    \"accordion-item\": \"../../ui/accordion-item/index\"\n  }\n}"
        },
        {
          "path": "registry/default/components/accordion/accordion-08.js",
          "target": "components/ui/accordion-08/accordion-08.js",
          "type": "registry:component",
          "content": "Component({\n  data: {\n    value: \"3\",\n    items: [\n  {\n    \"id\": \"1\",\n    \"title\": \"Connected accounts\",\n    \"sub\": \"Manage your linked social and work accounts\",\n    \"content\": \"Connect your accounts from Google, GitHub, or Microsoft to enable single sign-on and streamline your workflow. Connected accounts can be used for quick login and importing your preferences across platforms. You can revoke access to any connected account at any time.\"\n  },\n  {\n    \"id\": \"2\",\n    \"title\": \"Notifications\",\n    \"sub\": \"Customize your notification preferences\",\n    \"content\": \"Choose which updates you want to receive. You can get notifications for: security alerts, billing updates, newsletter and product announcements, usage reports, and scheduled maintenance. Notifications can be delivered via email, SMS, or push notifications on your devices.\"\n  },\n  {\n    \"id\": \"3\",\n    \"title\": \"2-step verification\",\n    \"sub\": \"Add an extra layer of security to your account\",\n    \"content\": \"Protect your account with two-factor authentication. You can use authenticator apps like Google Authenticator or Authy, receive SMS codes, or use security keys like YubiKey. We recommend using an authenticator app for the most secure experience.\"\n  },\n  {\n    \"id\": \"4\",\n    \"title\": \"Contact support\",\n    \"sub\": \"We're here to help 24/7\",\n    \"content\": \"Our support team is available around the ClockIcon to assist you. For billing inquiries, technical issues, or general questions, you can reach us through live chat, email at support@example.com, or schedule a call with our technical team. Premium support is available for enterprise customers.\"\n  }\n]\n  },\n  methods: {\n    handleValueChange(e) {\n      this.setData({ value: e.detail.value })\n    },\n    toggleCollapsible(e) {\n      const itemIndex = e.currentTarget.dataset.itemIndex\n      const collapsibleIndex = e.currentTarget.dataset.collapsibleIndex\n      const items = this.data.items.slice()\n      const collapsible = items[itemIndex]?.collapsibles?.[collapsibleIndex]\n      if (!collapsible) return\n      collapsible.open = !collapsible.open\n      this.setData({ items })\n    }\n  }\n})"
        }
      ],
      "meta": {
        "tags": [
          "accordion",
          "radix"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "accordion-08",
          "group": "accordion",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "accordion-08",
              "path": "registry/default/components/accordion/accordion-08.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "accordion-08",
              "path": "registry/default/components/accordion/accordion-08.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "accordion-08",
              "path": "registry/default/components/accordion/accordion-08.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "accordion-08",
              "path": "registry/default/components/accordion/accordion-08.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "accordion",
        "title": "Accordion · With sub-header and plus-minus"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "accordion"
      ]
    },
    {
      "name": "accordion-09",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/accordion.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/accordion/accordion-09.tsx",
          "type": "registry:component",
          "target": "components/ui/accordion-09.tsx",
          "content": "import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@timui/react'\nimport { BellIcon, ChevronDownIcon, LifeBuoyIcon, Link2Icon, ShieldCheckIcon } from 'lucide-react'\n\nconst items = [\n  {\n    id: '1',\n    icon: Link2Icon,\n    title: 'Connected accounts',\n    sub: 'Manage your linked social and work accounts',\n    content:\n      'Connect your accounts from Google, GitHub, or Microsoft to enable single sign-on and streamline your workflow. Connected accounts can be used for quick login and importing your preferences across platforms. You can revoke access to any connected account at any time.',\n  },\n  {\n    id: '2',\n    icon: BellIcon,\n    title: 'Notifications',\n    sub: 'Customize your notification preferences',\n    content:\n      'Choose which updates you want to receive. You can get notifications for: security alerts, billing updates, newsletter and product announcements, usage reports, and scheduled maintenance. Notifications can be delivered via email, SMS, or push notifications on your devices.',\n  },\n  {\n    id: '3',\n    icon: ShieldCheckIcon,\n    title: '2-step verification',\n    sub: 'Add an extra layer of security to your account',\n    content:\n      'Protect your account with two-factor authentication. You can use authenticator apps like Google Authenticator or Authy, receive SMS codes, or use security keys like YubiKey. We recommend using an authenticator app for the most secure experience.',\n  },\n  {\n    id: '4',\n    icon: LifeBuoyIcon,\n    title: 'Contact support',\n    sub: \"We're here to help 24/7\",\n    content:\n      'Our support team is available around the ClockIcon to assist you. For billing inquiries, technical issues, or general questions, you can reach us through live chat, email at support@example.com, or schedule a call with our technical team. Premium support is available for enterprise customers.',\n  },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"space-y-4\">\n      <h2 className=\"text-xl font-bold\">W/ icon, sub-header, and chevron</h2>\n      <Accordion type=\"single\" collapsible className=\"w-full\" defaultValue=\"3\">\n        {items.map((item) => (\n          <AccordionItem value={item.id} key={item.id} className=\"py-2\">\n            <div className=\"flex\">\n              <AccordionTrigger\n                showChevron={false}\n                className=\"focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-center justify-between rounded-md py-2 text-left text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-[3px] [&[data-state=open]>svg]:rotate-180\"\n              >\n                <span className=\"flex items-center gap-3\">\n                  <span\n                    className=\"flex size-10 shrink-0 items-center justify-center rounded-full border\"\n                    aria-hidden=\"true\"\n                  >\n                    <item.icon size={16} className=\"opacity-60\" />\n                  </span>\n                  <span className=\"flex flex-col space-y-1\">\n                    <span>{item.title}</span>\n                    {item.sub && <span className=\"text-sm font-normal\">{item.sub}</span>}\n                  </span>\n                </span>\n                <ChevronDownIcon\n                  size={16}\n                  className=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\"\n                  aria-hidden=\"true\"\n                />\n              </AccordionTrigger>\n            </div>\n            <AccordionContent className=\"text-muted-foreground ms-3 ps-10 pb-2\">\n              {item.content}\n            </AccordionContent>\n          </AccordionItem>\n        ))}\n      </Accordion>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-09.vue",
          "target": "components/ui/accordion-09.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { BellIcon, ChevronDownIcon, LifeBuoyIcon, Link2Icon, ShieldCheckIcon } from 'lucide-vue-next';\nimport { Accordion } from '@timui/vue';\nimport { AccordionContent } from '@timui/vue';\nimport { AccordionItem } from '@timui/vue';\nimport { AccordionTrigger } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: '1',\n    icon: Link2Icon,\n    title: 'Connected accounts',\n    sub: 'Manage your linked social and work accounts',\n    content:\n      'Connect your accounts from Google, GitHub, or Microsoft to enable single sign-on and streamline your workflow. Connected accounts can be used for quick login and importing your preferences across platforms. You can revoke access to any connected account at any time.',\n  },\n  {\n    id: '2',\n    icon: BellIcon,\n    title: 'Notifications',\n    sub: 'Customize your notification preferences',\n    content:\n      'Choose which updates you want to receive. You can get notifications for: security alerts, billing updates, newsletter and product announcements, usage reports, and scheduled maintenance. Notifications can be delivered via email, SMS, or push notifications on your devices.',\n  },\n  {\n    id: '3',\n    icon: ShieldCheckIcon,\n    title: '2-step verification',\n    sub: 'Add an extra layer of security to your account',\n    content:\n      'Protect your account with two-factor authentication. You can use authenticator apps like Google Authenticator or Authy, receive SMS codes, or use security keys like YubiKey. We recommend using an authenticator app for the most secure experience.',\n  },\n  {\n    id: '4',\n    icon: LifeBuoyIcon,\n    title: 'Contact support',\n    sub: \"We're here to help 24/7\",\n    content:\n      'Our support team is available around the ClockIcon to assist you. For billing inquiries, technical issues, or general questions, you can reach us through live chat, email at support@example.com, or schedule a call with our technical team. Premium support is available for enterprise customers.',\n  },\n]\n\n</script>\n\n<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">W/ icon, sub-header, and chevron</h2><Accordion type=\"single\" collapsible class=\"w-full\" default-value=\"3\"><AccordionItem v-for=\"(item, index) in items\" :value=\"item.id\" :key=\"item.id\" class=\"py-2\"><div class=\"flex\"><AccordionTrigger :showChevron=\"false\" class=\"focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-center justify-between rounded-md py-2 text-left text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-[3px] [&[data-state=open]>svg]:rotate-180\"><span class=\"flex items-center gap-3\"><span class=\"flex size-10 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><item.icon :size=\"16\" class=\"opacity-60\" /></span><span class=\"flex flex-col space-y-1\"><span>{{ item.title }}</span><span v-if=\"item.sub\" class=\"text-sm font-normal\">{{ item.sub }}</span></span></span><ChevronDownIcon :size=\"16\" class=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\" aria-hidden=\"true\" /></AccordionTrigger></div><AccordionContent class=\"text-muted-foreground ms-3 ps-10 pb-2\">{{ item.content }}</AccordionContent></AccordionItem></Accordion></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-09.html",
          "target": "components/ui/accordion-09.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">W/ icon, sub-header, and chevron</h2><Accordion type=\"single\" collapsible class=\"w-full\" default-value=\"3\"><!-- Loop items -->\n<AccordionItem value=\"${item.id}\" key=\"${item.id}\" class=\"py-2\"><div class=\"flex\"><AccordionTrigger showchevron=\"${false}\" class=\"focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-center justify-between rounded-md py-2 text-left text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-[3px] [&[data-state=open]>svg]:rotate-180\"><span class=\"flex items-center gap-3\"><span class=\"flex size-10 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><item.icon size=\"${16}\" class=\"opacity-60\" /></span><span class=\"flex flex-col space-y-1\"><span>${item.title}</span><!-- if item.sub -->\n<span class=\"text-sm font-normal\">${item.sub}</span>\n<!-- endif --></span></span><ChevronDownIcon size=\"${16}\" class=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\" aria-hidden=\"true\" /></AccordionTrigger></div><AccordionContent class=\"text-muted-foreground ms-3 ps-10 pb-2\">${item.content}</AccordionContent></AccordionItem>\n<!-- End Loop --></Accordion></div>\n</template>"
        },
        {
          "path": "registry/default/components/accordion/accordion-09.wxml",
          "target": "components/ui/accordion-09/accordion-09.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-4\"><h2 class=\"text-xl font-bold\">W/ icon, sub-header, and chevron</h2><accordion type=\"single\" collapsible class=\"w-full\" default-value=\"3\"><accordionitem wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" value=\"{{item.id}}\" key=\"{{item.id}}\" class=\"py-2\"><view class=\"flex\"><accordiontrigger showchevron=\"{{false}}\" class=\"focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-center justify-between rounded-md py-2 text-left text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-[3px] [&[data-state=open]>svg]:rotate-180\"><text class=\"flex items-center gap-3\"><text class=\"flex size-10 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><item.icon size=\"{{16}}\" class=\"opacity-60\" /></text><text class=\"flex flex-col space-y-1\"><text>{{ item.title }}</text><text wx:if=\"{{item.sub}}\" class=\"text-sm font-normal\">{{ item.sub }}</text></text></text><chevrondownicon size=\"{{16}}\" class=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\" aria-hidden=\"true\" /></accordiontrigger></view><accordioncontent class=\"text-muted-foreground ms-3 ps-10 pb-2\">{{ item.content }}</accordioncontent></accordionitem></accordion></view>\n</view>"
        },
        {
          "path": "registry/default/components/accordion/accordion-09.json",
          "target": "components/ui/accordion-09/accordion-09.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {\n    \"accordion\": \"../../ui/accordion\",\n    \"accordion-item\": \"../../ui/accordion-item/index\"\n  }\n}"
        },
        {
          "path": "registry/default/components/accordion/accordion-09.js",
          "target": "components/ui/accordion-09/accordion-09.js",
          "type": "registry:component",
          "content": "Component({\n  data: {\n    value: \"3\",\n    items: [\n  {\n    \"id\": \"1\",\n    \"icon\": \"Link2Icon\",\n    \"title\": \"Connected accounts\",\n    \"sub\": \"Manage your linked social and work accounts\",\n    \"content\": \"Connect your accounts from Google, GitHub, or Microsoft to enable single sign-on and streamline your workflow. Connected accounts can be used for quick login and importing your preferences across platforms. You can revoke access to any connected account at any time.\",\n    \"iconLabel\": \"Link\"\n  },\n  {\n    \"id\": \"2\",\n    \"icon\": \"BellIcon\",\n    \"title\": \"Notifications\",\n    \"sub\": \"Customize your notification preferences\",\n    \"content\": \"Choose which updates you want to receive. You can get notifications for: security alerts, billing updates, newsletter and product announcements, usage reports, and scheduled maintenance. Notifications can be delivered via email, SMS, or push notifications on your devices.\",\n    \"iconLabel\": \"Bell\"\n  },\n  {\n    \"id\": \"3\",\n    \"icon\": \"ShieldCheckIcon\",\n    \"title\": \"2-step verification\",\n    \"sub\": \"Add an extra layer of security to your account\",\n    \"content\": \"Protect your account with two-factor authentication. You can use authenticator apps like Google Authenticator or Authy, receive SMS codes, or use security keys like YubiKey. We recommend using an authenticator app for the most secure experience.\",\n    \"iconLabel\": \"Safe\"\n  },\n  {\n    \"id\": \"4\",\n    \"icon\": \"LifeBuoyIcon\",\n    \"title\": \"Contact support\",\n    \"sub\": \"We're here to help 24/7\",\n    \"content\": \"Our support team is available around the ClockIcon to assist you. For billing inquiries, technical issues, or general questions, you can reach us through live chat, email at support@example.com, or schedule a call with our technical team. Premium support is available for enterprise customers.\",\n    \"iconLabel\": \"Help\"\n  }\n]\n  },\n  methods: {\n    handleValueChange(e) {\n      this.setData({ value: e.detail.value })\n    },\n    toggleCollapsible(e) {\n      const itemIndex = e.currentTarget.dataset.itemIndex\n      const collapsibleIndex = e.currentTarget.dataset.collapsibleIndex\n      const items = this.data.items.slice()\n      const collapsible = items[itemIndex]?.collapsibles?.[collapsibleIndex]\n      if (!collapsible) return\n      collapsible.open = !collapsible.open\n      this.setData({ items })\n    }\n  }\n})"
        }
      ],
      "meta": {
        "tags": [
          "accordion",
          "radix"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "accordion-09",
          "group": "accordion",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "accordion-09",
              "path": "registry/default/components/accordion/accordion-09.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "accordion-09",
              "path": "registry/default/components/accordion/accordion-09.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "accordion-09",
              "path": "registry/default/components/accordion/accordion-09.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "accordion-09",
              "path": "registry/default/components/accordion/accordion-09.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "accordion",
        "title": "Accordion · With icon, sub-header, and chevron"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "accordion"
      ]
    },
    {
      "name": "accordion-10",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/accordion.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/accordion/accordion-10.tsx",
          "type": "registry:component",
          "target": "components/ui/accordion-10.tsx",
          "content": "import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@timui/react'\nimport { BellIcon, LifeBuoyIcon, Link2Icon, PlusIcon, ShieldCheckIcon } from 'lucide-react'\n\nconst items = [\n  {\n    id: '1',\n    icon: Link2Icon,\n    title: 'Connected accounts',\n    sub: 'Manage your linked social and work accounts',\n    content:\n      'Connect your accounts from Google, GitHub, or Microsoft to enable single sign-on and streamline your workflow. Connected accounts can be used for quick login and importing your preferences across platforms. You can revoke access to any connected account at any time.',\n  },\n  {\n    id: '2',\n    icon: BellIcon,\n    title: 'Notifications',\n    sub: 'Customize your notification preferences',\n    content:\n      'Choose which updates you want to receive. You can get notifications for: security alerts, billing updates, newsletter and product announcements, usage reports, and scheduled maintenance. Notifications can be delivered via email, SMS, or push notifications on your devices.',\n  },\n  {\n    id: '3',\n    icon: ShieldCheckIcon,\n    title: '2-step verification',\n    sub: 'Add an extra layer of security to your account',\n    content:\n      'Protect your account with two-factor authentication. You can use authenticator apps like Google Authenticator or Authy, receive SMS codes, or use security keys like YubiKey. We recommend using an authenticator app for the most secure experience.',\n  },\n  {\n    id: '4',\n    icon: LifeBuoyIcon,\n    title: 'Contact support',\n    sub: \"We're here to help 24/7\",\n    content:\n      'Our support team is available around the ClockIcon to assist you. For billing inquiries, technical issues, or general questions, you can reach us through live chat, email at support@example.com, or schedule a call with our technical team. Premium support is available for enterprise customers.',\n  },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"space-y-4\">\n      <h2 className=\"text-xl font-bold\">W/ icon, sub-header, and plus-minus</h2>\n      <Accordion type=\"single\" collapsible className=\"w-full\" defaultValue=\"3\">\n        {items.map((item) => (\n          <AccordionItem value={item.id} key={item.id} className=\"py-2\">\n            <AccordionTrigger\n              className=\"focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-center justify-between rounded-md py-2 text-left text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-[3px] [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&>svg]:rotate-0 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\"\n              icon={\n                <PlusIcon\n                  size={16}\n                  className=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\"\n                  aria-hidden=\"true\"\n                />\n              }\n            >\n              <span className=\"flex items-center gap-3\">\n                <span\n                  className=\"flex size-10 shrink-0 items-center justify-center rounded-full border\"\n                  aria-hidden=\"true\"\n                >\n                  <item.icon size={16} className=\"opacity-60\" />\n                </span>\n                <span className=\"flex flex-col space-y-1\">\n                  <span>{item.title}</span>\n                  {item.sub && <span className=\"text-sm font-normal\">{item.sub}</span>}\n                </span>\n              </span>\n            </AccordionTrigger>\n            <AccordionContent className=\"text-muted-foreground ms-3 ps-10 pb-2\">\n              {item.content}\n            </AccordionContent>\n          </AccordionItem>\n        ))}\n      </Accordion>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-10.vue",
          "target": "components/ui/accordion-10.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { BellIcon, LifeBuoyIcon, Link2Icon, PlusIcon, ShieldCheckIcon } from 'lucide-vue-next'\nimport { Accordion } from '@timui/vue'\nimport { AccordionContent } from '@timui/vue'\nimport { AccordionItem } from '@timui/vue'\nimport { AccordionTrigger } from '@timui/vue'\n\nconst items = [\n  {\n    id: '1',\n    icon: Link2Icon,\n    title: 'Connected accounts',\n    sub: 'Manage your linked social and work accounts',\n    content:\n      'Connect your accounts from Google, GitHub, or Microsoft to enable single sign-on and streamline your workflow. Connected accounts can be used for quick login and importing your preferences across platforms. You can revoke access to any connected account at any time.',\n  },\n  {\n    id: '2',\n    icon: BellIcon,\n    title: 'Notifications',\n    sub: 'Customize your notification preferences',\n    content:\n      'Choose which updates you want to receive. You can get notifications for: security alerts, billing updates, newsletter and product announcements, usage reports, and scheduled maintenance. Notifications can be delivered via email, SMS, or push notifications on your devices.',\n  },\n  {\n    id: '3',\n    icon: ShieldCheckIcon,\n    title: '2-step verification',\n    sub: 'Add an extra layer of security to your account',\n    content:\n      'Protect your account with two-factor authentication. You can use authenticator apps like Google Authenticator or Authy, receive SMS codes, or use security keys like YubiKey. We recommend using an authenticator app for the most secure experience.',\n  },\n  {\n    id: '4',\n    icon: LifeBuoyIcon,\n    title: 'Contact support',\n    sub: \"We're here to help 24/7\",\n    content:\n      'Our support team is available around the clock to assist you. For billing inquiries, technical issues, or general questions, you can reach us through live chat, email, or schedule a call with our technical team.',\n  },\n]\n</script>\n\n<template>\n  <div class=\"space-y-4\">\n    <h2 class=\"text-xl font-bold\">W/ icon, sub-header, and plus-minus</h2>\n    <Accordion type=\"single\" collapsible class=\"w-full\" default-value=\"3\">\n      <AccordionItem v-for=\"item in items\" :key=\"item.id\" :value=\"item.id\" class=\"py-2\">\n        <AccordionTrigger\n          class=\"focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-center justify-between rounded-md py-2 text-left text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-[3px] [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&>svg]:rotate-0 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\"\n        >\n          <template #icon>\n            <PlusIcon\n              :size=\"16\"\n              class=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\"\n              aria-hidden=\"true\"\n            />\n          </template>\n          <span class=\"flex items-center gap-3\">\n            <span\n              class=\"flex size-10 shrink-0 items-center justify-center rounded-full border\"\n              aria-hidden=\"true\"\n            >\n              <component :is=\"item.icon\" :size=\"16\" class=\"opacity-60\" />\n            </span>\n            <span class=\"flex flex-col space-y-1\">\n              <span>{{ item.title }}</span>\n              <span v-if=\"item.sub\" class=\"text-sm font-normal\">{{ item.sub }}</span>\n            </span>\n          </span>\n        </AccordionTrigger>\n        <AccordionContent class=\"text-muted-foreground ms-3 ps-10 pb-2\">\n          {{ item.content }}\n        </AccordionContent>\n      </AccordionItem>\n    </Accordion>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-10.html",
          "target": "components/ui/accordion-10.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">W/ icon, sub-header, and plus-minus</h2><Accordion type=\"single\" collapsible class=\"w-full\" default-value=\"3\"><!-- Loop items -->\n<AccordionItem value=\"${item.id}\" key=\"${item.id}\" class=\"py-2\"><AccordionTrigger class=\"focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-center justify-between rounded-md py-2 text-left text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-[3px] [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&>svg]:rotate-0 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\" icon=\"${<PlusIcon\n                  size={16}\n                  className=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\"\n                  aria-hidden=\"true\"\n                />}\"><span class=\"flex items-center gap-3\"><span class=\"flex size-10 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><item.icon size=\"${16}\" class=\"opacity-60\" /></span><span class=\"flex flex-col space-y-1\"><span>${item.title}</span><!-- if item.sub -->\n<span class=\"text-sm font-normal\">${item.sub}</span>\n<!-- endif --></span></span></AccordionTrigger><AccordionContent class=\"text-muted-foreground ms-3 ps-10 pb-2\">${item.content}</AccordionContent></AccordionItem>\n<!-- End Loop --></Accordion></div>\n</template>"
        },
        {
          "path": "registry/default/components/accordion/accordion-10.wxml",
          "target": "components/ui/accordion-10/accordion-10.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-4\"><h2 class=\"text-xl font-bold\">W/ icon, sub-header, and plus-minus</h2><accordion type=\"single\" collapsible class=\"w-full\" default-value=\"3\"><accordionitem wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" value=\"{{item.id}}\" key=\"{{item.id}}\" class=\"py-2\"><accordiontrigger class=\"focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-center justify-between rounded-md py-2 text-left text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-[3px] [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&>svg]:rotate-0 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\" icon=\"{{<PlusIcon\n                  size={16}\n                  className=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\"\n                  aria-hidden=\"true\"\n                />}}\"><text class=\"flex items-center gap-3\"><text class=\"flex size-10 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><item.icon size=\"{{16}}\" class=\"opacity-60\" /></text><text class=\"flex flex-col space-y-1\"><text>{{ item.title }}</text><text wx:if=\"{{item.sub}}\" class=\"text-sm font-normal\">{{ item.sub }}</text></text></text></accordiontrigger><accordioncontent class=\"text-muted-foreground ms-3 ps-10 pb-2\">{{ item.content }}</accordioncontent></accordionitem></accordion></view>\n</view>"
        },
        {
          "path": "registry/default/components/accordion/accordion-10.json",
          "target": "components/ui/accordion-10/accordion-10.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {\n    \"accordion\": \"../../ui/accordion\",\n    \"accordion-item\": \"../../ui/accordion-item/index\"\n  }\n}"
        },
        {
          "path": "registry/default/components/accordion/accordion-10.js",
          "target": "components/ui/accordion-10/accordion-10.js",
          "type": "registry:component",
          "content": "Component({\n  data: {\n    value: \"3\",\n    items: [\n  {\n    \"id\": \"1\",\n    \"icon\": \"Link2Icon\",\n    \"title\": \"Connected accounts\",\n    \"sub\": \"Manage your linked social and work accounts\",\n    \"content\": \"Connect your accounts from Google, GitHub, or Microsoft to enable single sign-on and streamline your workflow. Connected accounts can be used for quick login and importing your preferences across platforms. You can revoke access to any connected account at any time.\",\n    \"iconLabel\": \"Link\"\n  },\n  {\n    \"id\": \"2\",\n    \"icon\": \"BellIcon\",\n    \"title\": \"Notifications\",\n    \"sub\": \"Customize your notification preferences\",\n    \"content\": \"Choose which updates you want to receive. You can get notifications for: security alerts, billing updates, newsletter and product announcements, usage reports, and scheduled maintenance. Notifications can be delivered via email, SMS, or push notifications on your devices.\",\n    \"iconLabel\": \"Bell\"\n  },\n  {\n    \"id\": \"3\",\n    \"icon\": \"ShieldCheckIcon\",\n    \"title\": \"2-step verification\",\n    \"sub\": \"Add an extra layer of security to your account\",\n    \"content\": \"Protect your account with two-factor authentication. You can use authenticator apps like Google Authenticator or Authy, receive SMS codes, or use security keys like YubiKey. We recommend using an authenticator app for the most secure experience.\",\n    \"iconLabel\": \"Safe\"\n  },\n  {\n    \"id\": \"4\",\n    \"icon\": \"LifeBuoyIcon\",\n    \"title\": \"Contact support\",\n    \"sub\": \"We're here to help 24/7\",\n    \"content\": \"Our support team is available around the ClockIcon to assist you. For billing inquiries, technical issues, or general questions, you can reach us through live chat, email at support@example.com, or schedule a call with our technical team. Premium support is available for enterprise customers.\",\n    \"iconLabel\": \"Help\"\n  }\n]\n  },\n  methods: {\n    handleValueChange(e) {\n      this.setData({ value: e.detail.value })\n    },\n    toggleCollapsible(e) {\n      const itemIndex = e.currentTarget.dataset.itemIndex\n      const collapsibleIndex = e.currentTarget.dataset.collapsibleIndex\n      const items = this.data.items.slice()\n      const collapsible = items[itemIndex]?.collapsibles?.[collapsibleIndex]\n      if (!collapsible) return\n      collapsible.open = !collapsible.open\n      this.setData({ items })\n    }\n  }\n})"
        }
      ],
      "meta": {
        "tags": [
          "accordion",
          "radix"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "accordion-10",
          "group": "accordion",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "accordion-10",
              "path": "registry/default/components/accordion/accordion-10.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "accordion-10",
              "path": "registry/default/components/accordion/accordion-10.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "accordion-10",
              "path": "registry/default/components/accordion/accordion-10.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "accordion-10",
              "path": "registry/default/components/accordion/accordion-10.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "accordion",
        "title": "Accordion · With icon, sub-header, and plus-minus"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "accordion"
      ]
    },
    {
      "name": "accordion-11",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/accordion.json"
      ],
      "files": [
        {
          "path": "registry/default/components/accordion/accordion-11.tsx",
          "type": "registry:component",
          "target": "components/ui/accordion-11.tsx",
          "content": "import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@timui/react'\n\nconst items = [\n  {\n    id: '1',\n    title: 'What makes Timkit UI different?',\n    content:\n      'Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.',\n  },\n  {\n    id: '2',\n    title: 'How can I customize the components?',\n    content:\n      'Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.',\n  },\n  {\n    id: '3',\n    title: 'Is Timkit UI optimized for performance?',\n    content:\n      'Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.',\n  },\n  {\n    id: '4',\n    title: 'How accessible are the components?',\n    content:\n      'All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.',\n  },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"space-y-4\">\n      <h2 className=\"text-xl font-bold\">Tabs w/ chevron</h2>\n      <Accordion type=\"single\" collapsible className=\"w-full space-y-2\" defaultValue=\"3\">\n        {items.map((item) => (\n          <AccordionItem\n            value={item.id}\n            key={item.id}\n            className=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 rounded-md border px-4 py-1 outline-none last:border-b has-focus-visible:ring-[3px]\"\n          >\n            <AccordionTrigger className=\"py-2 text-[15px] leading-6 hover:no-underline focus-visible:ring-0\">\n              {item.title}\n            </AccordionTrigger>\n            <AccordionContent className=\"text-muted-foreground pb-2\">\n              {item.content}\n            </AccordionContent>\n          </AccordionItem>\n        ))}\n      </Accordion>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-11.vue",
          "target": "components/ui/accordion-11.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Accordion } from '@timui/vue';\nimport { AccordionContent } from '@timui/vue';\nimport { AccordionItem } from '@timui/vue';\nimport { AccordionTrigger } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: '1',\n    title: 'What makes Timkit UI different?',\n    content:\n      'Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.',\n  },\n  {\n    id: '2',\n    title: 'How can I customize the components?',\n    content:\n      'Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.',\n  },\n  {\n    id: '3',\n    title: 'Is Timkit UI optimized for performance?',\n    content:\n      'Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.',\n  },\n  {\n    id: '4',\n    title: 'How accessible are the components?',\n    content:\n      'All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.',\n  },\n]\n\n</script>\n\n<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">Tabs w/ chevron</h2><Accordion type=\"single\" collapsible class=\"w-full space-y-2\" default-value=\"3\"><AccordionItem v-for=\"(item, index) in items\" :value=\"item.id\" :key=\"item.id\" class=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 rounded-md border px-4 py-1 outline-none last:border-b has-focus-visible:ring-[3px]\"><AccordionTrigger class=\"py-2 text-[15px] leading-6 hover:no-underline focus-visible:ring-0\">{{ item.title }}</AccordionTrigger><AccordionContent class=\"text-muted-foreground pb-2\">{{ item.content }}</AccordionContent></AccordionItem></Accordion></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-11.html",
          "target": "components/ui/accordion-11.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">Tabs w/ chevron</h2><Accordion type=\"single\" collapsible class=\"w-full space-y-2\" default-value=\"3\"><!-- Loop items -->\n<AccordionItem value=\"${item.id}\" key=\"${item.id}\" class=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 rounded-md border px-4 py-1 outline-none last:border-b has-focus-visible:ring-[3px]\"><AccordionTrigger class=\"py-2 text-[15px] leading-6 hover:no-underline focus-visible:ring-0\">${item.title}</AccordionTrigger><AccordionContent class=\"text-muted-foreground pb-2\">${item.content}</AccordionContent></AccordionItem>\n<!-- End Loop --></Accordion></div>\n</template>"
        },
        {
          "path": "registry/default/components/accordion/accordion-11.wxml",
          "target": "components/ui/accordion-11/accordion-11.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-4\"><h2 class=\"text-xl font-bold\">Tabs w/ chevron</h2><accordion type=\"single\" collapsible class=\"w-full space-y-2\" default-value=\"3\"><accordionitem wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" value=\"{{item.id}}\" key=\"{{item.id}}\" class=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 rounded-md border px-4 py-1 outline-none last:border-b has-focus-visible:ring-[3px]\"><accordiontrigger class=\"py-2 text-[15px] leading-6 hover:no-underline focus-visible:ring-0\">{{ item.title }}</accordiontrigger><accordioncontent class=\"text-muted-foreground pb-2\">{{ item.content }}</accordioncontent></accordionitem></accordion></view>\n</view>"
        },
        {
          "path": "registry/default/components/accordion/accordion-11.json",
          "target": "components/ui/accordion-11/accordion-11.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {\n    \"accordion\": \"../../ui/accordion\",\n    \"accordion-item\": \"../../ui/accordion-item/index\"\n  }\n}"
        },
        {
          "path": "registry/default/components/accordion/accordion-11.js",
          "target": "components/ui/accordion-11/accordion-11.js",
          "type": "registry:component",
          "content": "Component({\n  data: {\n    value: \"3\",\n    items: [\n  {\n    \"id\": \"1\",\n    \"title\": \"What makes Timkit UI different?\",\n    \"content\": \"Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.\"\n  },\n  {\n    \"id\": \"2\",\n    \"title\": \"How can I customize the components?\",\n    \"content\": \"Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.\"\n  },\n  {\n    \"id\": \"3\",\n    \"title\": \"Is Timkit UI optimized for performance?\",\n    \"content\": \"Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.\"\n  },\n  {\n    \"id\": \"4\",\n    \"title\": \"How accessible are the components?\",\n    \"content\": \"All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.\"\n  }\n]\n  },\n  methods: {\n    handleValueChange(e) {\n      this.setData({ value: e.detail.value })\n    },\n    toggleCollapsible(e) {\n      const itemIndex = e.currentTarget.dataset.itemIndex\n      const collapsibleIndex = e.currentTarget.dataset.collapsibleIndex\n      const items = this.data.items.slice()\n      const collapsible = items[itemIndex]?.collapsibles?.[collapsibleIndex]\n      if (!collapsible) return\n      collapsible.open = !collapsible.open\n      this.setData({ items })\n    }\n  }\n})"
        }
      ],
      "meta": {
        "tags": [
          "accordion",
          "radix"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "accordion-11",
          "group": "accordion",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "accordion-11",
              "path": "registry/default/components/accordion/accordion-11.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "accordion-11",
              "path": "registry/default/components/accordion/accordion-11.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "accordion-11",
              "path": "registry/default/components/accordion/accordion-11.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "accordion-11",
              "path": "registry/default/components/accordion/accordion-11.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "accordion",
        "title": "Accordion · Tabs w/ chevron"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "accordion"
      ]
    },
    {
      "name": "accordion-12",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/accordion.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/accordion/accordion-12.tsx",
          "type": "registry:component",
          "target": "components/ui/accordion-12.tsx",
          "content": "import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@timui/react'\nimport { PlusIcon } from 'lucide-react'\n\nconst items = [\n  {\n    id: '1',\n    title: 'What makes Timkit UI different?',\n    content:\n      'Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.',\n  },\n  {\n    id: '2',\n    title: 'How can I customize the components?',\n    content:\n      'Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.',\n  },\n  {\n    id: '3',\n    title: 'Is Timkit UI optimized for performance?',\n    content:\n      'Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.',\n  },\n  {\n    id: '4',\n    title: 'How accessible are the components?',\n    content:\n      'All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.',\n  },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"space-y-4\">\n      <h2 className=\"text-xl font-bold\">Tabs w/ plus-minus</h2>\n      <Accordion type=\"single\" collapsible className=\"w-full space-y-2\" defaultValue=\"3\">\n        {items.map((item) => (\n          <AccordionItem\n            value={item.id}\n            key={item.id}\n            className=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 rounded-md border px-4 py-1 outline-none last:border-b has-focus-visible:ring-[3px]\"\n          >\n            <div className=\"flex\">\n              <AccordionTrigger\n                showChevron={false}\n                className=\"ocus-visible:ring-0 flex flex-1 items-center justify-between rounded-md py-2 text-left text-[15px] leading-6 font-semibold transition-all outline-none [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\"\n              >\n                {item.title}\n                <PlusIcon\n                  size={16}\n                  className=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\"\n                  aria-hidden=\"true\"\n                />\n              </AccordionTrigger>\n            </div>\n            <AccordionContent className=\"text-muted-foreground pb-2\">\n              {item.content}\n            </AccordionContent>\n          </AccordionItem>\n        ))}\n      </Accordion>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-12.vue",
          "target": "components/ui/accordion-12.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { PlusIcon } from 'lucide-vue-next';\nimport { Accordion } from '@timui/vue';\nimport { AccordionContent } from '@timui/vue';\nimport { AccordionItem } from '@timui/vue';\nimport { AccordionTrigger } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: '1',\n    title: 'What makes Timkit UI different?',\n    content:\n      'Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.',\n  },\n  {\n    id: '2',\n    title: 'How can I customize the components?',\n    content:\n      'Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.',\n  },\n  {\n    id: '3',\n    title: 'Is Timkit UI optimized for performance?',\n    content:\n      'Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.',\n  },\n  {\n    id: '4',\n    title: 'How accessible are the components?',\n    content:\n      'All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.',\n  },\n]\n\n</script>\n\n<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">Tabs w/ plus-minus</h2><Accordion type=\"single\" collapsible class=\"w-full space-y-2\" default-value=\"3\"><AccordionItem v-for=\"(item, index) in items\" :value=\"item.id\" :key=\"item.id\" class=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 rounded-md border px-4 py-1 outline-none last:border-b has-focus-visible:ring-[3px]\"><div class=\"flex\"><AccordionTrigger :showChevron=\"false\" class=\"ocus-visible:ring-0 flex flex-1 items-center justify-between rounded-md py-2 text-left text-[15px] leading-6 font-semibold transition-all outline-none [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\">{{ item.title }}<PlusIcon :size=\"16\" class=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\" aria-hidden=\"true\" /></AccordionTrigger></div><AccordionContent class=\"text-muted-foreground pb-2\">{{ item.content }}</AccordionContent></AccordionItem></Accordion></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-12.html",
          "target": "components/ui/accordion-12.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">Tabs w/ plus-minus</h2><Accordion type=\"single\" collapsible class=\"w-full space-y-2\" default-value=\"3\"><!-- Loop items -->\n<AccordionItem value=\"${item.id}\" key=\"${item.id}\" class=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 rounded-md border px-4 py-1 outline-none last:border-b has-focus-visible:ring-[3px]\"><div class=\"flex\"><AccordionTrigger showchevron=\"${false}\" class=\"ocus-visible:ring-0 flex flex-1 items-center justify-between rounded-md py-2 text-left text-[15px] leading-6 font-semibold transition-all outline-none [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\">${item.title}<PlusIcon size=\"${16}\" class=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\" aria-hidden=\"true\" /></AccordionTrigger></div><AccordionContent class=\"text-muted-foreground pb-2\">${item.content}</AccordionContent></AccordionItem>\n<!-- End Loop --></Accordion></div>\n</template>"
        },
        {
          "path": "registry/default/components/accordion/accordion-12.wxml",
          "target": "components/ui/accordion-12/accordion-12.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-4\"><h2 class=\"text-xl font-bold\">Tabs w/ plus-minus</h2><accordion type=\"single\" collapsible class=\"w-full space-y-2\" default-value=\"3\"><accordionitem wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" value=\"{{item.id}}\" key=\"{{item.id}}\" class=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 rounded-md border px-4 py-1 outline-none last:border-b has-focus-visible:ring-[3px]\"><view class=\"flex\"><accordiontrigger showchevron=\"{{false}}\" class=\"ocus-visible:ring-0 flex flex-1 items-center justify-between rounded-md py-2 text-left text-[15px] leading-6 font-semibold transition-all outline-none [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\">{{ item.title }}<plusicon size=\"{{16}}\" class=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\" aria-hidden=\"true\" /></accordiontrigger></view><accordioncontent class=\"text-muted-foreground pb-2\">{{ item.content }}</accordioncontent></accordionitem></accordion></view>\n</view>"
        },
        {
          "path": "registry/default/components/accordion/accordion-12.json",
          "target": "components/ui/accordion-12/accordion-12.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {\n    \"accordion\": \"../../ui/accordion\",\n    \"accordion-item\": \"../../ui/accordion-item/index\"\n  }\n}"
        },
        {
          "path": "registry/default/components/accordion/accordion-12.js",
          "target": "components/ui/accordion-12/accordion-12.js",
          "type": "registry:component",
          "content": "Component({\n  data: {\n    value: \"3\",\n    items: [\n  {\n    \"id\": \"1\",\n    \"title\": \"What makes Timkit UI different?\",\n    \"content\": \"Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.\"\n  },\n  {\n    \"id\": \"2\",\n    \"title\": \"How can I customize the components?\",\n    \"content\": \"Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.\"\n  },\n  {\n    \"id\": \"3\",\n    \"title\": \"Is Timkit UI optimized for performance?\",\n    \"content\": \"Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.\"\n  },\n  {\n    \"id\": \"4\",\n    \"title\": \"How accessible are the components?\",\n    \"content\": \"All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.\"\n  }\n]\n  },\n  methods: {\n    handleValueChange(e) {\n      this.setData({ value: e.detail.value })\n    },\n    toggleCollapsible(e) {\n      const itemIndex = e.currentTarget.dataset.itemIndex\n      const collapsibleIndex = e.currentTarget.dataset.collapsibleIndex\n      const items = this.data.items.slice()\n      const collapsible = items[itemIndex]?.collapsibles?.[collapsibleIndex]\n      if (!collapsible) return\n      collapsible.open = !collapsible.open\n      this.setData({ items })\n    }\n  }\n})"
        }
      ],
      "meta": {
        "tags": [
          "accordion",
          "radix"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "accordion-12",
          "group": "accordion",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "accordion-12",
              "path": "registry/default/components/accordion/accordion-12.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "accordion-12",
              "path": "registry/default/components/accordion/accordion-12.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "accordion-12",
              "path": "registry/default/components/accordion/accordion-12.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "accordion-12",
              "path": "registry/default/components/accordion/accordion-12.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "accordion",
        "title": "Accordion · Tabs w/ plus-minus"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "accordion"
      ]
    },
    {
      "name": "accordion-13",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/accordion.json"
      ],
      "files": [
        {
          "path": "registry/default/components/accordion/accordion-13.tsx",
          "type": "registry:component",
          "target": "components/ui/accordion-13.tsx",
          "content": "import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@timui/react'\n\nconst items = [\n  {\n    id: '1',\n    title: 'What makes Timkit UI different?',\n    content:\n      'Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.',\n  },\n  {\n    id: '2',\n    title: 'How can I customize the components?',\n    content:\n      'Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.',\n  },\n  {\n    id: '3',\n    title: 'Is Timkit UI optimized for performance?',\n    content:\n      'Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.',\n  },\n  {\n    id: '4',\n    title: 'How accessible are the components?',\n    content:\n      'All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.',\n  },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"space-y-4\">\n      <h2 className=\"text-xl font-bold\">Tabs w/ left chevron</h2>\n      <Accordion type=\"single\" collapsible className=\"w-full space-y-2\" defaultValue=\"3\">\n        {items.map((item) => (\n          <AccordionItem\n            value={item.id}\n            key={item.id}\n            className=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 rounded-md border px-4 py-1 outline-none last:border-b has-focus-visible:ring-[3px]\"\n          >\n            <AccordionTrigger className=\"justify-start gap-3 py-2 text-[15px] leading-6 hover:no-underline focus-visible:ring-0 [&>svg]:-order-1\">\n              {item.title}\n            </AccordionTrigger>\n            <AccordionContent className=\"text-muted-foreground ps-7 pb-2\">\n              {item.content}\n            </AccordionContent>\n          </AccordionItem>\n        ))}\n      </Accordion>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-13.vue",
          "target": "components/ui/accordion-13.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Accordion } from '@timui/vue';\nimport { AccordionContent } from '@timui/vue';\nimport { AccordionItem } from '@timui/vue';\nimport { AccordionTrigger } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: '1',\n    title: 'What makes Timkit UI different?',\n    content:\n      'Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.',\n  },\n  {\n    id: '2',\n    title: 'How can I customize the components?',\n    content:\n      'Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.',\n  },\n  {\n    id: '3',\n    title: 'Is Timkit UI optimized for performance?',\n    content:\n      'Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.',\n  },\n  {\n    id: '4',\n    title: 'How accessible are the components?',\n    content:\n      'All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.',\n  },\n]\n\n</script>\n\n<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">Tabs w/ left chevron</h2><Accordion type=\"single\" collapsible class=\"w-full space-y-2\" default-value=\"3\"><AccordionItem v-for=\"(item, index) in items\" :value=\"item.id\" :key=\"item.id\" class=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 rounded-md border px-4 py-1 outline-none last:border-b has-focus-visible:ring-[3px]\"><AccordionTrigger class=\"justify-start gap-3 py-2 text-[15px] leading-6 hover:no-underline focus-visible:ring-0 [&>svg]:-order-1\">{{ item.title }}</AccordionTrigger><AccordionContent class=\"text-muted-foreground ps-7 pb-2\">{{ item.content }}</AccordionContent></AccordionItem></Accordion></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-13.html",
          "target": "components/ui/accordion-13.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">Tabs w/ left chevron</h2><Accordion type=\"single\" collapsible class=\"w-full space-y-2\" default-value=\"3\"><!-- Loop items -->\n<AccordionItem value=\"${item.id}\" key=\"${item.id}\" class=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 rounded-md border px-4 py-1 outline-none last:border-b has-focus-visible:ring-[3px]\"><AccordionTrigger class=\"justify-start gap-3 py-2 text-[15px] leading-6 hover:no-underline focus-visible:ring-0 [&>svg]:-order-1\">${item.title}</AccordionTrigger><AccordionContent class=\"text-muted-foreground ps-7 pb-2\">${item.content}</AccordionContent></AccordionItem>\n<!-- End Loop --></Accordion></div>\n</template>"
        },
        {
          "path": "registry/default/components/accordion/accordion-13.wxml",
          "target": "components/ui/accordion-13/accordion-13.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-4\"><h2 class=\"text-xl font-bold\">Tabs w/ left chevron</h2><accordion type=\"single\" collapsible class=\"w-full space-y-2\" default-value=\"3\"><accordionitem wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" value=\"{{item.id}}\" key=\"{{item.id}}\" class=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 rounded-md border px-4 py-1 outline-none last:border-b has-focus-visible:ring-[3px]\"><accordiontrigger class=\"justify-start gap-3 py-2 text-[15px] leading-6 hover:no-underline focus-visible:ring-0 [&>svg]:-order-1\">{{ item.title }}</accordiontrigger><accordioncontent class=\"text-muted-foreground ps-7 pb-2\">{{ item.content }}</accordioncontent></accordionitem></accordion></view>\n</view>"
        },
        {
          "path": "registry/default/components/accordion/accordion-13.json",
          "target": "components/ui/accordion-13/accordion-13.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {\n    \"accordion\": \"../../ui/accordion\",\n    \"accordion-item\": \"../../ui/accordion-item/index\"\n  }\n}"
        },
        {
          "path": "registry/default/components/accordion/accordion-13.js",
          "target": "components/ui/accordion-13/accordion-13.js",
          "type": "registry:component",
          "content": "Component({\n  data: {\n    value: \"3\",\n    items: [\n  {\n    \"id\": \"1\",\n    \"title\": \"What makes Timkit UI different?\",\n    \"content\": \"Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.\"\n  },\n  {\n    \"id\": \"2\",\n    \"title\": \"How can I customize the components?\",\n    \"content\": \"Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.\"\n  },\n  {\n    \"id\": \"3\",\n    \"title\": \"Is Timkit UI optimized for performance?\",\n    \"content\": \"Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.\"\n  },\n  {\n    \"id\": \"4\",\n    \"title\": \"How accessible are the components?\",\n    \"content\": \"All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.\"\n  }\n]\n  },\n  methods: {\n    handleValueChange(e) {\n      this.setData({ value: e.detail.value })\n    },\n    toggleCollapsible(e) {\n      const itemIndex = e.currentTarget.dataset.itemIndex\n      const collapsibleIndex = e.currentTarget.dataset.collapsibleIndex\n      const items = this.data.items.slice()\n      const collapsible = items[itemIndex]?.collapsibles?.[collapsibleIndex]\n      if (!collapsible) return\n      collapsible.open = !collapsible.open\n      this.setData({ items })\n    }\n  }\n})"
        }
      ],
      "meta": {
        "tags": [
          "accordion",
          "radix"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "accordion-13",
          "group": "accordion",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "accordion-13",
              "path": "registry/default/components/accordion/accordion-13.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "accordion-13",
              "path": "registry/default/components/accordion/accordion-13.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "accordion-13",
              "path": "registry/default/components/accordion/accordion-13.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "accordion-13",
              "path": "registry/default/components/accordion/accordion-13.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "accordion",
        "title": "Accordion · Tabs w/ left chevron"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "accordion"
      ]
    },
    {
      "name": "accordion-14",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/accordion.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/accordion/accordion-14.tsx",
          "type": "registry:component",
          "target": "components/ui/accordion-14.tsx",
          "content": "import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@timui/react'\nimport { PlusIcon } from 'lucide-react'\n\nconst items = [\n  {\n    id: '1',\n    title: 'What makes Timkit UI different?',\n    content:\n      'Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.',\n  },\n  {\n    id: '2',\n    title: 'How can I customize the components?',\n    content:\n      'Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.',\n  },\n  {\n    id: '3',\n    title: 'Is Timkit UI optimized for performance?',\n    content:\n      'Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.',\n  },\n  {\n    id: '4',\n    title: 'How accessible are the components?',\n    content:\n      'All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.',\n  },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"space-y-4\">\n      <h2 className=\"text-xl font-bold\">Tabs w/ left plus-minus</h2>\n      <Accordion type=\"single\" collapsible className=\"w-full space-y-2\" defaultValue=\"3\">\n        {items.map((item) => (\n          <AccordionItem\n            value={item.id}\n            key={item.id}\n            className=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 rounded-md border px-4 py-1 outline-none last:border-b has-focus-visible:ring-[3px]\"\n          >\n            <div className=\"flex\">\n              <AccordionTrigger\n                showChevron={false}\n                className=\"flex flex-1 items-center justify-between rounded-md py-2 text-left text-sm text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-0 [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\"\n              >\n                {item.title}\n                <PlusIcon\n                  size={16}\n                  className=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\"\n                  aria-hidden=\"true\"\n                />\n              </AccordionTrigger>\n            </div>\n            <AccordionContent className=\"text-muted-foreground pb-2\">\n              {item.content}\n            </AccordionContent>\n          </AccordionItem>\n        ))}\n      </Accordion>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-14.vue",
          "target": "components/ui/accordion-14.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { PlusIcon } from 'lucide-vue-next';\nimport { Accordion } from '@timui/vue';\nimport { AccordionContent } from '@timui/vue';\nimport { AccordionItem } from '@timui/vue';\nimport { AccordionTrigger } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: '1',\n    title: 'What makes Timkit UI different?',\n    content:\n      'Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.',\n  },\n  {\n    id: '2',\n    title: 'How can I customize the components?',\n    content:\n      'Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.',\n  },\n  {\n    id: '3',\n    title: 'Is Timkit UI optimized for performance?',\n    content:\n      'Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.',\n  },\n  {\n    id: '4',\n    title: 'How accessible are the components?',\n    content:\n      'All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.',\n  },\n]\n\n</script>\n\n<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">Tabs w/ left plus-minus</h2><Accordion type=\"single\" collapsible class=\"w-full space-y-2\" default-value=\"3\"><AccordionItem v-for=\"(item, index) in items\" :value=\"item.id\" :key=\"item.id\" class=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 rounded-md border px-4 py-1 outline-none last:border-b has-focus-visible:ring-[3px]\"><div class=\"flex\"><AccordionTrigger :showChevron=\"false\" class=\"flex flex-1 items-center justify-between rounded-md py-2 text-left text-sm text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-0 [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\">{{ item.title }}<PlusIcon :size=\"16\" class=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\" aria-hidden=\"true\" /></AccordionTrigger></div><AccordionContent class=\"text-muted-foreground pb-2\">{{ item.content }}</AccordionContent></AccordionItem></Accordion></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-14.html",
          "target": "components/ui/accordion-14.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">Tabs w/ left plus-minus</h2><Accordion type=\"single\" collapsible class=\"w-full space-y-2\" default-value=\"3\"><!-- Loop items -->\n<AccordionItem value=\"${item.id}\" key=\"${item.id}\" class=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 rounded-md border px-4 py-1 outline-none last:border-b has-focus-visible:ring-[3px]\"><div class=\"flex\"><AccordionTrigger showchevron=\"${false}\" class=\"flex flex-1 items-center justify-between rounded-md py-2 text-left text-sm text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-0 [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\">${item.title}<PlusIcon size=\"${16}\" class=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\" aria-hidden=\"true\" /></AccordionTrigger></div><AccordionContent class=\"text-muted-foreground pb-2\">${item.content}</AccordionContent></AccordionItem>\n<!-- End Loop --></Accordion></div>\n</template>"
        },
        {
          "path": "registry/default/components/accordion/accordion-14.wxml",
          "target": "components/ui/accordion-14/accordion-14.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-4\"><h2 class=\"text-xl font-bold\">Tabs w/ left plus-minus</h2><accordion type=\"single\" collapsible class=\"w-full space-y-2\" default-value=\"3\"><accordionitem wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" value=\"{{item.id}}\" key=\"{{item.id}}\" class=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 rounded-md border px-4 py-1 outline-none last:border-b has-focus-visible:ring-[3px]\"><view class=\"flex\"><accordiontrigger showchevron=\"{{false}}\" class=\"flex flex-1 items-center justify-between rounded-md py-2 text-left text-sm text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-0 [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\">{{ item.title }}<plusicon size=\"{{16}}\" class=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\" aria-hidden=\"true\" /></accordiontrigger></view><accordioncontent class=\"text-muted-foreground pb-2\">{{ item.content }}</accordioncontent></accordionitem></accordion></view>\n</view>"
        },
        {
          "path": "registry/default/components/accordion/accordion-14.json",
          "target": "components/ui/accordion-14/accordion-14.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {\n    \"accordion\": \"../../ui/accordion\",\n    \"accordion-item\": \"../../ui/accordion-item/index\"\n  }\n}"
        },
        {
          "path": "registry/default/components/accordion/accordion-14.js",
          "target": "components/ui/accordion-14/accordion-14.js",
          "type": "registry:component",
          "content": "Component({\n  data: {\n    value: \"3\",\n    items: [\n  {\n    \"id\": \"1\",\n    \"title\": \"What makes Timkit UI different?\",\n    \"content\": \"Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.\"\n  },\n  {\n    \"id\": \"2\",\n    \"title\": \"How can I customize the components?\",\n    \"content\": \"Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.\"\n  },\n  {\n    \"id\": \"3\",\n    \"title\": \"Is Timkit UI optimized for performance?\",\n    \"content\": \"Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.\"\n  },\n  {\n    \"id\": \"4\",\n    \"title\": \"How accessible are the components?\",\n    \"content\": \"All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.\"\n  }\n]\n  },\n  methods: {\n    handleValueChange(e) {\n      this.setData({ value: e.detail.value })\n    },\n    toggleCollapsible(e) {\n      const itemIndex = e.currentTarget.dataset.itemIndex\n      const collapsibleIndex = e.currentTarget.dataset.collapsibleIndex\n      const items = this.data.items.slice()\n      const collapsible = items[itemIndex]?.collapsibles?.[collapsibleIndex]\n      if (!collapsible) return\n      collapsible.open = !collapsible.open\n      this.setData({ items })\n    }\n  }\n})"
        }
      ],
      "meta": {
        "tags": [
          "accordion",
          "radix"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "accordion-14",
          "group": "accordion",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "accordion-14",
              "path": "registry/default/components/accordion/accordion-14.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "accordion-14",
              "path": "registry/default/components/accordion/accordion-14.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "accordion-14",
              "path": "registry/default/components/accordion/accordion-14.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "accordion-14",
              "path": "registry/default/components/accordion/accordion-14.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "accordion",
        "title": "Accordion · Tabs w/ left plus-minus"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "accordion"
      ]
    },
    {
      "name": "accordion-15",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/accordion.json"
      ],
      "files": [
        {
          "path": "registry/default/components/accordion/accordion-15.tsx",
          "type": "registry:component",
          "target": "components/ui/accordion-15.tsx",
          "content": "import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@timui/react'\n\nconst items = [\n  {\n    id: '1',\n    title: 'What makes Timkit UI different?',\n    content:\n      'Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.',\n  },\n  {\n    id: '2',\n    title: 'How can I customize the components?',\n    content:\n      'Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.',\n  },\n  {\n    id: '3',\n    title: 'Is Timkit UI optimized for performance?',\n    content:\n      'Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.',\n  },\n  {\n    id: '4',\n    title: 'How accessible are the components?',\n    content:\n      'All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.',\n  },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"space-y-4\">\n      <h2 className=\"text-xl font-bold\">Table w/ chevron</h2>\n      <Accordion type=\"single\" collapsible className=\"w-full -space-y-px\" defaultValue=\"3\">\n        {items.map((item) => (\n          <AccordionItem\n            value={item.id}\n            key={item.id}\n            className=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative border px-4 py-1 outline-none first:rounded-t-md last:rounded-b-md last:border-b has-focus-visible:z-10 has-focus-visible:ring-[3px]\"\n          >\n            <AccordionTrigger className=\"py-2 text-[15px] leading-6 hover:no-underline focus-visible:ring-0\">\n              {item.title}\n            </AccordionTrigger>\n            <AccordionContent className=\"text-muted-foreground pb-2\">\n              {item.content}\n            </AccordionContent>\n          </AccordionItem>\n        ))}\n      </Accordion>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-15.vue",
          "target": "components/ui/accordion-15.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Accordion } from '@timui/vue';\nimport { AccordionContent } from '@timui/vue';\nimport { AccordionItem } from '@timui/vue';\nimport { AccordionTrigger } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: '1',\n    title: 'What makes Timkit UI different?',\n    content:\n      'Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.',\n  },\n  {\n    id: '2',\n    title: 'How can I customize the components?',\n    content:\n      'Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.',\n  },\n  {\n    id: '3',\n    title: 'Is Timkit UI optimized for performance?',\n    content:\n      'Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.',\n  },\n  {\n    id: '4',\n    title: 'How accessible are the components?',\n    content:\n      'All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.',\n  },\n]\n\n</script>\n\n<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">Table w/ chevron</h2><Accordion type=\"single\" collapsible class=\"w-full -space-y-px\" default-value=\"3\"><AccordionItem v-for=\"(item, index) in items\" :value=\"item.id\" :key=\"item.id\" class=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative border px-4 py-1 outline-none first:rounded-t-md last:rounded-b-md last:border-b has-focus-visible:z-10 has-focus-visible:ring-[3px]\"><AccordionTrigger class=\"py-2 text-[15px] leading-6 hover:no-underline focus-visible:ring-0\">{{ item.title }}</AccordionTrigger><AccordionContent class=\"text-muted-foreground pb-2\">{{ item.content }}</AccordionContent></AccordionItem></Accordion></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-15.html",
          "target": "components/ui/accordion-15.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">Table w/ chevron</h2><Accordion type=\"single\" collapsible class=\"w-full -space-y-px\" default-value=\"3\"><!-- Loop items -->\n<AccordionItem value=\"${item.id}\" key=\"${item.id}\" class=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative border px-4 py-1 outline-none first:rounded-t-md last:rounded-b-md last:border-b has-focus-visible:z-10 has-focus-visible:ring-[3px]\"><AccordionTrigger class=\"py-2 text-[15px] leading-6 hover:no-underline focus-visible:ring-0\">${item.title}</AccordionTrigger><AccordionContent class=\"text-muted-foreground pb-2\">${item.content}</AccordionContent></AccordionItem>\n<!-- End Loop --></Accordion></div>\n</template>"
        },
        {
          "path": "registry/default/components/accordion/accordion-15.wxml",
          "target": "components/ui/accordion-15/accordion-15.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-4\"><h2 class=\"text-xl font-bold\">Table w/ chevron</h2><accordion type=\"single\" collapsible class=\"w-full -space-y-px\" default-value=\"3\"><accordionitem wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" value=\"{{item.id}}\" key=\"{{item.id}}\" class=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative border px-4 py-1 outline-none first:rounded-t-md last:rounded-b-md last:border-b has-focus-visible:z-10 has-focus-visible:ring-[3px]\"><accordiontrigger class=\"py-2 text-[15px] leading-6 hover:no-underline focus-visible:ring-0\">{{ item.title }}</accordiontrigger><accordioncontent class=\"text-muted-foreground pb-2\">{{ item.content }}</accordioncontent></accordionitem></accordion></view>\n</view>"
        },
        {
          "path": "registry/default/components/accordion/accordion-15.json",
          "target": "components/ui/accordion-15/accordion-15.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {\n    \"accordion\": \"../../ui/accordion\",\n    \"accordion-item\": \"../../ui/accordion-item/index\"\n  }\n}"
        },
        {
          "path": "registry/default/components/accordion/accordion-15.js",
          "target": "components/ui/accordion-15/accordion-15.js",
          "type": "registry:component",
          "content": "Component({\n  data: {\n    value: \"3\",\n    items: [\n  {\n    \"id\": \"1\",\n    \"title\": \"What makes Timkit UI different?\",\n    \"content\": \"Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.\"\n  },\n  {\n    \"id\": \"2\",\n    \"title\": \"How can I customize the components?\",\n    \"content\": \"Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.\"\n  },\n  {\n    \"id\": \"3\",\n    \"title\": \"Is Timkit UI optimized for performance?\",\n    \"content\": \"Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.\"\n  },\n  {\n    \"id\": \"4\",\n    \"title\": \"How accessible are the components?\",\n    \"content\": \"All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.\"\n  }\n]\n  },\n  methods: {\n    handleValueChange(e) {\n      this.setData({ value: e.detail.value })\n    },\n    toggleCollapsible(e) {\n      const itemIndex = e.currentTarget.dataset.itemIndex\n      const collapsibleIndex = e.currentTarget.dataset.collapsibleIndex\n      const items = this.data.items.slice()\n      const collapsible = items[itemIndex]?.collapsibles?.[collapsibleIndex]\n      if (!collapsible) return\n      collapsible.open = !collapsible.open\n      this.setData({ items })\n    }\n  }\n})"
        }
      ],
      "meta": {
        "tags": [
          "accordion",
          "radix"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "accordion-15",
          "group": "accordion",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "accordion-15",
              "path": "registry/default/components/accordion/accordion-15.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "accordion-15",
              "path": "registry/default/components/accordion/accordion-15.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "accordion-15",
              "path": "registry/default/components/accordion/accordion-15.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "accordion-15",
              "path": "registry/default/components/accordion/accordion-15.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "accordion",
        "title": "Accordion · Table w/ chevron"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "accordion"
      ]
    },
    {
      "name": "accordion-16",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/accordion.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/accordion/accordion-16.tsx",
          "type": "registry:component",
          "target": "components/ui/accordion-16.tsx",
          "content": "import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@timui/react'\nimport { PlusIcon } from 'lucide-react'\n\nconst items = [\n  {\n    id: '1',\n    title: 'What makes Timkit UI different?',\n    content:\n      'Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.',\n  },\n  {\n    id: '2',\n    title: 'How can I customize the components?',\n    content:\n      'Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.',\n  },\n  {\n    id: '3',\n    title: 'Is Timkit UI optimized for performance?',\n    content:\n      'Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.',\n  },\n  {\n    id: '4',\n    title: 'How accessible are the components?',\n    content:\n      'All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.',\n  },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"space-y-4\">\n      <h2 className=\"text-xl font-bold\">Table w/ plus-minus</h2>\n      <Accordion type=\"single\" collapsible className=\"w-full -space-y-px\" defaultValue=\"3\">\n        {items.map((item) => (\n          <AccordionItem\n            value={item.id}\n            key={item.id}\n            className=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative border px-4 py-1 outline-none first:rounded-t-md last:rounded-b-md last:border-b has-focus-visible:z-10 has-focus-visible:ring-[3px]\"\n          >\n            <div className=\"flex\">\n              <AccordionTrigger\n                showChevron={false}\n                className=\"flex flex-1 items-center justify-between rounded-md py-2 text-left text-sm text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-0 [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\"\n              >\n                {item.title}\n                <PlusIcon\n                  size={16}\n                  className=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\"\n                  aria-hidden=\"true\"\n                />\n              </AccordionTrigger>\n            </div>\n            <AccordionContent className=\"text-muted-foreground pb-2\">\n              {item.content}\n            </AccordionContent>\n          </AccordionItem>\n        ))}\n      </Accordion>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-16.vue",
          "target": "components/ui/accordion-16.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { PlusIcon } from 'lucide-vue-next';\nimport { Accordion } from '@timui/vue';\nimport { AccordionContent } from '@timui/vue';\nimport { AccordionItem } from '@timui/vue';\nimport { AccordionTrigger } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: '1',\n    title: 'What makes Timkit UI different?',\n    content:\n      'Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.',\n  },\n  {\n    id: '2',\n    title: 'How can I customize the components?',\n    content:\n      'Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.',\n  },\n  {\n    id: '3',\n    title: 'Is Timkit UI optimized for performance?',\n    content:\n      'Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.',\n  },\n  {\n    id: '4',\n    title: 'How accessible are the components?',\n    content:\n      'All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.',\n  },\n]\n\n</script>\n\n<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">Table w/ plus-minus</h2><Accordion type=\"single\" collapsible class=\"w-full -space-y-px\" default-value=\"3\"><AccordionItem v-for=\"(item, index) in items\" :value=\"item.id\" :key=\"item.id\" class=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative border px-4 py-1 outline-none first:rounded-t-md last:rounded-b-md last:border-b has-focus-visible:z-10 has-focus-visible:ring-[3px]\"><div class=\"flex\"><AccordionTrigger :showChevron=\"false\" class=\"flex flex-1 items-center justify-between rounded-md py-2 text-left text-sm text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-0 [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\">{{ item.title }}<PlusIcon :size=\"16\" class=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\" aria-hidden=\"true\" /></AccordionTrigger></div><AccordionContent class=\"text-muted-foreground pb-2\">{{ item.content }}</AccordionContent></AccordionItem></Accordion></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-16.html",
          "target": "components/ui/accordion-16.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">Table w/ plus-minus</h2><Accordion type=\"single\" collapsible class=\"w-full -space-y-px\" default-value=\"3\"><!-- Loop items -->\n<AccordionItem value=\"${item.id}\" key=\"${item.id}\" class=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative border px-4 py-1 outline-none first:rounded-t-md last:rounded-b-md last:border-b has-focus-visible:z-10 has-focus-visible:ring-[3px]\"><div class=\"flex\"><AccordionTrigger showchevron=\"${false}\" class=\"flex flex-1 items-center justify-between rounded-md py-2 text-left text-sm text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-0 [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\">${item.title}<PlusIcon size=\"${16}\" class=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\" aria-hidden=\"true\" /></AccordionTrigger></div><AccordionContent class=\"text-muted-foreground pb-2\">${item.content}</AccordionContent></AccordionItem>\n<!-- End Loop --></Accordion></div>\n</template>"
        },
        {
          "path": "registry/default/components/accordion/accordion-16.wxml",
          "target": "components/ui/accordion-16/accordion-16.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-4\"><h2 class=\"text-xl font-bold\">Table w/ plus-minus</h2><accordion type=\"single\" collapsible class=\"w-full -space-y-px\" default-value=\"3\"><accordionitem wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" value=\"{{item.id}}\" key=\"{{item.id}}\" class=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative border px-4 py-1 outline-none first:rounded-t-md last:rounded-b-md last:border-b has-focus-visible:z-10 has-focus-visible:ring-[3px]\"><view class=\"flex\"><accordiontrigger showchevron=\"{{false}}\" class=\"flex flex-1 items-center justify-between rounded-md py-2 text-left text-sm text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-0 [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\">{{ item.title }}<plusicon size=\"{{16}}\" class=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\" aria-hidden=\"true\" /></accordiontrigger></view><accordioncontent class=\"text-muted-foreground pb-2\">{{ item.content }}</accordioncontent></accordionitem></accordion></view>\n</view>"
        },
        {
          "path": "registry/default/components/accordion/accordion-16.json",
          "target": "components/ui/accordion-16/accordion-16.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {\n    \"accordion\": \"../../ui/accordion\",\n    \"accordion-item\": \"../../ui/accordion-item/index\"\n  }\n}"
        },
        {
          "path": "registry/default/components/accordion/accordion-16.js",
          "target": "components/ui/accordion-16/accordion-16.js",
          "type": "registry:component",
          "content": "Component({\n  data: {\n    value: \"3\",\n    items: [\n  {\n    \"id\": \"1\",\n    \"title\": \"What makes Timkit UI different?\",\n    \"content\": \"Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.\"\n  },\n  {\n    \"id\": \"2\",\n    \"title\": \"How can I customize the components?\",\n    \"content\": \"Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.\"\n  },\n  {\n    \"id\": \"3\",\n    \"title\": \"Is Timkit UI optimized for performance?\",\n    \"content\": \"Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.\"\n  },\n  {\n    \"id\": \"4\",\n    \"title\": \"How accessible are the components?\",\n    \"content\": \"All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.\"\n  }\n]\n  },\n  methods: {\n    handleValueChange(e) {\n      this.setData({ value: e.detail.value })\n    },\n    toggleCollapsible(e) {\n      const itemIndex = e.currentTarget.dataset.itemIndex\n      const collapsibleIndex = e.currentTarget.dataset.collapsibleIndex\n      const items = this.data.items.slice()\n      const collapsible = items[itemIndex]?.collapsibles?.[collapsibleIndex]\n      if (!collapsible) return\n      collapsible.open = !collapsible.open\n      this.setData({ items })\n    }\n  }\n})"
        }
      ],
      "meta": {
        "tags": [
          "accordion",
          "radix"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "accordion-16",
          "group": "accordion",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "accordion-16",
              "path": "registry/default/components/accordion/accordion-16.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "accordion-16",
              "path": "registry/default/components/accordion/accordion-16.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "accordion-16",
              "path": "registry/default/components/accordion/accordion-16.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "accordion-16",
              "path": "registry/default/components/accordion/accordion-16.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "accordion",
        "title": "Accordion · Table w/ plus-minus"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "accordion"
      ]
    },
    {
      "name": "accordion-17",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/accordion.json"
      ],
      "files": [
        {
          "path": "registry/default/components/accordion/accordion-17.tsx",
          "type": "registry:component",
          "target": "components/ui/accordion-17.tsx",
          "content": "import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@timui/react'\n\nconst items = [\n  {\n    id: '1',\n    title: 'What makes Timkit UI different?',\n    content:\n      'Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.',\n  },\n  {\n    id: '2',\n    title: 'How can I customize the components?',\n    content:\n      'Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.',\n  },\n  {\n    id: '3',\n    title: 'Is Timkit UI optimized for performance?',\n    content:\n      'Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.',\n  },\n  {\n    id: '4',\n    title: 'How accessible are the components?',\n    content:\n      'All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.',\n  },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"space-y-4\">\n      <h2 className=\"text-xl font-bold\">Table w/ left chevron</h2>\n      <Accordion type=\"single\" collapsible className=\"w-full -space-y-px\" defaultValue=\"3\">\n        {items.map((item) => (\n          <AccordionItem\n            value={item.id}\n            key={item.id}\n            className=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative border px-4 py-1 outline-none first:rounded-t-md last:rounded-b-md last:border-b has-focus-visible:z-10 has-focus-visible:ring-[3px]\"\n          >\n            <AccordionTrigger className=\"justify-start gap-3 rounded-md py-2 text-[15px] leading-6 outline-none hover:no-underline focus-visible:ring-0 [&>svg]:-order-1\">\n              {item.title}\n            </AccordionTrigger>\n            <AccordionContent className=\"text-muted-foreground ps-7 pb-2\">\n              {item.content}\n            </AccordionContent>\n          </AccordionItem>\n        ))}\n      </Accordion>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-17.vue",
          "target": "components/ui/accordion-17.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Accordion } from '@timui/vue';\nimport { AccordionContent } from '@timui/vue';\nimport { AccordionItem } from '@timui/vue';\nimport { AccordionTrigger } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: '1',\n    title: 'What makes Timkit UI different?',\n    content:\n      'Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.',\n  },\n  {\n    id: '2',\n    title: 'How can I customize the components?',\n    content:\n      'Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.',\n  },\n  {\n    id: '3',\n    title: 'Is Timkit UI optimized for performance?',\n    content:\n      'Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.',\n  },\n  {\n    id: '4',\n    title: 'How accessible are the components?',\n    content:\n      'All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.',\n  },\n]\n\n</script>\n\n<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">Table w/ left chevron</h2><Accordion type=\"single\" collapsible class=\"w-full -space-y-px\" default-value=\"3\"><AccordionItem v-for=\"(item, index) in items\" :value=\"item.id\" :key=\"item.id\" class=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative border px-4 py-1 outline-none first:rounded-t-md last:rounded-b-md last:border-b has-focus-visible:z-10 has-focus-visible:ring-[3px]\"><AccordionTrigger class=\"justify-start gap-3 rounded-md py-2 text-[15px] leading-6 outline-none hover:no-underline focus-visible:ring-0 [&>svg]:-order-1\">{{ item.title }}</AccordionTrigger><AccordionContent class=\"text-muted-foreground ps-7 pb-2\">{{ item.content }}</AccordionContent></AccordionItem></Accordion></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-17.html",
          "target": "components/ui/accordion-17.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">Table w/ left chevron</h2><Accordion type=\"single\" collapsible class=\"w-full -space-y-px\" default-value=\"3\"><!-- Loop items -->\n<AccordionItem value=\"${item.id}\" key=\"${item.id}\" class=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative border px-4 py-1 outline-none first:rounded-t-md last:rounded-b-md last:border-b has-focus-visible:z-10 has-focus-visible:ring-[3px]\"><AccordionTrigger class=\"justify-start gap-3 rounded-md py-2 text-[15px] leading-6 outline-none hover:no-underline focus-visible:ring-0 [&>svg]:-order-1\">${item.title}</AccordionTrigger><AccordionContent class=\"text-muted-foreground ps-7 pb-2\">${item.content}</AccordionContent></AccordionItem>\n<!-- End Loop --></Accordion></div>\n</template>"
        },
        {
          "path": "registry/default/components/accordion/accordion-17.wxml",
          "target": "components/ui/accordion-17/accordion-17.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-4\"><h2 class=\"text-xl font-bold\">Table w/ left chevron</h2><accordion type=\"single\" collapsible class=\"w-full -space-y-px\" default-value=\"3\"><accordionitem wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" value=\"{{item.id}}\" key=\"{{item.id}}\" class=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative border px-4 py-1 outline-none first:rounded-t-md last:rounded-b-md last:border-b has-focus-visible:z-10 has-focus-visible:ring-[3px]\"><accordiontrigger class=\"justify-start gap-3 rounded-md py-2 text-[15px] leading-6 outline-none hover:no-underline focus-visible:ring-0 [&>svg]:-order-1\">{{ item.title }}</accordiontrigger><accordioncontent class=\"text-muted-foreground ps-7 pb-2\">{{ item.content }}</accordioncontent></accordionitem></accordion></view>\n</view>"
        },
        {
          "path": "registry/default/components/accordion/accordion-17.json",
          "target": "components/ui/accordion-17/accordion-17.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {\n    \"accordion\": \"../../ui/accordion\",\n    \"accordion-item\": \"../../ui/accordion-item/index\"\n  }\n}"
        },
        {
          "path": "registry/default/components/accordion/accordion-17.js",
          "target": "components/ui/accordion-17/accordion-17.js",
          "type": "registry:component",
          "content": "Component({\n  data: {\n    value: \"3\",\n    items: [\n  {\n    \"id\": \"1\",\n    \"title\": \"What makes Timkit UI different?\",\n    \"content\": \"Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.\"\n  },\n  {\n    \"id\": \"2\",\n    \"title\": \"How can I customize the components?\",\n    \"content\": \"Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.\"\n  },\n  {\n    \"id\": \"3\",\n    \"title\": \"Is Timkit UI optimized for performance?\",\n    \"content\": \"Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.\"\n  },\n  {\n    \"id\": \"4\",\n    \"title\": \"How accessible are the components?\",\n    \"content\": \"All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.\"\n  }\n]\n  },\n  methods: {\n    handleValueChange(e) {\n      this.setData({ value: e.detail.value })\n    },\n    toggleCollapsible(e) {\n      const itemIndex = e.currentTarget.dataset.itemIndex\n      const collapsibleIndex = e.currentTarget.dataset.collapsibleIndex\n      const items = this.data.items.slice()\n      const collapsible = items[itemIndex]?.collapsibles?.[collapsibleIndex]\n      if (!collapsible) return\n      collapsible.open = !collapsible.open\n      this.setData({ items })\n    }\n  }\n})"
        }
      ],
      "meta": {
        "tags": [
          "accordion",
          "radix"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "accordion-17",
          "group": "accordion",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "accordion-17",
              "path": "registry/default/components/accordion/accordion-17.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "accordion-17",
              "path": "registry/default/components/accordion/accordion-17.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "accordion-17",
              "path": "registry/default/components/accordion/accordion-17.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "accordion-17",
              "path": "registry/default/components/accordion/accordion-17.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "accordion",
        "title": "Accordion · Table w/ left chevron"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "accordion"
      ]
    },
    {
      "name": "accordion-18",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/accordion.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/accordion/accordion-18.tsx",
          "type": "registry:component",
          "target": "components/ui/accordion-18.tsx",
          "content": "import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@timui/react'\nimport { PlusIcon } from 'lucide-react'\n\nconst items = [\n  {\n    id: '1',\n    title: 'What makes Timkit UI different?',\n    content:\n      'Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.',\n  },\n  {\n    id: '2',\n    title: 'How can I customize the components?',\n    content:\n      'Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.',\n  },\n  {\n    id: '3',\n    title: 'Is Timkit UI optimized for performance?',\n    content:\n      'Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.',\n  },\n  {\n    id: '4',\n    title: 'How accessible are the components?',\n    content:\n      'All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.',\n  },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"space-y-4\">\n      <h2 className=\"text-xl font-bold\">Table w/ left plus-minus</h2>\n      <Accordion type=\"single\" collapsible className=\"w-full -space-y-px\" defaultValue=\"3\">\n        {items.map((item) => (\n          <AccordionItem\n            value={item.id}\n            key={item.id}\n            className=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative border px-4 py-1 outline-none first:rounded-t-md last:rounded-b-md last:border-b has-focus-visible:z-10 has-focus-visible:ring-[3px]\"\n          >\n            <div className=\"flex\">\n              <AccordionTrigger\n                showChevron={false}\n                className=\"flex flex-1 items-center gap-4 rounded-md py-2 text-left text-sm text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-0 [&>svg]:-order-1 [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\"\n              >\n                {item.title}\n                <PlusIcon\n                  size={16}\n                  className=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\"\n                  aria-hidden=\"true\"\n                />\n              </AccordionTrigger>\n            </div>\n            <AccordionContent className=\"text-muted-foreground ps-7 pb-2\">\n              {item.content}\n            </AccordionContent>\n          </AccordionItem>\n        ))}\n      </Accordion>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-18.vue",
          "target": "components/ui/accordion-18.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { PlusIcon } from 'lucide-vue-next';\nimport { Accordion } from '@timui/vue';\nimport { AccordionContent } from '@timui/vue';\nimport { AccordionItem } from '@timui/vue';\nimport { AccordionTrigger } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: '1',\n    title: 'What makes Timkit UI different?',\n    content:\n      'Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.',\n  },\n  {\n    id: '2',\n    title: 'How can I customize the components?',\n    content:\n      'Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.',\n  },\n  {\n    id: '3',\n    title: 'Is Timkit UI optimized for performance?',\n    content:\n      'Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.',\n  },\n  {\n    id: '4',\n    title: 'How accessible are the components?',\n    content:\n      'All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.',\n  },\n]\n\n</script>\n\n<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">Table w/ left plus-minus</h2><Accordion type=\"single\" collapsible class=\"w-full -space-y-px\" default-value=\"3\"><AccordionItem v-for=\"(item, index) in items\" :value=\"item.id\" :key=\"item.id\" class=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative border px-4 py-1 outline-none first:rounded-t-md last:rounded-b-md last:border-b has-focus-visible:z-10 has-focus-visible:ring-[3px]\"><div class=\"flex\"><AccordionTrigger :showChevron=\"false\" class=\"flex flex-1 items-center gap-4 rounded-md py-2 text-left text-sm text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-0 [&>svg]:-order-1 [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\">{{ item.title }}<PlusIcon :size=\"16\" class=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\" aria-hidden=\"true\" /></AccordionTrigger></div><AccordionContent class=\"text-muted-foreground ps-7 pb-2\">{{ item.content }}</AccordionContent></AccordionItem></Accordion></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-18.html",
          "target": "components/ui/accordion-18.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">Table w/ left plus-minus</h2><Accordion type=\"single\" collapsible class=\"w-full -space-y-px\" default-value=\"3\"><!-- Loop items -->\n<AccordionItem value=\"${item.id}\" key=\"${item.id}\" class=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative border px-4 py-1 outline-none first:rounded-t-md last:rounded-b-md last:border-b has-focus-visible:z-10 has-focus-visible:ring-[3px]\"><div class=\"flex\"><AccordionTrigger showchevron=\"${false}\" class=\"flex flex-1 items-center gap-4 rounded-md py-2 text-left text-sm text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-0 [&>svg]:-order-1 [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\">${item.title}<PlusIcon size=\"${16}\" class=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\" aria-hidden=\"true\" /></AccordionTrigger></div><AccordionContent class=\"text-muted-foreground ps-7 pb-2\">${item.content}</AccordionContent></AccordionItem>\n<!-- End Loop --></Accordion></div>\n</template>"
        },
        {
          "path": "registry/default/components/accordion/accordion-18.wxml",
          "target": "components/ui/accordion-18/accordion-18.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-4\"><h2 class=\"text-xl font-bold\">Table w/ left plus-minus</h2><accordion type=\"single\" collapsible class=\"w-full -space-y-px\" default-value=\"3\"><accordionitem wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" value=\"{{item.id}}\" key=\"{{item.id}}\" class=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative border px-4 py-1 outline-none first:rounded-t-md last:rounded-b-md last:border-b has-focus-visible:z-10 has-focus-visible:ring-[3px]\"><view class=\"flex\"><accordiontrigger showchevron=\"{{false}}\" class=\"flex flex-1 items-center gap-4 rounded-md py-2 text-left text-sm text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:ring-0 [&>svg]:-order-1 [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\">{{ item.title }}<plusicon size=\"{{16}}\" class=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\" aria-hidden=\"true\" /></accordiontrigger></view><accordioncontent class=\"text-muted-foreground ps-7 pb-2\">{{ item.content }}</accordioncontent></accordionitem></accordion></view>\n</view>"
        },
        {
          "path": "registry/default/components/accordion/accordion-18.json",
          "target": "components/ui/accordion-18/accordion-18.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {\n    \"accordion\": \"../../ui/accordion\",\n    \"accordion-item\": \"../../ui/accordion-item/index\"\n  }\n}"
        },
        {
          "path": "registry/default/components/accordion/accordion-18.js",
          "target": "components/ui/accordion-18/accordion-18.js",
          "type": "registry:component",
          "content": "Component({\n  data: {\n    value: \"3\",\n    items: [\n  {\n    \"id\": \"1\",\n    \"title\": \"What makes Timkit UI different?\",\n    \"content\": \"Timkit UI focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.\"\n  },\n  {\n    \"id\": \"2\",\n    \"title\": \"How can I customize the components?\",\n    \"content\": \"Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.\"\n  },\n  {\n    \"id\": \"3\",\n    \"title\": \"Is Timkit UI optimized for performance?\",\n    \"content\": \"Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.\"\n  },\n  {\n    \"id\": \"4\",\n    \"title\": \"How accessible are the components?\",\n    \"content\": \"All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.\"\n  }\n]\n  },\n  methods: {\n    handleValueChange(e) {\n      this.setData({ value: e.detail.value })\n    },\n    toggleCollapsible(e) {\n      const itemIndex = e.currentTarget.dataset.itemIndex\n      const collapsibleIndex = e.currentTarget.dataset.collapsibleIndex\n      const items = this.data.items.slice()\n      const collapsible = items[itemIndex]?.collapsibles?.[collapsibleIndex]\n      if (!collapsible) return\n      collapsible.open = !collapsible.open\n      this.setData({ items })\n    }\n  }\n})"
        }
      ],
      "meta": {
        "tags": [
          "accordion",
          "radix"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "accordion-18",
          "group": "accordion",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "accordion-18",
              "path": "registry/default/components/accordion/accordion-18.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "accordion-18",
              "path": "registry/default/components/accordion/accordion-18.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "accordion-18",
              "path": "registry/default/components/accordion/accordion-18.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "accordion-18",
              "path": "registry/default/components/accordion/accordion-18.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "accordion",
        "title": "Accordion · Table w/ left plus-minus"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "accordion"
      ]
    },
    {
      "name": "accordion-19",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/accordion.json",
        "https://ui.timkit.cn/r/collapsible.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/accordion/accordion-19.tsx",
          "type": "registry:component",
          "target": "components/ui/accordion-19.tsx",
          "content": "import {\n  Accordion,\n  AccordionContent,\n  AccordionItem,\n  AccordionTrigger,\n  Collapsible,\n  CollapsibleContent,\n  CollapsibleTrigger,\n} from '@timui/react'\nimport { ChevronDownIcon } from 'lucide-react'\n\nconst items = [\n  {\n    id: '1',\n    title: 'What makes Timkit UI different?',\n    collapsibles: [\n      {\n        title: 'What about performance?',\n        content: 'We optimize every component for maximum performance and minimal bundle size.',\n      },\n      {\n        title: 'How is the documentation?',\n        content:\n          'Our documentation is comprehensive and includes live examples for every component.',\n      },\n    ],\n  },\n  {\n    id: '2',\n    title: 'How can I customize the components?',\n    collapsibles: [\n      {\n        title: 'Can I use custom themes?',\n        content:\n          'Yes, our theming system is fully customizable and supports both light and dark modes.',\n      },\n      {\n        title: 'What about Tailwind support?',\n        content: 'We have first-class support for Tailwind CSS with custom utility classes.',\n      },\n    ],\n  },\n  {\n    id: '3',\n    title: 'Is Timkit UI optimized for performance?',\n    collapsibles: [\n      {\n        title: \"What's the bundle size impact?\",\n        content:\n          'Our components are tree-shakeable and typically add minimal overhead to your bundle.',\n        open: true,\n      },\n      {\n        title: 'How is code splitting handled?',\n        content: 'We support automatic code splitting for optimal loading performance.',\n      },\n    ],\n  },\n  {\n    id: '4',\n    title: 'How accessible are the components?',\n    collapsibles: [\n      {\n        title: 'Which screen readers are supported?',\n        content: 'We test with NVDA, VoiceOver, and JAWS to ensure broad compatibility.',\n      },\n      {\n        title: 'What about keyboard navigation?',\n        content:\n          'Full keyboard navigation support is implemented following WAI-ARIA best practices.',\n      },\n    ],\n  },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"space-y-4\">\n      <h2 className=\"text-xl font-bold\">Multi-level</h2>\n      <Accordion type=\"single\" collapsible className=\"w-full -space-y-px\" defaultValue=\"3\">\n        {items.map((item) => (\n          <AccordionItem\n            value={item.id}\n            key={item.id}\n            className=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative border outline-none first:rounded-t-md last:rounded-b-md last:border-b has-focus-visible:z-10 has-focus-visible:ring-[3px]\"\n          >\n            <AccordionTrigger className=\"rounded-md px-4 py-3 text-[15px] leading-6 outline-none hover:no-underline focus-visible:ring-0\">\n              {item.title}\n            </AccordionTrigger>\n            <AccordionContent className=\"p-0\">\n              {item.collapsibles.map((collapsible, index) => (\n                <CollapsibleDemo\n                  key={index}\n                  title={collapsible.title}\n                  content={collapsible.content}\n                  open={collapsible.open}\n                />\n              ))}\n            </AccordionContent>\n          </AccordionItem>\n        ))}\n      </Accordion>\n    </div>\n  )\n}\n\nfunction CollapsibleDemo({\n  title,\n  content,\n  open,\n}: {\n  title: string\n  content: string\n  open?: boolean\n}) {\n  return (\n    <Collapsible className=\"bg-accent border-t px-4 py-3\" defaultOpen={open}>\n      <CollapsibleTrigger className=\"flex gap-2 text-[15px] leading-6 font-semibold [&[data-state=open]>svg]:rotate-180\">\n        <ChevronDownIcon\n          size={16}\n          className=\"mt-1 shrink-0 opacity-60 transition-transform duration-200\"\n          aria-hidden=\"true\"\n        />\n        {title}\n      </CollapsibleTrigger>\n      <CollapsibleContent className=\"text-muted-foreground data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down mt-1 overflow-hidden ps-6 text-sm transition-all\">\n        {content}\n      </CollapsibleContent>\n    </Collapsible>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-19.vue",
          "target": "components/ui/accordion-19.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ChevronDownIcon } from 'lucide-vue-next';\nimport { Accordion } from '@timui/vue';\nimport { AccordionContent } from '@timui/vue';\nimport { AccordionItem } from '@timui/vue';\nimport { AccordionTrigger } from '@timui/vue';\nimport { Collapsible } from '@timui/vue';\nimport { CollapsibleContent } from '@timui/vue';\nimport { CollapsibleTrigger } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: '1',\n    title: 'What makes Timkit UI different?',\n    collapsibles: [\n      {\n        title: 'What about performance?',\n        content: 'We optimize every component for maximum performance and minimal bundle size.',\n      },\n      {\n        title: 'How is the documentation?',\n        content:\n          'Our documentation is comprehensive and includes live examples for every component.',\n      },\n    ],\n  },\n  {\n    id: '2',\n    title: 'How can I customize the components?',\n    collapsibles: [\n      {\n        title: 'Can I use custom themes?',\n        content:\n          'Yes, our theming system is fully customizable and supports both light and dark modes.',\n      },\n      {\n        title: 'What about Tailwind support?',\n        content: 'We have first-class support for Tailwind CSS with custom utility classes.',\n      },\n    ],\n  },\n  {\n    id: '3',\n    title: 'Is Timkit UI optimized for performance?',\n    collapsibles: [\n      {\n        title: \"What's the bundle size impact?\",\n        content:\n          'Our components are tree-shakeable and typically add minimal overhead to your bundle.',\n        open: true,\n      },\n      {\n        title: 'How is code splitting handled?',\n        content: 'We support automatic code splitting for optimal loading performance.',\n      },\n    ],\n  },\n  {\n    id: '4',\n    title: 'How accessible are the components?',\n    collapsibles: [\n      {\n        title: 'Which screen readers are supported?',\n        content: 'We test with NVDA, VoiceOver, and JAWS to ensure broad compatibility.',\n      },\n      {\n        title: 'What about keyboard navigation?',\n        content:\n          'Full keyboard navigation support is implemented following WAI-ARIA best practices.',\n      },\n    ],\n  },\n]\n\n</script>\n\n<template>\n  <div class=\"space-y-4\">\n    <h2 class=\"text-xl font-bold\">Multi-level</h2>\n    <Accordion type=\"single\" collapsible class=\"w-full -space-y-px\" default-value=\"3\">\n      <AccordionItem\n        v-for=\"item in items\"\n        :key=\"item.id\"\n        :value=\"item.id\"\n        class=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative border outline-none first:rounded-t-md last:rounded-b-md last:border-b has-focus-visible:z-10 has-focus-visible:ring-[3px]\"\n      >\n        <AccordionTrigger class=\"rounded-md px-4 py-3 text-[15px] leading-6 outline-none hover:no-underline focus-visible:ring-0\">\n          {{ item.title }}\n        </AccordionTrigger>\n        <AccordionContent class=\"p-0\">\n          <Collapsible\n            v-for=\"(collapsible, index) in item.collapsibles\"\n            :key=\"index\"\n            class=\"bg-accent border-t px-4 py-3\"\n            :default-open=\"collapsible.open\"\n          >\n            <CollapsibleTrigger class=\"flex gap-2 text-[15px] leading-6 font-semibold [&[data-state=open]>svg]:rotate-180\">\n              <ChevronDownIcon\n                :size=\"16\"\n                class=\"mt-1 shrink-0 opacity-60 transition-transform duration-200\"\n                aria-hidden=\"true\"\n              />\n              {{ collapsible.title }}\n            </CollapsibleTrigger>\n            <CollapsibleContent class=\"text-muted-foreground data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down mt-1 overflow-hidden ps-6 text-sm transition-all\">\n              {{ collapsible.content }}\n            </CollapsibleContent>\n          </Collapsible>\n        </AccordionContent>\n      </AccordionItem>\n    </Accordion>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-19.html",
          "target": "components/ui/accordion-19.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">Multi-level</h2><Accordion type=\"single\" collapsible class=\"w-full -space-y-px\" default-value=\"3\"><!-- Loop items -->\n<AccordionItem value=\"${item.id}\" key=\"${item.id}\" class=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative border outline-none first:rounded-t-md last:rounded-b-md last:border-b has-focus-visible:z-10 has-focus-visible:ring-[3px]\"><AccordionTrigger class=\"rounded-md px-4 py-3 text-[15px] leading-6 outline-none hover:no-underline focus-visible:ring-0\">${item.title}</AccordionTrigger><AccordionContent class=\"p-0\"><!-- Loop item.collapsibles -->\n<CollapsibleDemo key=\"${index}\" title=\"${collapsible.title}\" content=\"${collapsible.content}\" open=\"${collapsible.open}\" />\n<!-- End Loop --></AccordionContent></AccordionItem>\n<!-- End Loop --></Accordion></div>\n</template>"
        },
        {
          "path": "registry/default/components/accordion/accordion-19.wxml",
          "target": "components/ui/accordion-19/accordion-19.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-4\"><h2 class=\"text-xl font-bold\">Multi-level</h2><accordion type=\"single\" collapsible class=\"w-full -space-y-px\" default-value=\"3\"><accordionitem wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" value=\"{{item.id}}\" key=\"{{item.id}}\" class=\"bg-background has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative border outline-none first:rounded-t-md last:rounded-b-md last:border-b has-focus-visible:z-10 has-focus-visible:ring-[3px]\"><accordiontrigger class=\"rounded-md px-4 py-3 text-[15px] leading-6 outline-none hover:no-underline focus-visible:ring-0\">{{ item.title }}</accordiontrigger><accordioncontent class=\"p-0\"><collapsibledemo wx:for=\"{{item.collapsibles}}\" wx:for-item=\"collapsible\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{index}}\" title=\"{{collapsible.title}}\" content=\"{{collapsible.content}}\" open=\"{{collapsible.open}}\" /></accordioncontent></accordionitem></accordion></view>\n</view>"
        },
        {
          "path": "registry/default/components/accordion/accordion-19.json",
          "target": "components/ui/accordion-19/accordion-19.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {\n    \"accordion\": \"../../ui/accordion\",\n    \"accordion-item\": \"../../ui/accordion-item/index\"\n  }\n}"
        },
        {
          "path": "registry/default/components/accordion/accordion-19.js",
          "target": "components/ui/accordion-19/accordion-19.js",
          "type": "registry:component",
          "content": "Component({\n  data: {\n    value: \"3\",\n    items: [\n  {\n    \"id\": \"1\",\n    \"title\": \"What makes Timkit UI different?\",\n    \"collapsibles\": [\n      {\n        \"title\": \"What about performance?\",\n        \"content\": \"We optimize every component for maximum performance and minimal bundle size.\"\n      },\n      {\n        \"title\": \"How is the documentation?\",\n        \"content\": \"Our documentation is comprehensive and includes live examples for every component.\"\n      }\n    ]\n  },\n  {\n    \"id\": \"2\",\n    \"title\": \"How can I customize the components?\",\n    \"collapsibles\": [\n      {\n        \"title\": \"Can I use custom themes?\",\n        \"content\": \"Yes, our theming system is fully customizable and supports both light and dark modes.\"\n      },\n      {\n        \"title\": \"What about Tailwind support?\",\n        \"content\": \"We have first-class support for Tailwind CSS with custom utility classes.\"\n      }\n    ]\n  },\n  {\n    \"id\": \"3\",\n    \"title\": \"Is Timkit UI optimized for performance?\",\n    \"collapsibles\": [\n      {\n        \"title\": \"What's the bundle size impact?\",\n        \"content\": \"Our components are tree-shakeable and typically add minimal overhead to your bundle.\",\n        \"open\": true\n      },\n      {\n        \"title\": \"How is code splitting handled?\",\n        \"content\": \"We support automatic code splitting for optimal loading performance.\"\n      }\n    ]\n  },\n  {\n    \"id\": \"4\",\n    \"title\": \"How accessible are the components?\",\n    \"collapsibles\": [\n      {\n        \"title\": \"Which screen readers are supported?\",\n        \"content\": \"We test with NVDA, VoiceOver, and JAWS to ensure broad compatibility.\"\n      },\n      {\n        \"title\": \"What about keyboard navigation?\",\n        \"content\": \"Full keyboard navigation support is implemented following WAI-ARIA best practices.\"\n      }\n    ]\n  }\n]\n  },\n  methods: {\n    handleValueChange(e) {\n      this.setData({ value: e.detail.value })\n    },\n    toggleCollapsible(e) {\n      const itemIndex = e.currentTarget.dataset.itemIndex\n      const collapsibleIndex = e.currentTarget.dataset.collapsibleIndex\n      const items = this.data.items.slice()\n      const collapsible = items[itemIndex]?.collapsibles?.[collapsibleIndex]\n      if (!collapsible) return\n      collapsible.open = !collapsible.open\n      this.setData({ items })\n    }\n  }\n})"
        }
      ],
      "meta": {
        "tags": [
          "accordion",
          "collapsible",
          "radix"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "accordion-19",
          "group": "accordion",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "accordion-19",
              "path": "registry/default/components/accordion/accordion-19.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "accordion-19",
              "path": "registry/default/components/accordion/accordion-19.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "accordion-19",
              "path": "registry/default/components/accordion/accordion-19.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "accordion-19",
              "path": "registry/default/components/accordion/accordion-19.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "accordion",
        "title": "Accordion · Multi-level"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "accordion"
      ]
    },
    {
      "name": "accordion-20",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/accordion.json",
        "https://ui.timkit.cn/r/collapsible.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/accordion/accordion-20.tsx",
          "type": "registry:component",
          "target": "components/ui/accordion-20.tsx",
          "content": "import {\n  Accordion,\n  AccordionContent,\n  AccordionItem,\n  AccordionTrigger,\n  Collapsible,\n  CollapsibleContent,\n  CollapsibleTrigger,\n} from '@timui/react'\nimport {\n  AtSignIcon,\n  ChevronDownIcon,\n  CircleDashedIcon,\n  CommandIcon,\n  EclipseIcon,\n  GaugeIcon,\n  LucideIcon,\n  ZapIcon,\n} from 'lucide-react'\n\nconst items = [\n  {\n    id: '1',\n    title: 'What makes Timkit UI different?',\n    icon: CommandIcon,\n    collapsibles: [\n      {\n        title: 'What about performance?',\n        content: 'We optimize every component for maximum performance and minimal bundle size.',\n        icon: GaugeIcon,\n      },\n      {\n        title: 'How is the documentation?',\n        content:\n          'Our documentation is comprehensive and includes live examples for every component.',\n        icon: CircleDashedIcon,\n      },\n    ],\n  },\n  {\n    id: '2',\n    title: 'How can I customize the components?',\n    icon: EclipseIcon,\n    collapsibles: [\n      {\n        title: 'Can I use custom themes?',\n        content:\n          'Yes, our theming system is fully customizable and supports both light and dark modes.',\n        icon: GaugeIcon,\n      },\n      {\n        title: 'What about Tailwind support?',\n        content: 'We have first-class support for Tailwind CSS with custom utility classes.',\n        icon: CircleDashedIcon,\n      },\n    ],\n  },\n  {\n    id: '3',\n    title: 'Is Timkit UI optimized for performance?',\n    icon: ZapIcon,\n    collapsibles: [\n      {\n        title: \"What's the bundle size impact?\",\n        content:\n          'Our components are tree-shakeable and typically add minimal overhead to your bundle.',\n        open: true,\n        icon: GaugeIcon,\n      },\n      {\n        title: 'How is code splitting handled?',\n        content: 'We support automatic code splitting for optimal loading performance.',\n        icon: CircleDashedIcon,\n      },\n    ],\n  },\n  {\n    id: '4',\n    title: 'How accessible are the components?',\n    icon: AtSignIcon,\n    collapsibles: [\n      {\n        title: 'Which screen readers are supported?',\n        content: 'We test with NVDA, VoiceOver, and JAWS to ensure broad compatibility.',\n        icon: GaugeIcon,\n      },\n      {\n        title: 'What about keyboard navigation?',\n        content:\n          'Full keyboard navigation support is implemented following WAI-ARIA best practices.',\n        icon: CircleDashedIcon,\n      },\n    ],\n  },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"space-y-4\">\n      <h2 className=\"text-xl font-bold\">Multi-level w/ icon</h2>\n      <Accordion type=\"single\" collapsible className=\"w-full\" defaultValue=\"3\">\n        {items.map((item) => (\n          <AccordionItem\n            value={item.id}\n            key={item.id}\n            className=\"has-focus-visible:border-ring has-focus-visible:ring-ring/50 outline-none has-focus-visible:ring-[3px]\"\n          >\n            <AccordionTrigger className=\"justify-start gap-3 rounded-md text-[15px] leading-6 outline-none hover:no-underline focus-visible:ring-0 [&>svg]:-order-1\">\n              <span className=\"flex items-center gap-3\">\n                <item.icon size={16} className=\"shrink-0 opacity-60\" aria-hidden=\"true\" />\n                <span>{item.title}</span>\n              </span>\n            </AccordionTrigger>\n            <AccordionContent className=\"p-0\">\n              {item.collapsibles.map((collapsible, index) => (\n                <CollapsibleDemo\n                  key={index}\n                  title={collapsible.title}\n                  content={collapsible.content}\n                  open={collapsible.open}\n                  icon={collapsible.icon}\n                />\n              ))}\n            </AccordionContent>\n          </AccordionItem>\n        ))}\n      </Accordion>\n    </div>\n  )\n}\n\nfunction CollapsibleDemo({\n  title,\n  content,\n  open,\n  icon: Icon,\n}: {\n  title: string\n  content: string\n  open?: boolean\n  icon: LucideIcon\n}) {\n  return (\n    <Collapsible className=\"border-t py-3 ps-6 pe-4\" defaultOpen={open}>\n      <CollapsibleTrigger className=\"flex gap-2 text-[15px] leading-6 font-semibold [&[data-state=open]>svg]:rotate-180\">\n        <ChevronDownIcon\n          size={16}\n          className=\"mt-1 shrink-0 opacity-60 transition-transform duration-200\"\n          aria-hidden=\"true\"\n        />\n        <span className=\"flex items-center gap-3\">\n          <Icon size={16} className=\"shrink-0 opacity-60\" aria-hidden=\"true\" />\n          <span>{title}</span>\n        </span>\n      </CollapsibleTrigger>\n      <CollapsibleContent className=\"text-muted-foreground data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down mt-1 overflow-hidden ps-6 text-sm transition-all\">\n        {content}\n      </CollapsibleContent>\n    </Collapsible>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-20.vue",
          "target": "components/ui/accordion-20.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { AtSignIcon, ChevronDownIcon, CircleDashedIcon, CommandIcon, EclipseIcon, GaugeIcon, LucideIcon, ZapIcon } from 'lucide-vue-next';\nimport { Accordion } from '@timui/vue';\nimport { AccordionContent } from '@timui/vue';\nimport { AccordionItem } from '@timui/vue';\nimport { AccordionTrigger } from '@timui/vue';\nimport { Collapsible } from '@timui/vue';\nimport { CollapsibleContent } from '@timui/vue';\nimport { CollapsibleTrigger } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: '1',\n    title: 'What makes Timkit UI different?',\n    icon: CommandIcon,\n    collapsibles: [\n      {\n        title: 'What about performance?',\n        content: 'We optimize every component for maximum performance and minimal bundle size.',\n        icon: GaugeIcon,\n      },\n      {\n        title: 'How is the documentation?',\n        content:\n          'Our documentation is comprehensive and includes live examples for every component.',\n        icon: CircleDashedIcon,\n      },\n    ],\n  },\n  {\n    id: '2',\n    title: 'How can I customize the components?',\n    icon: EclipseIcon,\n    collapsibles: [\n      {\n        title: 'Can I use custom themes?',\n        content:\n          'Yes, our theming system is fully customizable and supports both light and dark modes.',\n        icon: GaugeIcon,\n      },\n      {\n        title: 'What about Tailwind support?',\n        content: 'We have first-class support for Tailwind CSS with custom utility classes.',\n        icon: CircleDashedIcon,\n      },\n    ],\n  },\n  {\n    id: '3',\n    title: 'Is Timkit UI optimized for performance?',\n    icon: ZapIcon,\n    collapsibles: [\n      {\n        title: \"What's the bundle size impact?\",\n        content:\n          'Our components are tree-shakeable and typically add minimal overhead to your bundle.',\n        open: true,\n        icon: GaugeIcon,\n      },\n      {\n        title: 'How is code splitting handled?',\n        content: 'We support automatic code splitting for optimal loading performance.',\n        icon: CircleDashedIcon,\n      },\n    ],\n  },\n  {\n    id: '4',\n    title: 'How accessible are the components?',\n    icon: AtSignIcon,\n    collapsibles: [\n      {\n        title: 'Which screen readers are supported?',\n        content: 'We test with NVDA, VoiceOver, and JAWS to ensure broad compatibility.',\n        icon: GaugeIcon,\n      },\n      {\n        title: 'What about keyboard navigation?',\n        content:\n          'Full keyboard navigation support is implemented following WAI-ARIA best practices.',\n        icon: CircleDashedIcon,\n      },\n    ],\n  },\n]\n\n</script>\n\n<template>\n  <div class=\"space-y-4\">\n    <h2 class=\"text-xl font-bold\">Multi-level w/ icon</h2>\n    <Accordion type=\"single\" collapsible class=\"w-full\" default-value=\"3\">\n      <AccordionItem\n        v-for=\"item in items\"\n        :key=\"item.id\"\n        :value=\"item.id\"\n        class=\"has-focus-visible:border-ring has-focus-visible:ring-ring/50 outline-none has-focus-visible:ring-[3px]\"\n      >\n        <AccordionTrigger class=\"justify-start gap-3 rounded-md text-[15px] leading-6 outline-none hover:no-underline focus-visible:ring-0 [&>svg]:-order-1\">\n          <span class=\"flex items-center gap-3\">\n            <component :is=\"item.icon\" :size=\"16\" class=\"shrink-0 opacity-60\" aria-hidden=\"true\" />\n            <span>{{ item.title }}</span>\n          </span>\n        </AccordionTrigger>\n        <AccordionContent class=\"p-0\">\n          <Collapsible\n            v-for=\"(collapsible, index) in item.collapsibles\"\n            :key=\"index\"\n            class=\"border-t py-3 ps-6 pe-4\"\n            :default-open=\"collapsible.open\"\n          >\n            <CollapsibleTrigger class=\"flex gap-2 text-[15px] leading-6 font-semibold [&[data-state=open]>svg]:rotate-180\">\n              <ChevronDownIcon\n                :size=\"16\"\n                class=\"mt-1 shrink-0 opacity-60 transition-transform duration-200\"\n                aria-hidden=\"true\"\n              />\n              <span class=\"flex items-center gap-3\">\n                <component :is=\"collapsible.icon\" :size=\"16\" class=\"shrink-0 opacity-60\" aria-hidden=\"true\" />\n                <span>{{ collapsible.title }}</span>\n              </span>\n            </CollapsibleTrigger>\n            <CollapsibleContent class=\"text-muted-foreground data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down mt-1 overflow-hidden ps-6 text-sm transition-all\">\n              {{ collapsible.content }}\n            </CollapsibleContent>\n          </Collapsible>\n        </AccordionContent>\n      </AccordionItem>\n    </Accordion>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/accordion/accordion-20.html",
          "target": "components/ui/accordion-20.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-4\"><h2 class=\"text-xl font-bold\">Multi-level w/ icon</h2><Accordion type=\"single\" collapsible class=\"w-full\" default-value=\"3\"><!-- Loop items -->\n<AccordionItem value=\"${item.id}\" key=\"${item.id}\" class=\"has-focus-visible:border-ring has-focus-visible:ring-ring/50 outline-none has-focus-visible:ring-[3px]\"><AccordionTrigger class=\"justify-start gap-3 rounded-md text-[15px] leading-6 outline-none hover:no-underline focus-visible:ring-0 [&>svg]:-order-1\"><span class=\"flex items-center gap-3\"><item.icon size=\"${16}\" class=\"shrink-0 opacity-60\" aria-hidden=\"true\" /><span>${item.title}</span></span></AccordionTrigger><AccordionContent class=\"p-0\"><!-- Loop item.collapsibles -->\n<CollapsibleDemo key=\"${index}\" title=\"${collapsible.title}\" content=\"${collapsible.content}\" open=\"${collapsible.open}\" icon=\"${collapsible.icon}\" />\n<!-- End Loop --></AccordionContent></AccordionItem>\n<!-- End Loop --></Accordion></div>\n</template>"
        },
        {
          "path": "registry/default/components/accordion/accordion-20.wxml",
          "target": "components/ui/accordion-20/accordion-20.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-4\"><h2 class=\"text-xl font-bold\">Multi-level w/ icon</h2><accordion type=\"single\" collapsible class=\"w-full\" default-value=\"3\"><accordionitem wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" value=\"{{item.id}}\" key=\"{{item.id}}\" class=\"has-focus-visible:border-ring has-focus-visible:ring-ring/50 outline-none has-focus-visible:ring-[3px]\"><accordiontrigger class=\"justify-start gap-3 rounded-md text-[15px] leading-6 outline-none hover:no-underline focus-visible:ring-0 [&>svg]:-order-1\"><text class=\"flex items-center gap-3\"><item.icon size=\"{{16}}\" class=\"shrink-0 opacity-60\" aria-hidden=\"true\" /><text>{{ item.title }}</text></text></accordiontrigger><accordioncontent class=\"p-0\"><collapsibledemo wx:for=\"{{item.collapsibles}}\" wx:for-item=\"collapsible\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{index}}\" title=\"{{collapsible.title}}\" content=\"{{collapsible.content}}\" open=\"{{collapsible.open}}\" icon=\"{{collapsible.icon}}\" /></accordioncontent></accordionitem></accordion></view>\n</view>"
        },
        {
          "path": "registry/default/components/accordion/accordion-20.json",
          "target": "components/ui/accordion-20/accordion-20.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {\n    \"accordion\": \"../../ui/accordion\",\n    \"accordion-item\": \"../../ui/accordion-item/index\"\n  }\n}"
        },
        {
          "path": "registry/default/components/accordion/accordion-20.js",
          "target": "components/ui/accordion-20/accordion-20.js",
          "type": "registry:component",
          "content": "Component({\n  data: {\n    value: \"3\",\n    items: [\n  {\n    \"id\": \"1\",\n    \"title\": \"What makes Timkit UI different?\",\n    \"icon\": \"CommandIcon\",\n    \"collapsibles\": [\n      {\n        \"title\": \"What about performance?\",\n        \"content\": \"We optimize every component for maximum performance and minimal bundle size.\",\n        \"icon\": \"GaugeIcon\",\n        \"iconLabel\": \"Gauge\"\n      },\n      {\n        \"title\": \"How is the documentation?\",\n        \"content\": \"Our documentation is comprehensive and includes live examples for every component.\",\n        \"icon\": \"CircleDashedIcon\",\n        \"iconLabel\": \"Dash\"\n      }\n    ],\n    \"iconLabel\": \"Cmd\"\n  },\n  {\n    \"id\": \"2\",\n    \"title\": \"How can I customize the components?\",\n    \"icon\": \"EclipseIcon\",\n    \"collapsibles\": [\n      {\n        \"title\": \"Can I use custom themes?\",\n        \"content\": \"Yes, our theming system is fully customizable and supports both light and dark modes.\",\n        \"icon\": \"GaugeIcon\",\n        \"iconLabel\": \"Gauge\"\n      },\n      {\n        \"title\": \"What about Tailwind support?\",\n        \"content\": \"We have first-class support for Tailwind CSS with custom utility classes.\",\n        \"icon\": \"CircleDashedIcon\",\n        \"iconLabel\": \"Dash\"\n      }\n    ],\n    \"iconLabel\": \"Ecl\"\n  },\n  {\n    \"id\": \"3\",\n    \"title\": \"Is Timkit UI optimized for performance?\",\n    \"icon\": \"ZapIcon\",\n    \"collapsibles\": [\n      {\n        \"title\": \"What's the bundle size impact?\",\n        \"content\": \"Our components are tree-shakeable and typically add minimal overhead to your bundle.\",\n        \"open\": true,\n        \"icon\": \"GaugeIcon\",\n        \"iconLabel\": \"Gauge\"\n      },\n      {\n        \"title\": \"How is code splitting handled?\",\n        \"content\": \"We support automatic code splitting for optimal loading performance.\",\n        \"icon\": \"CircleDashedIcon\",\n        \"iconLabel\": \"Dash\"\n      }\n    ],\n    \"iconLabel\": \"Zap\"\n  },\n  {\n    \"id\": \"4\",\n    \"title\": \"How accessible are the components?\",\n    \"icon\": \"AtSignIcon\",\n    \"collapsibles\": [\n      {\n        \"title\": \"Which screen readers are supported?\",\n        \"content\": \"We test with NVDA, VoiceOver, and JAWS to ensure broad compatibility.\",\n        \"icon\": \"GaugeIcon\",\n        \"iconLabel\": \"Gauge\"\n      },\n      {\n        \"title\": \"What about keyboard navigation?\",\n        \"content\": \"Full keyboard navigation support is implemented following WAI-ARIA best practices.\",\n        \"icon\": \"CircleDashedIcon\",\n        \"iconLabel\": \"Dash\"\n      }\n    ],\n    \"iconLabel\": \"@\"\n  }\n]\n  },\n  methods: {\n    handleValueChange(e) {\n      this.setData({ value: e.detail.value })\n    },\n    toggleCollapsible(e) {\n      const itemIndex = e.currentTarget.dataset.itemIndex\n      const collapsibleIndex = e.currentTarget.dataset.collapsibleIndex\n      const items = this.data.items.slice()\n      const collapsible = items[itemIndex]?.collapsibles?.[collapsibleIndex]\n      if (!collapsible) return\n      collapsible.open = !collapsible.open\n      this.setData({ items })\n    }\n  }\n})"
        }
      ],
      "meta": {
        "tags": [
          "accordion",
          "collapsible",
          "radix"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "accordion-20",
          "group": "accordion",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "accordion-20",
              "path": "registry/default/components/accordion/accordion-20.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "accordion-20",
              "path": "registry/default/components/accordion/accordion-20.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "accordion-20",
              "path": "registry/default/components/accordion/accordion-20.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "accordion-20",
              "path": "registry/default/components/accordion/accordion-20.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "accordion",
        "title": "Accordion · Multi-level w/ icon"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "accordion"
      ]
    },
    {
      "name": "tooltip-01",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/tooltip.json"
      ],
      "files": [
        {
          "path": "registry/default/components/tooltip/tooltip-01.tsx",
          "type": "registry:component",
          "target": "components/ui/tooltip-01.tsx",
          "content": "import { Button, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <TooltipProvider delayDuration={0}>\n      <Tooltip>\n        <TooltipTrigger asChild>\n          <Button variant=\"outline\" size=\"sm\">\n            Tiny\n          </Button>\n        </TooltipTrigger>\n        <TooltipContent className=\"px-2 py-1 text-xs\">This is a simple tooltip</TooltipContent>\n      </Tooltip>\n    </TooltipProvider>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-01.vue",
          "target": "components/ui/tooltip-01.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\nimport { Tooltip } from '@timui/vue';\nimport { TooltipContent } from '@timui/vue';\nimport { TooltipProvider } from '@timui/vue';\nimport { TooltipTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <TooltipProvider :delayDuration=\"0\"><Tooltip><TooltipTrigger as-child><Button variant=\"outline\" size=\"sm\">Tiny\n          </Button></TooltipTrigger><TooltipContent class=\"px-2 py-1 text-xs\">This is a simple tooltip</TooltipContent></Tooltip></TooltipProvider>\n</template>\n"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-01.html",
          "target": "components/ui/tooltip-01.html",
          "type": "registry:component",
          "content": "<template>\n  <TooltipProvider delayduration=\"${0}\"><Tooltip><TooltipTrigger aschild><Button variant=\"outline\" size=\"sm\">Tiny\n          </Button></TooltipTrigger><TooltipContent class=\"px-2 py-1 text-xs\">This is a simple tooltip</TooltipContent></Tooltip></TooltipProvider>\n</template>"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-01.wxml",
          "target": "components/ui/tooltip-01/tooltip-01.wxml",
          "type": "registry:component",
          "content": "<view>\n  <tooltipprovider delayduration=\"{{0}}\"><tooltip><tooltiptrigger aschild><button variant=\"outline\" size=\"sm\">Tiny\n          </button></tooltiptrigger><tooltipcontent class=\"px-2 py-1 text-xs\">This is a simple tooltip</tooltipcontent></tooltip></tooltipprovider>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tooltip",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tooltip-01",
          "group": "tooltip",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tooltip-01",
              "path": "registry/default/components/tooltip/tooltip-01.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tooltip-01",
              "path": "registry/default/components/tooltip/tooltip-01.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tooltip-01",
              "path": "registry/default/components/tooltip/tooltip-01.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tooltip-01",
              "path": "registry/default/components/tooltip/tooltip-01.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tooltip",
        "title": "Tooltip · Overlay Pattern"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "tooltip"
      ]
    },
    {
      "name": "tooltip-02",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/tooltip.json"
      ],
      "files": [
        {
          "path": "registry/default/components/tooltip/tooltip-02.tsx",
          "type": "registry:component",
          "target": "components/ui/tooltip-02.tsx",
          "content": "import { Button, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <TooltipProvider delayDuration={0}>\n      <Tooltip>\n        <TooltipTrigger asChild>\n          <Button variant=\"outline\" size=\"sm\">\n            Dark\n          </Button>\n        </TooltipTrigger>\n        <TooltipContent className=\"dark px-2 py-1 text-xs\">\n          This tooltip will be always dark\n        </TooltipContent>\n      </Tooltip>\n    </TooltipProvider>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-02.vue",
          "target": "components/ui/tooltip-02.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\nimport { Tooltip } from '@timui/vue';\nimport { TooltipContent } from '@timui/vue';\nimport { TooltipProvider } from '@timui/vue';\nimport { TooltipTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <TooltipProvider :delayDuration=\"0\"><Tooltip><TooltipTrigger as-child><Button variant=\"outline\" size=\"sm\">Dark\n          </Button></TooltipTrigger><TooltipContent class=\"dark px-2 py-1 text-xs\">This tooltip will be always dark\n        </TooltipContent></Tooltip></TooltipProvider>\n</template>\n"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-02.html",
          "target": "components/ui/tooltip-02.html",
          "type": "registry:component",
          "content": "<template>\n  <TooltipProvider delayduration=\"${0}\"><Tooltip><TooltipTrigger aschild><Button variant=\"outline\" size=\"sm\">Dark\n          </Button></TooltipTrigger><TooltipContent class=\"dark px-2 py-1 text-xs\">This tooltip will be always dark\n        </TooltipContent></Tooltip></TooltipProvider>\n</template>"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-02.wxml",
          "target": "components/ui/tooltip-02/tooltip-02.wxml",
          "type": "registry:component",
          "content": "<view>\n  <tooltipprovider delayduration=\"{{0}}\"><tooltip><tooltiptrigger aschild><button variant=\"outline\" size=\"sm\">Dark\n          </button></tooltiptrigger><tooltipcontent class=\"dark px-2 py-1 text-xs\">This tooltip will be always dark\n        </tooltipcontent></tooltip></tooltipprovider>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tooltip",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tooltip-02",
          "group": "tooltip",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tooltip-02",
              "path": "registry/default/components/tooltip/tooltip-02.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tooltip-02",
              "path": "registry/default/components/tooltip/tooltip-02.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tooltip-02",
              "path": "registry/default/components/tooltip/tooltip-02.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tooltip-02",
              "path": "registry/default/components/tooltip/tooltip-02.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tooltip",
        "title": "Tooltip · Overlay Pattern"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "tooltip"
      ]
    },
    {
      "name": "tooltip-03",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/tooltip.json"
      ],
      "files": [
        {
          "path": "registry/default/components/tooltip/tooltip-03.tsx",
          "type": "registry:component",
          "target": "components/ui/tooltip-03.tsx",
          "content": "import { Button, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <TooltipProvider delayDuration={0}>\n      <Tooltip>\n        <TooltipTrigger asChild>\n          <Button variant=\"outline\" size=\"sm\">\n            W/ arrow\n          </Button>\n        </TooltipTrigger>\n        <TooltipContent className=\"dark px-2 py-1 text-xs\" showArrow={true}>\n          This tooltip has an arrow\n        </TooltipContent>\n      </Tooltip>\n    </TooltipProvider>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-03.vue",
          "target": "components/ui/tooltip-03.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\nimport { Tooltip } from '@timui/vue';\nimport { TooltipContent } from '@timui/vue';\nimport { TooltipProvider } from '@timui/vue';\nimport { TooltipTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <TooltipProvider :delayDuration=\"0\"><Tooltip><TooltipTrigger as-child><Button variant=\"outline\" size=\"sm\">W/ arrow\n          </Button></TooltipTrigger><TooltipContent class=\"dark px-2 py-1 text-xs\" :showArrow=\"true\">This tooltip has an arrow\n        </TooltipContent></Tooltip></TooltipProvider>\n</template>\n"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-03.html",
          "target": "components/ui/tooltip-03.html",
          "type": "registry:component",
          "content": "<template>\n  <TooltipProvider delayduration=\"${0}\"><Tooltip><TooltipTrigger aschild><Button variant=\"outline\" size=\"sm\">W/ arrow\n          </Button></TooltipTrigger><TooltipContent class=\"dark px-2 py-1 text-xs\" showarrow=\"${true}\">This tooltip has an arrow\n        </TooltipContent></Tooltip></TooltipProvider>\n</template>"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-03.wxml",
          "target": "components/ui/tooltip-03/tooltip-03.wxml",
          "type": "registry:component",
          "content": "<view>\n  <tooltipprovider delayduration=\"{{0}}\"><tooltip><tooltiptrigger aschild><button variant=\"outline\" size=\"sm\">W/ arrow\n          </button></tooltiptrigger><tooltipcontent class=\"dark px-2 py-1 text-xs\" showarrow=\"{{true}}\">This tooltip has an arrow\n        </tooltipcontent></tooltip></tooltipprovider>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tooltip",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tooltip-03",
          "group": "tooltip",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tooltip-03",
              "path": "registry/default/components/tooltip/tooltip-03.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tooltip-03",
              "path": "registry/default/components/tooltip/tooltip-03.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tooltip-03",
              "path": "registry/default/components/tooltip/tooltip-03.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tooltip-03",
              "path": "registry/default/components/tooltip/tooltip-03.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tooltip",
        "title": "Tooltip · Overlay Pattern"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "tooltip"
      ]
    },
    {
      "name": "tooltip-04",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/tooltip.json"
      ],
      "files": [
        {
          "path": "registry/default/components/tooltip/tooltip-04.tsx",
          "type": "registry:component",
          "target": "components/ui/tooltip-04.tsx",
          "content": "import { Button, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <TooltipProvider delayDuration={0}>\n      <Tooltip>\n        <TooltipTrigger asChild>\n          <Button variant=\"outline\" size=\"sm\">\n            W/ title\n          </Button>\n        </TooltipTrigger>\n        <TooltipContent className=\"py-3\">\n          <div className=\"space-y-1\">\n            <p className=\"text-[13px] font-medium\">Tooltip with title</p>\n            <p className=\"text-muted-foreground text-xs\">\n              Tooltips are made to be highly customizable, with features like dynamic placement,\n              rich content, and a robust API. You can even use them as a full-featured dropdown menu\n              by setting the <code>trigger</code> prop to <code>click</code>.\n            </p>\n          </div>\n        </TooltipContent>\n      </Tooltip>\n    </TooltipProvider>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-04.vue",
          "target": "components/ui/tooltip-04.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\nimport { Tooltip } from '@timui/vue';\nimport { TooltipContent } from '@timui/vue';\nimport { TooltipProvider } from '@timui/vue';\nimport { TooltipTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <TooltipProvider :delayDuration=\"0\"><Tooltip><TooltipTrigger as-child><Button variant=\"outline\" size=\"sm\">W/ title\n          </Button></TooltipTrigger><TooltipContent class=\"py-3\"><div class=\"space-y-1\"><p class=\"text-[13px] font-medium\">Tooltip with title</p><p class=\"text-muted-foreground text-xs\">Tooltips are made to be highly customizable, with features like dynamic placement,\n              rich content, and a robust API. You can even use them as a full-featured dropdown menu\n              by setting the <code>trigger</code>prop to <code>click</code>.\n            </p></div></TooltipContent></Tooltip></TooltipProvider>\n</template>\n"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-04.html",
          "target": "components/ui/tooltip-04.html",
          "type": "registry:component",
          "content": "<template>\n  <TooltipProvider delayduration=\"${0}\"><Tooltip><TooltipTrigger aschild><Button variant=\"outline\" size=\"sm\">W/ title\n          </Button></TooltipTrigger><TooltipContent class=\"py-3\"><div class=\"space-y-1\"><p class=\"text-[13px] font-medium\">Tooltip with title</p><p class=\"text-muted-foreground text-xs\">Tooltips are made to be highly customizable, with features like dynamic placement,\n              rich content, and a robust API. You can even use them as a full-featured dropdown menu\n              by setting the <code>trigger</code>prop to <code>click</code>.\n            </p></div></TooltipContent></Tooltip></TooltipProvider>\n</template>"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-04.wxml",
          "target": "components/ui/tooltip-04/tooltip-04.wxml",
          "type": "registry:component",
          "content": "<view>\n  <tooltipprovider delayduration=\"{{0}}\"><tooltip><tooltiptrigger aschild><button variant=\"outline\" size=\"sm\">W/ title\n          </button></tooltiptrigger><tooltipcontent class=\"py-3\"><view class=\"space-y-1\"><text class=\"text-[13px] font-medium\">Tooltip with title</text><text class=\"text-muted-foreground text-xs\">Tooltips are made to be highly customizable, with features like dynamic placement,\n              rich content, and a robust API. You can even use them as a full-featured dropdown menu\n              by setting the <code>trigger</code>prop to <code>click</code>.\n            </text></view></tooltipcontent></tooltip></tooltipprovider>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tooltip",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tooltip-04",
          "group": "tooltip",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tooltip-04",
              "path": "registry/default/components/tooltip/tooltip-04.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tooltip-04",
              "path": "registry/default/components/tooltip/tooltip-04.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tooltip-04",
              "path": "registry/default/components/tooltip/tooltip-04.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tooltip-04",
              "path": "registry/default/components/tooltip/tooltip-04.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tooltip",
        "title": "Tooltip · Overlay Pattern"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "tooltip"
      ]
    },
    {
      "name": "tooltip-05",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/tooltip.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/tooltip/tooltip-05.tsx",
          "type": "registry:component",
          "target": "components/ui/tooltip-05.tsx",
          "content": "import { Button, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@timui/react'\nimport { GlobeIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <TooltipProvider delayDuration={0}>\n      <Tooltip>\n        <TooltipTrigger asChild>\n          <Button variant=\"outline\" size=\"sm\">\n            W/ icon\n          </Button>\n        </TooltipTrigger>\n        <TooltipContent className=\"dark py-3\">\n          <div className=\"flex gap-3\">\n            <GlobeIcon className=\"mt-0.5 shrink-0 opacity-60\" size={16} aria-hidden=\"true\" />\n            <div className=\"space-y-1\">\n              <p className=\"text-[13px] font-medium\">Tooltip with title and icon</p>\n              <p className=\"text-muted-foreground text-xs\">\n                Tooltips are made to be highly customizable, with features like dynamic placement,\n                rich content, and a robust API.\n              </p>\n            </div>\n          </div>\n        </TooltipContent>\n      </Tooltip>\n    </TooltipProvider>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-05.vue",
          "target": "components/ui/tooltip-05.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { GlobeIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { Tooltip } from '@timui/vue';\nimport { TooltipContent } from '@timui/vue';\nimport { TooltipProvider } from '@timui/vue';\nimport { TooltipTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <TooltipProvider :delayDuration=\"0\"><Tooltip><TooltipTrigger as-child><Button variant=\"outline\" size=\"sm\">W/ icon\n          </Button></TooltipTrigger><TooltipContent class=\"dark py-3\"><div class=\"flex gap-3\"><GlobeIcon class=\"mt-0.5 shrink-0 opacity-60\" :size=\"16\" aria-hidden=\"true\" /><div class=\"space-y-1\"><p class=\"text-[13px] font-medium\">Tooltip with title and icon</p><p class=\"text-muted-foreground text-xs\">Tooltips are made to be highly customizable, with features like dynamic placement,\n                rich content, and a robust API.\n              </p></div></div></TooltipContent></Tooltip></TooltipProvider>\n</template>\n"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-05.html",
          "target": "components/ui/tooltip-05.html",
          "type": "registry:component",
          "content": "<template>\n  <TooltipProvider delayduration=\"${0}\"><Tooltip><TooltipTrigger aschild><Button variant=\"outline\" size=\"sm\">W/ icon\n          </Button></TooltipTrigger><TooltipContent class=\"dark py-3\"><div class=\"flex gap-3\"><GlobeIcon class=\"mt-0.5 shrink-0 opacity-60\" size=\"${16}\" aria-hidden=\"true\" /><div class=\"space-y-1\"><p class=\"text-[13px] font-medium\">Tooltip with title and icon</p><p class=\"text-muted-foreground text-xs\">Tooltips are made to be highly customizable, with features like dynamic placement,\n                rich content, and a robust API.\n              </p></div></div></TooltipContent></Tooltip></TooltipProvider>\n</template>"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-05.wxml",
          "target": "components/ui/tooltip-05/tooltip-05.wxml",
          "type": "registry:component",
          "content": "<view>\n  <tooltipprovider delayduration=\"{{0}}\"><tooltip><tooltiptrigger aschild><button variant=\"outline\" size=\"sm\">W/ icon\n          </button></tooltiptrigger><tooltipcontent class=\"dark py-3\"><view class=\"flex gap-3\"><globeicon class=\"mt-0.5 shrink-0 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" /><view class=\"space-y-1\"><text class=\"text-[13px] font-medium\">Tooltip with title and icon</text><text class=\"text-muted-foreground text-xs\">Tooltips are made to be highly customizable, with features like dynamic placement,\n                rich content, and a robust API.\n              </text></view></view></tooltipcontent></tooltip></tooltipprovider>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tooltip",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tooltip-05",
          "group": "tooltip",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tooltip-05",
              "path": "registry/default/components/tooltip/tooltip-05.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tooltip-05",
              "path": "registry/default/components/tooltip/tooltip-05.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tooltip-05",
              "path": "registry/default/components/tooltip/tooltip-05.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tooltip-05",
              "path": "registry/default/components/tooltip/tooltip-05.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tooltip",
        "title": "Tooltip · Overlay Pattern"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "tooltip"
      ]
    },
    {
      "name": "tooltip-06",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/tooltip.json"
      ],
      "files": [
        {
          "path": "registry/default/components/tooltip/tooltip-06.tsx",
          "type": "registry:component",
          "target": "components/ui/tooltip-06.tsx",
          "content": "import { Button, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <TooltipProvider delayDuration={0}>\n      <Tooltip>\n        <TooltipTrigger asChild>\n          <Button variant=\"outline\" size=\"sm\">\n            W/ image\n          </Button>\n        </TooltipTrigger>\n        <TooltipContent className=\"py-3\">\n          <div className=\"space-y-2\">\n            <img\n              className=\"w-full rounded\"\n              src=\"/dialog-content.png\"\n              width={382}\n              height={216}\n              alt=\"Content image\"\n            />\n            <div className=\"space-y-1\">\n              <p className=\"text-[13px] font-medium\">Tooltip with title and icon</p>\n              <p className=\"text-muted-foreground text-xs\">\n                Tooltips are made to be highly customizable, with features like dynamic placement,\n                rich content, and a robust API.\n              </p>\n            </div>\n          </div>\n        </TooltipContent>\n      </Tooltip>\n    </TooltipProvider>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-06.vue",
          "target": "components/ui/tooltip-06.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\nimport { Tooltip } from '@timui/vue';\nimport { TooltipContent } from '@timui/vue';\nimport { TooltipProvider } from '@timui/vue';\nimport { TooltipTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <TooltipProvider :delayDuration=\"0\"><Tooltip><TooltipTrigger as-child><Button variant=\"outline\" size=\"sm\">W/ image\n          </Button></TooltipTrigger><TooltipContent class=\"py-3\"><div class=\"space-y-2\"><img class=\"w-full rounded\" src=\"/dialog-content.png\" :width=\"382\" :height=\"216\" alt=\"Content image\" /><div class=\"space-y-1\"><p class=\"text-[13px] font-medium\">Tooltip with title and icon</p><p class=\"text-muted-foreground text-xs\">Tooltips are made to be highly customizable, with features like dynamic placement,\n                rich content, and a robust API.\n              </p></div></div></TooltipContent></Tooltip></TooltipProvider>\n</template>\n"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-06.html",
          "target": "components/ui/tooltip-06.html",
          "type": "registry:component",
          "content": "<template>\n  <TooltipProvider delayduration=\"${0}\"><Tooltip><TooltipTrigger aschild><Button variant=\"outline\" size=\"sm\">W/ image\n          </Button></TooltipTrigger><TooltipContent class=\"py-3\"><div class=\"space-y-2\"><img class=\"w-full rounded\" src=\"/dialog-content.png\" width=\"${382}\" height=\"${216}\" alt=\"Content image\" /><div class=\"space-y-1\"><p class=\"text-[13px] font-medium\">Tooltip with title and icon</p><p class=\"text-muted-foreground text-xs\">Tooltips are made to be highly customizable, with features like dynamic placement,\n                rich content, and a robust API.\n              </p></div></div></TooltipContent></Tooltip></TooltipProvider>\n</template>"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-06.wxml",
          "target": "components/ui/tooltip-06/tooltip-06.wxml",
          "type": "registry:component",
          "content": "<view>\n  <tooltipprovider delayduration=\"{{0}}\"><tooltip><tooltiptrigger aschild><button variant=\"outline\" size=\"sm\">W/ image\n          </button></tooltiptrigger><tooltipcontent class=\"py-3\"><view class=\"space-y-2\"><image class=\"w-full rounded\" src=\"/dialog-content.png\" width=\"{{382}}\" height=\"{{216}}\" alt=\"Content image\" /><view class=\"space-y-1\"><text class=\"text-[13px] font-medium\">Tooltip with title and icon</text><text class=\"text-muted-foreground text-xs\">Tooltips are made to be highly customizable, with features like dynamic placement,\n                rich content, and a robust API.\n              </text></view></view></tooltipcontent></tooltip></tooltipprovider>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tooltip",
          "image",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tooltip-06",
          "group": "tooltip",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tooltip-06",
              "path": "registry/default/components/tooltip/tooltip-06.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tooltip-06",
              "path": "registry/default/components/tooltip/tooltip-06.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tooltip-06",
              "path": "registry/default/components/tooltip/tooltip-06.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tooltip-06",
              "path": "registry/default/components/tooltip/tooltip-06.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tooltip",
        "title": "Tooltip · Overlay Pattern"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "tooltip"
      ]
    },
    {
      "name": "tooltip-07",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/tooltip.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/tooltip/tooltip-07.tsx",
          "type": "registry:component",
          "target": "components/ui/tooltip-07.tsx",
          "content": "import { Button, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@timui/react'\nimport {\n  ChevronDownIcon,\n  ChevronLeftIcon,\n  ChevronRightIcon,\n  ChevronUpIcon,\n  CircleIcon,\n} from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <div className=\"inline-grid w-fit grid-cols-3 gap-1\">\n      <TooltipProvider delayDuration={0}>\n        <Tooltip>\n          <TooltipTrigger asChild>\n            <Button\n              className=\"col-start-2\"\n              variant=\"outline\"\n              size=\"icon\"\n              aria-label=\"Pan camera up\"\n            >\n              <ChevronUpIcon size={16} aria-hidden=\"true\" />\n            </Button>\n          </TooltipTrigger>\n          <TooltipContent side=\"top\" className=\"px-2 py-1 text-xs\">\n            Pan top\n            <kbd className=\"bg-background text-muted-foreground/70 ms-2 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">\n              ⌘T\n            </kbd>\n          </TooltipContent>\n        </Tooltip>\n      </TooltipProvider>\n      <TooltipProvider delayDuration={0}>\n        <Tooltip>\n          <TooltipTrigger asChild>\n            <Button\n              className=\"col-start-1\"\n              variant=\"outline\"\n              size=\"icon\"\n              aria-label=\"Pan camera left\"\n            >\n              <ChevronLeftIcon size={16} aria-hidden=\"true\" />\n            </Button>\n          </TooltipTrigger>\n          <TooltipContent side=\"left\" className=\"px-2 py-1 text-xs\">\n            Pan left\n            <kbd className=\"bg-background text-muted-foreground/70 ms-2 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">\n              ⌘L\n            </kbd>\n          </TooltipContent>\n        </Tooltip>\n      </TooltipProvider>\n      <div className=\"flex items-center justify-center\" aria-hidden=\"true\">\n        <CircleIcon className=\"opacity-60\" size={16} />\n      </div>\n      <TooltipProvider delayDuration={0}>\n        <Tooltip>\n          <TooltipTrigger asChild>\n            <Button variant=\"outline\" size=\"icon\" aria-label=\"Pan camera right\">\n              <ChevronRightIcon size={16} aria-hidden=\"true\" />\n            </Button>\n          </TooltipTrigger>\n          <TooltipContent side=\"right\" className=\"px-2 py-1 text-xs\">\n            Pan right\n            <kbd className=\"bg-background text-muted-foreground/70 ms-2 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">\n              ⌘R\n            </kbd>\n          </TooltipContent>\n        </Tooltip>\n      </TooltipProvider>\n      <TooltipProvider delayDuration={0}>\n        <Tooltip>\n          <TooltipTrigger asChild>\n            <Button\n              className=\"col-start-2\"\n              variant=\"outline\"\n              size=\"icon\"\n              aria-label=\"Pan camera down\"\n            >\n              <ChevronDownIcon size={16} aria-hidden=\"true\" />\n            </Button>\n          </TooltipTrigger>\n          <TooltipContent side=\"bottom\" className=\"px-2 py-1 text-xs\">\n            Pan bottom\n            <kbd className=\"bg-background text-muted-foreground/70 ms-2 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">\n              ⌘B\n            </kbd>\n          </TooltipContent>\n        </Tooltip>\n      </TooltipProvider>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-07.vue",
          "target": "components/ui/tooltip-07.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, CircleIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { Tooltip } from '@timui/vue';\nimport { TooltipContent } from '@timui/vue';\nimport { TooltipProvider } from '@timui/vue';\nimport { TooltipTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"inline-grid w-fit grid-cols-3 gap-1\"><TooltipProvider :delayDuration=\"0\"><Tooltip><TooltipTrigger as-child><Button class=\"col-start-2\" variant=\"outline\" size=\"icon\" aria-label=\"Pan camera up\"><ChevronUpIcon :size=\"16\" aria-hidden=\"true\" /></Button></TooltipTrigger><TooltipContent side=\"top\" class=\"px-2 py-1 text-xs\">Pan top\n            <kbd class=\"bg-background text-muted-foreground/70 ms-2 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">⌘T\n            </kbd></TooltipContent></Tooltip></TooltipProvider><TooltipProvider :delayDuration=\"0\"><Tooltip><TooltipTrigger as-child><Button class=\"col-start-1\" variant=\"outline\" size=\"icon\" aria-label=\"Pan camera left\"><ChevronLeftIcon :size=\"16\" aria-hidden=\"true\" /></Button></TooltipTrigger><TooltipContent side=\"left\" class=\"px-2 py-1 text-xs\">Pan left\n            <kbd class=\"bg-background text-muted-foreground/70 ms-2 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">⌘L\n            </kbd></TooltipContent></Tooltip></TooltipProvider><div class=\"flex items-center justify-center\" aria-hidden=\"true\"><CircleIcon class=\"opacity-60\" :size=\"16\" /></div><TooltipProvider :delayDuration=\"0\"><Tooltip><TooltipTrigger as-child><Button variant=\"outline\" size=\"icon\" aria-label=\"Pan camera right\"><ChevronRightIcon :size=\"16\" aria-hidden=\"true\" /></Button></TooltipTrigger><TooltipContent side=\"right\" class=\"px-2 py-1 text-xs\">Pan right\n            <kbd class=\"bg-background text-muted-foreground/70 ms-2 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">⌘R\n            </kbd></TooltipContent></Tooltip></TooltipProvider><TooltipProvider :delayDuration=\"0\"><Tooltip><TooltipTrigger as-child><Button class=\"col-start-2\" variant=\"outline\" size=\"icon\" aria-label=\"Pan camera down\"><ChevronDownIcon :size=\"16\" aria-hidden=\"true\" /></Button></TooltipTrigger><TooltipContent side=\"bottom\" class=\"px-2 py-1 text-xs\">Pan bottom\n            <kbd class=\"bg-background text-muted-foreground/70 ms-2 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">⌘B\n            </kbd></TooltipContent></Tooltip></TooltipProvider></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-07.html",
          "target": "components/ui/tooltip-07.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"inline-grid w-fit grid-cols-3 gap-1\"><TooltipProvider delayduration=\"${0}\"><Tooltip><TooltipTrigger aschild><Button class=\"col-start-2\" variant=\"outline\" size=\"icon\" aria-label=\"Pan camera up\"><ChevronUpIcon size=\"${16}\" aria-hidden=\"true\" /></Button></TooltipTrigger><TooltipContent side=\"top\" class=\"px-2 py-1 text-xs\">Pan top\n            <kbd class=\"bg-background text-muted-foreground/70 ms-2 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">⌘T\n            </kbd></TooltipContent></Tooltip></TooltipProvider><TooltipProvider delayduration=\"${0}\"><Tooltip><TooltipTrigger aschild><Button class=\"col-start-1\" variant=\"outline\" size=\"icon\" aria-label=\"Pan camera left\"><ChevronLeftIcon size=\"${16}\" aria-hidden=\"true\" /></Button></TooltipTrigger><TooltipContent side=\"left\" class=\"px-2 py-1 text-xs\">Pan left\n            <kbd class=\"bg-background text-muted-foreground/70 ms-2 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">⌘L\n            </kbd></TooltipContent></Tooltip></TooltipProvider><div class=\"flex items-center justify-center\" aria-hidden=\"true\"><CircleIcon class=\"opacity-60\" size=\"${16}\" /></div><TooltipProvider delayduration=\"${0}\"><Tooltip><TooltipTrigger aschild><Button variant=\"outline\" size=\"icon\" aria-label=\"Pan camera right\"><ChevronRightIcon size=\"${16}\" aria-hidden=\"true\" /></Button></TooltipTrigger><TooltipContent side=\"right\" class=\"px-2 py-1 text-xs\">Pan right\n            <kbd class=\"bg-background text-muted-foreground/70 ms-2 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">⌘R\n            </kbd></TooltipContent></Tooltip></TooltipProvider><TooltipProvider delayduration=\"${0}\"><Tooltip><TooltipTrigger aschild><Button class=\"col-start-2\" variant=\"outline\" size=\"icon\" aria-label=\"Pan camera down\"><ChevronDownIcon size=\"${16}\" aria-hidden=\"true\" /></Button></TooltipTrigger><TooltipContent side=\"bottom\" class=\"px-2 py-1 text-xs\">Pan bottom\n            <kbd class=\"bg-background text-muted-foreground/70 ms-2 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">⌘B\n            </kbd></TooltipContent></Tooltip></TooltipProvider></div>\n</template>"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-07.wxml",
          "target": "components/ui/tooltip-07/tooltip-07.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"inline-grid w-fit grid-cols-3 gap-1\"><tooltipprovider delayduration=\"{{0}}\"><tooltip><tooltiptrigger aschild><button class=\"col-start-2\" variant=\"outline\" size=\"icon\" aria-label=\"Pan camera up\"><chevronupicon size=\"{{16}}\" aria-hidden=\"true\" /></button></tooltiptrigger><tooltipcontent side=\"top\" class=\"px-2 py-1 text-xs\">Pan top\n            <kbd class=\"bg-background text-muted-foreground/70 ms-2 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">⌘T\n            </kbd></tooltipcontent></tooltip></tooltipprovider><tooltipprovider delayduration=\"{{0}}\"><tooltip><tooltiptrigger aschild><button class=\"col-start-1\" variant=\"outline\" size=\"icon\" aria-label=\"Pan camera left\"><chevronlefticon size=\"{{16}}\" aria-hidden=\"true\" /></button></tooltiptrigger><tooltipcontent side=\"left\" class=\"px-2 py-1 text-xs\">Pan left\n            <kbd class=\"bg-background text-muted-foreground/70 ms-2 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">⌘L\n            </kbd></tooltipcontent></tooltip></tooltipprovider><view class=\"flex items-center justify-center\" aria-hidden=\"true\"><circleicon class=\"opacity-60\" size=\"{{16}}\" /></view><tooltipprovider delayduration=\"{{0}}\"><tooltip><tooltiptrigger aschild><button variant=\"outline\" size=\"icon\" aria-label=\"Pan camera right\"><chevronrighticon size=\"{{16}}\" aria-hidden=\"true\" /></button></tooltiptrigger><tooltipcontent side=\"right\" class=\"px-2 py-1 text-xs\">Pan right\n            <kbd class=\"bg-background text-muted-foreground/70 ms-2 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">⌘R\n            </kbd></tooltipcontent></tooltip></tooltipprovider><tooltipprovider delayduration=\"{{0}}\"><tooltip><tooltiptrigger aschild><button class=\"col-start-2\" variant=\"outline\" size=\"icon\" aria-label=\"Pan camera down\"><chevrondownicon size=\"{{16}}\" aria-hidden=\"true\" /></button></tooltiptrigger><tooltipcontent side=\"bottom\" class=\"px-2 py-1 text-xs\">Pan bottom\n            <kbd class=\"bg-background text-muted-foreground/70 ms-2 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">⌘B\n            </kbd></tooltipcontent></tooltip></tooltipprovider></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tooltip",
          "button",
          "kbd",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tooltip-07",
          "group": "tooltip",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tooltip-07",
              "path": "registry/default/components/tooltip/tooltip-07.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tooltip-07",
              "path": "registry/default/components/tooltip/tooltip-07.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tooltip-07",
              "path": "registry/default/components/tooltip/tooltip-07.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tooltip-07",
              "path": "registry/default/components/tooltip/tooltip-07.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tooltip",
        "title": "Tooltip · Pan camera up"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "tooltip"
      ]
    },
    {
      "name": "tooltip-08",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/tooltip.json"
      ],
      "files": [
        {
          "path": "registry/default/components/tooltip/tooltip-08.tsx",
          "type": "registry:component",
          "target": "components/ui/tooltip-08.tsx",
          "content": "import { Button, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <TooltipProvider delayDuration={0}>\n      <Tooltip>\n        <TooltipTrigger asChild>\n          <Button variant=\"outline\" size=\"sm\">\n            Stats\n          </Button>\n        </TooltipTrigger>\n        <TooltipContent className=\"py-3\">\n          <ul className=\"grid gap-3 text-xs\">\n            <li className=\"grid gap-0.5\">\n              <span className=\"text-muted-foreground\">Status</span>\n              <span className=\"font-medium\">Completed</span>\n            </li>\n            <li className=\"grid gap-0.5\">\n              <span className=\"text-muted-foreground\">Code Coverage</span>\n              <span className=\"font-medium\">94.3%</span>\n            </li>\n            <li className=\"grid gap-0.5\">\n              <span className=\"text-muted-foreground\">Last Deploy</span>\n              <span className=\"font-medium\">Today at 15:42</span>\n            </li>\n            <li className=\"grid gap-0.5\">\n              <span className=\"text-muted-foreground\">Performance Score</span>\n              <span className=\"font-medium\">98/100</span>\n            </li>\n          </ul>\n        </TooltipContent>\n      </Tooltip>\n    </TooltipProvider>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-08.vue",
          "target": "components/ui/tooltip-08.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\nimport { Tooltip } from '@timui/vue';\nimport { TooltipContent } from '@timui/vue';\nimport { TooltipProvider } from '@timui/vue';\nimport { TooltipTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <TooltipProvider :delayDuration=\"0\"><Tooltip><TooltipTrigger as-child><Button variant=\"outline\" size=\"sm\">Stats\n          </Button></TooltipTrigger><TooltipContent class=\"py-3\"><ul class=\"grid gap-3 text-xs\"><li class=\"grid gap-0.5\"><span class=\"text-muted-foreground\">Status</span><span class=\"font-medium\">Completed</span></li><li class=\"grid gap-0.5\"><span class=\"text-muted-foreground\">Code Coverage</span><span class=\"font-medium\">94.3%</span></li><li class=\"grid gap-0.5\"><span class=\"text-muted-foreground\">Last Deploy</span><span class=\"font-medium\">Today at 15:42</span></li><li class=\"grid gap-0.5\"><span class=\"text-muted-foreground\">Performance Score</span><span class=\"font-medium\">98/100</span></li></ul></TooltipContent></Tooltip></TooltipProvider>\n</template>\n"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-08.html",
          "target": "components/ui/tooltip-08.html",
          "type": "registry:component",
          "content": "<template>\n  <TooltipProvider delayduration=\"${0}\"><Tooltip><TooltipTrigger aschild><Button variant=\"outline\" size=\"sm\">Stats\n          </Button></TooltipTrigger><TooltipContent class=\"py-3\"><ul class=\"grid gap-3 text-xs\"><li class=\"grid gap-0.5\"><span class=\"text-muted-foreground\">Status</span><span class=\"font-medium\">Completed</span></li><li class=\"grid gap-0.5\"><span class=\"text-muted-foreground\">Code Coverage</span><span class=\"font-medium\">94.3%</span></li><li class=\"grid gap-0.5\"><span class=\"text-muted-foreground\">Last Deploy</span><span class=\"font-medium\">Today at 15:42</span></li><li class=\"grid gap-0.5\"><span class=\"text-muted-foreground\">Performance Score</span><span class=\"font-medium\">98/100</span></li></ul></TooltipContent></Tooltip></TooltipProvider>\n</template>"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-08.wxml",
          "target": "components/ui/tooltip-08/tooltip-08.wxml",
          "type": "registry:component",
          "content": "<view>\n  <tooltipprovider delayduration=\"{{0}}\"><tooltip><tooltiptrigger aschild><button variant=\"outline\" size=\"sm\">Stats\n          </button></tooltiptrigger><tooltipcontent class=\"py-3\"><ul class=\"grid gap-3 text-xs\"><li class=\"grid gap-0.5\"><text class=\"text-muted-foreground\">Status</text><text class=\"font-medium\">Completed</text></li><li class=\"grid gap-0.5\"><text class=\"text-muted-foreground\">Code Coverage</text><text class=\"font-medium\">94.3%</text></li><li class=\"grid gap-0.5\"><text class=\"text-muted-foreground\">Last Deploy</text><text class=\"font-medium\">Today at 15:42</text></li><li class=\"grid gap-0.5\"><text class=\"text-muted-foreground\">Performance Score</text><text class=\"font-medium\">98/100</text></li></ul></tooltipcontent></tooltip></tooltipprovider>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tooltip",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tooltip-08",
          "group": "tooltip",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tooltip-08",
              "path": "registry/default/components/tooltip/tooltip-08.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tooltip-08",
              "path": "registry/default/components/tooltip/tooltip-08.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tooltip-08",
              "path": "registry/default/components/tooltip/tooltip-08.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tooltip-08",
              "path": "registry/default/components/tooltip/tooltip-08.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tooltip",
        "title": "Tooltip · Overlay Pattern"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "tooltip"
      ]
    },
    {
      "name": "tooltip-09",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/tooltip.json"
      ],
      "files": [
        {
          "path": "registry/default/components/tooltip/tooltip-09.tsx",
          "type": "registry:component",
          "target": "components/ui/tooltip-09.tsx",
          "content": "import { Button, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <TooltipProvider delayDuration={0}>\n      <Tooltip>\n        <TooltipTrigger asChild>\n          <Button variant=\"outline\" size=\"sm\">\n            Chart\n          </Button>\n        </TooltipTrigger>\n        <TooltipContent className=\"py-2\">\n          <div className=\"space-y-2\">\n            <div className=\"text-[13px] font-medium\">Tuesday, Aug 13</div>\n            <div className=\"flex items-center gap-2 text-xs\">\n              <svg\n                width=\"8\"\n                height=\"8\"\n                fill=\"currentColor\"\n                viewBox=\"0 0 8 8\"\n                xmlns=\"http://www.w3.org/2000/svg\"\n                className=\"shrink-0 text-indigo-500\"\n                aria-hidden=\"true\"\n              >\n                <circle cx=\"4\" cy=\"4\" r=\"4\"></circle>\n              </svg>\n              <span className=\"flex grow gap-2\">\n                Sales <span className=\"ml-auto\">$40</span>\n              </span>\n            </div>\n            <div className=\"flex items-center gap-2 text-xs\">\n              <svg\n                width=\"8\"\n                height=\"8\"\n                fill=\"currentColor\"\n                viewBox=\"0 0 8 8\"\n                xmlns=\"http://www.w3.org/2000/svg\"\n                className=\"shrink-0 text-purple-500\"\n                aria-hidden=\"true\"\n              >\n                <circle cx=\"4\" cy=\"4\" r=\"4\"></circle>\n              </svg>\n              <span className=\"flex grow gap-2\">\n                Revenue <span className=\"ml-auto\">$74</span>\n              </span>\n            </div>\n            <div className=\"flex items-center gap-2 text-xs\">\n              <svg\n                width=\"8\"\n                height=\"8\"\n                fill=\"currentColor\"\n                viewBox=\"0 0 8 8\"\n                xmlns=\"http://www.w3.org/2000/svg\"\n                className=\"shrink-0 text-rose-500\"\n                aria-hidden=\"true\"\n              >\n                <circle cx=\"4\" cy=\"4\" r=\"4\"></circle>\n              </svg>\n              <span className=\"flex grow gap-2\">\n                Costs <span className=\"ml-auto\">$410</span>\n              </span>\n            </div>\n          </div>\n        </TooltipContent>\n      </Tooltip>\n    </TooltipProvider>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-09.vue",
          "target": "components/ui/tooltip-09.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\nimport { Tooltip } from '@timui/vue';\nimport { TooltipContent } from '@timui/vue';\nimport { TooltipProvider } from '@timui/vue';\nimport { TooltipTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <TooltipProvider :delayDuration=\"0\"><Tooltip><TooltipTrigger as-child><Button variant=\"outline\" size=\"sm\">Chart\n          </Button></TooltipTrigger><TooltipContent class=\"py-2\"><div class=\"space-y-2\"><div class=\"text-[13px] font-medium\">Tuesday, Aug 13</div><div class=\"flex items-center gap-2 text-xs\"><svg width=\"8\" height=\"8\" fill=\"currentColor\" viewBox=\"0 0 8 8\" xmlns=\"http://www.w3.org/2000/svg\" class=\"shrink-0 text-indigo-500\" aria-hidden=\"true\"><circle cx=\"4\" cy=\"4\" r=\"4\"></circle></svg><span class=\"flex grow gap-2\">Sales <span class=\"ml-auto\">$40</span></span></div><div class=\"flex items-center gap-2 text-xs\"><svg width=\"8\" height=\"8\" fill=\"currentColor\" viewBox=\"0 0 8 8\" xmlns=\"http://www.w3.org/2000/svg\" class=\"shrink-0 text-purple-500\" aria-hidden=\"true\"><circle cx=\"4\" cy=\"4\" r=\"4\"></circle></svg><span class=\"flex grow gap-2\">Revenue <span class=\"ml-auto\">$74</span></span></div><div class=\"flex items-center gap-2 text-xs\"><svg width=\"8\" height=\"8\" fill=\"currentColor\" viewBox=\"0 0 8 8\" xmlns=\"http://www.w3.org/2000/svg\" class=\"shrink-0 text-rose-500\" aria-hidden=\"true\"><circle cx=\"4\" cy=\"4\" r=\"4\"></circle></svg><span class=\"flex grow gap-2\">Costs <span class=\"ml-auto\">$410</span></span></div></div></TooltipContent></Tooltip></TooltipProvider>\n</template>\n"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-09.html",
          "target": "components/ui/tooltip-09.html",
          "type": "registry:component",
          "content": "<template>\n  <TooltipProvider delayduration=\"${0}\"><Tooltip><TooltipTrigger aschild><Button variant=\"outline\" size=\"sm\">Chart\n          </Button></TooltipTrigger><TooltipContent class=\"py-2\"><div class=\"space-y-2\"><div class=\"text-[13px] font-medium\">Tuesday, Aug 13</div><div class=\"flex items-center gap-2 text-xs\"><svg width=\"8\" height=\"8\" fill=\"currentColor\" viewbox=\"0 0 8 8\" xmlns=\"http://www.w3.org/2000/svg\" class=\"shrink-0 text-indigo-500\" aria-hidden=\"true\"><circle cx=\"4\" cy=\"4\" r=\"4\"></circle></svg><span class=\"flex grow gap-2\">Sales <span class=\"ml-auto\">$40</span></span></div><div class=\"flex items-center gap-2 text-xs\"><svg width=\"8\" height=\"8\" fill=\"currentColor\" viewbox=\"0 0 8 8\" xmlns=\"http://www.w3.org/2000/svg\" class=\"shrink-0 text-purple-500\" aria-hidden=\"true\"><circle cx=\"4\" cy=\"4\" r=\"4\"></circle></svg><span class=\"flex grow gap-2\">Revenue <span class=\"ml-auto\">$74</span></span></div><div class=\"flex items-center gap-2 text-xs\"><svg width=\"8\" height=\"8\" fill=\"currentColor\" viewbox=\"0 0 8 8\" xmlns=\"http://www.w3.org/2000/svg\" class=\"shrink-0 text-rose-500\" aria-hidden=\"true\"><circle cx=\"4\" cy=\"4\" r=\"4\"></circle></svg><span class=\"flex grow gap-2\">Costs <span class=\"ml-auto\">$410</span></span></div></div></TooltipContent></Tooltip></TooltipProvider>\n</template>"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-09.wxml",
          "target": "components/ui/tooltip-09/tooltip-09.wxml",
          "type": "registry:component",
          "content": "<view>\n  <tooltipprovider delayduration=\"{{0}}\"><tooltip><tooltiptrigger aschild><button variant=\"outline\" size=\"sm\">Chart\n          </button></tooltiptrigger><tooltipcontent class=\"py-2\"><view class=\"space-y-2\"><view class=\"text-[13px] font-medium\">Tuesday, Aug 13</view><view class=\"flex items-center gap-2 text-xs\"><svg width=\"8\" height=\"8\" fill=\"currentColor\" viewbox=\"0 0 8 8\" xmlns=\"http://www.w3.org/2000/svg\" class=\"shrink-0 text-indigo-500\" aria-hidden=\"true\"><circle cx=\"4\" cy=\"4\" r=\"4\"></circle></svg><text class=\"flex grow gap-2\">Sales <text class=\"ml-auto\">$40</text></text></view><view class=\"flex items-center gap-2 text-xs\"><svg width=\"8\" height=\"8\" fill=\"currentColor\" viewbox=\"0 0 8 8\" xmlns=\"http://www.w3.org/2000/svg\" class=\"shrink-0 text-purple-500\" aria-hidden=\"true\"><circle cx=\"4\" cy=\"4\" r=\"4\"></circle></svg><text class=\"flex grow gap-2\">Revenue <text class=\"ml-auto\">$74</text></text></view><view class=\"flex items-center gap-2 text-xs\"><svg width=\"8\" height=\"8\" fill=\"currentColor\" viewbox=\"0 0 8 8\" xmlns=\"http://www.w3.org/2000/svg\" class=\"shrink-0 text-rose-500\" aria-hidden=\"true\"><circle cx=\"4\" cy=\"4\" r=\"4\"></circle></svg><text class=\"flex grow gap-2\">Costs <text class=\"ml-auto\">$410</text></text></view></view></tooltipcontent></tooltip></tooltipprovider>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tooltip",
          "chart",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tooltip-09",
          "group": "tooltip",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tooltip-09",
              "path": "registry/default/components/tooltip/tooltip-09.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tooltip-09",
              "path": "registry/default/components/tooltip/tooltip-09.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tooltip-09",
              "path": "registry/default/components/tooltip/tooltip-09.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tooltip-09",
              "path": "registry/default/components/tooltip/tooltip-09.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tooltip",
        "title": "Tooltip · Overlay Pattern"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "tooltip"
      ]
    },
    {
      "name": "tooltip-10",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/hover-card.json"
      ],
      "files": [
        {
          "path": "registry/default/components/tooltip/tooltip-10.tsx",
          "type": "registry:component",
          "target": "components/ui/tooltip-10.tsx",
          "content": "import { Button, HoverCard, HoverCardContent, HoverCardTrigger } from '@timui/react'\n\nexport default function HoverCardDemo() {\n  return (\n    <HoverCard>\n      <HoverCardTrigger asChild>\n        <Button\n          className=\"size-auto overflow-hidden rounded-full bg-transparent p-0 hover:bg-transparent\"\n          aria-label=\"My profile\"\n          asChild\n        >\n          <a href=\"#\">\n            <img src=\"/avatar-40-04.jpg\" width={40} height={40} alt=\"Avatar\" />\n          </a>\n        </Button>\n      </HoverCardTrigger>\n      <HoverCardContent className=\"w-[340px]\">\n        <div className=\"flex items-start gap-3\">\n          <img\n            className=\"shrink-0 rounded-full\"\n            src=\"/avatar-40-04.jpg\"\n            width={40}\n            height={40}\n            alt=\"Avatar\"\n          />\n          <div className=\"space-y-1\">\n            <p className=\"text-sm font-medium\">@Origin_UI</p>\n            <p className=\"text-muted-foreground text-sm\">\n              Beautiful UI components built with Tailwind CSS and Next.js.\n            </p>\n          </div>\n        </div>\n      </HoverCardContent>\n    </HoverCard>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-10.vue",
          "target": "components/ui/tooltip-10.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\nimport { HoverCard } from '@timui/vue';\nimport { HoverCardContent } from '@timui/vue';\nimport { HoverCardTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <HoverCard><HoverCardTrigger as-child><Button class=\"size-auto overflow-hidden rounded-full bg-transparent p-0 hover:bg-transparent\" aria-label=\"My profile\" as-child><a href=\"#\"><img src=\"/avatar-40-04.jpg\" :width=\"40\" :height=\"40\" alt=\"Avatar\" /></a></Button></HoverCardTrigger><HoverCardContent class=\"w-[340px]\"><div class=\"flex items-start gap-3\"><img class=\"shrink-0 rounded-full\" src=\"/avatar-40-04.jpg\" :width=\"40\" :height=\"40\" alt=\"Avatar\" /><div class=\"space-y-1\"><p class=\"text-sm font-medium\">@Origin_UI</p><p class=\"text-muted-foreground text-sm\">Beautiful UI components built with Tailwind CSS and Next.js.\n            </p></div></div></HoverCardContent></HoverCard>\n</template>\n"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-10.html",
          "target": "components/ui/tooltip-10.html",
          "type": "registry:component",
          "content": "<template>\n  <HoverCard><HoverCardTrigger aschild><Button class=\"size-auto overflow-hidden rounded-full bg-transparent p-0 hover:bg-transparent\" aria-label=\"My profile\" aschild><a href=\"#\"><img src=\"/avatar-40-04.jpg\" width=\"${40}\" height=\"${40}\" alt=\"Avatar\" /></a></Button></HoverCardTrigger><HoverCardContent class=\"w-[340px]\"><div class=\"flex items-start gap-3\"><img class=\"shrink-0 rounded-full\" src=\"/avatar-40-04.jpg\" width=\"${40}\" height=\"${40}\" alt=\"Avatar\" /><div class=\"space-y-1\"><p class=\"text-sm font-medium\">@Origin_UI</p><p class=\"text-muted-foreground text-sm\">Beautiful UI components built with Tailwind CSS and Next.js.\n            </p></div></div></HoverCardContent></HoverCard>\n</template>"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-10.wxml",
          "target": "components/ui/tooltip-10/tooltip-10.wxml",
          "type": "registry:component",
          "content": "<view>\n  <hovercard><hovercardtrigger aschild><button class=\"size-auto overflow-hidden rounded-full bg-transparent p-0 hover:bg-transparent\" aria-label=\"My profile\" aschild><a href=\"#\"><image src=\"/avatar-40-04.jpg\" width=\"{{40}}\" height=\"{{40}}\" alt=\"Avatar\" /></a></button></hovercardtrigger><hovercardcontent class=\"w-[340px]\"><view class=\"flex items-start gap-3\"><image class=\"shrink-0 rounded-full\" src=\"/avatar-40-04.jpg\" width=\"{{40}}\" height=\"{{40}}\" alt=\"Avatar\" /><view class=\"space-y-1\"><text class=\"text-sm font-medium\">@Origin_UI</text><text class=\"text-muted-foreground text-sm\">Beautiful UI components built with Tailwind CSS and Next.js.\n            </text></view></view></hovercardcontent></hovercard>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tooltip",
          "hover card",
          "user",
          "avatar",
          "profile",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tooltip-10",
          "group": "tooltip",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tooltip-10",
              "path": "registry/default/components/tooltip/tooltip-10.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tooltip-10",
              "path": "registry/default/components/tooltip/tooltip-10.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tooltip-10",
              "path": "registry/default/components/tooltip/tooltip-10.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tooltip-10",
              "path": "registry/default/components/tooltip/tooltip-10.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tooltip",
        "title": "Tooltip · My profile"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "tooltip"
      ]
    },
    {
      "name": "tooltip-11",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/hover-card.json"
      ],
      "files": [
        {
          "path": "registry/default/components/tooltip/tooltip-11.tsx",
          "type": "registry:component",
          "target": "components/ui/tooltip-11.tsx",
          "content": "import { HoverCard, HoverCardContent, HoverCardTrigger } from '@timui/react'\n\nexport default function HoverCardDemo() {\n  return (\n    <HoverCard>\n      <div className=\"flex items-center gap-3\">\n        <img\n          className=\"shrink-0 rounded-full\"\n          src=\"avatar-40-05.jpg\"\n          width={40}\n          height={40}\n          alt=\"Avatar\"\n        />\n        <div className=\"space-y-0.5\">\n          <HoverCardTrigger asChild>\n            <p>\n              <a className=\"text-sm font-medium hover:underline\" href=\"#\">\n                Keith Kennedy\n              </a>\n            </p>\n          </HoverCardTrigger>\n          <p className=\"text-muted-foreground text-xs\">@k.kennedy</p>\n        </div>\n      </div>\n      <HoverCardContent>\n        <div className=\"space-y-3\">\n          <div className=\"flex items-center gap-3\">\n            <img\n              className=\"shrink-0 rounded-full\"\n              src=\"avatar-40-05.jpg\"\n              width={40}\n              height={40}\n              alt=\"Avatar\"\n            />\n            <div className=\"space-y-0.5\">\n              <p className=\"text-sm font-medium\">Keith Kennedy</p>\n              <p className=\"text-muted-foreground text-xs\">@k.kennedy</p>\n            </div>\n          </div>\n          <p className=\"text-muted-foreground text-sm\">\n            Designer at <strong className=\"text-foreground font-medium\">@Timkit UI</strong>.\n            Crafting web experiences with Tailwind CSS.\n          </p>\n          <div className=\"flex items-center gap-2\">\n            <div className=\"flex -space-x-1.5\">\n              <img\n                className=\"ring-background rounded-full ring-1\"\n                src=\"/avatar-20-04.jpg\"\n                width={20}\n                height={20}\n                alt=\"Friend 01\"\n              />\n              <img\n                className=\"ring-background rounded-full ring-1\"\n                src=\"/avatar-20-05.jpg\"\n                width={20}\n                height={20}\n                alt=\"Friend 02\"\n              />\n              <img\n                className=\"ring-background rounded-full ring-1\"\n                src=\"/avatar-20-06.jpg\"\n                width={20}\n                height={20}\n                alt=\"Friend 03\"\n              />\n            </div>\n            <div className=\"text-muted-foreground text-xs\">3 mutual friends</div>\n          </div>\n        </div>\n      </HoverCardContent>\n    </HoverCard>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-11.vue",
          "target": "components/ui/tooltip-11.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { HoverCard } from '@timui/vue';\nimport { HoverCardContent } from '@timui/vue';\nimport { HoverCardTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <HoverCard><div class=\"flex items-center gap-3\"><img class=\"shrink-0 rounded-full\" src=\"avatar-40-05.jpg\" :width=\"40\" :height=\"40\" alt=\"Avatar\" /><div class=\"space-y-0.5\"><HoverCardTrigger as-child><p><a class=\"text-sm font-medium hover:underline\" href=\"#\">Keith Kennedy\n              </a></p></HoverCardTrigger><p class=\"text-muted-foreground text-xs\">@k.kennedy</p></div></div><HoverCardContent><div class=\"space-y-3\"><div class=\"flex items-center gap-3\"><img class=\"shrink-0 rounded-full\" src=\"avatar-40-05.jpg\" :width=\"40\" :height=\"40\" alt=\"Avatar\" /><div class=\"space-y-0.5\"><p class=\"text-sm font-medium\">Keith Kennedy</p><p class=\"text-muted-foreground text-xs\">@k.kennedy</p></div></div><p class=\"text-muted-foreground text-sm\">Designer at <strong class=\"text-foreground font-medium\">@Timkit UI</strong>.\n            Crafting web experiences with Tailwind CSS.\n          </p><div class=\"flex items-center gap-2\"><div class=\"flex -space-x-1.5\"><img class=\"ring-background rounded-full ring-1\" src=\"/avatar-20-04.jpg\" :width=\"20\" :height=\"20\" alt=\"Friend 01\" /><img class=\"ring-background rounded-full ring-1\" src=\"/avatar-20-05.jpg\" :width=\"20\" :height=\"20\" alt=\"Friend 02\" /><img class=\"ring-background rounded-full ring-1\" src=\"/avatar-20-06.jpg\" :width=\"20\" :height=\"20\" alt=\"Friend 03\" /></div><div class=\"text-muted-foreground text-xs\">3 mutual friends</div></div></div></HoverCardContent></HoverCard>\n</template>\n"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-11.html",
          "target": "components/ui/tooltip-11.html",
          "type": "registry:component",
          "content": "<template>\n  <HoverCard><div class=\"flex items-center gap-3\"><img class=\"shrink-0 rounded-full\" src=\"avatar-40-05.jpg\" width=\"${40}\" height=\"${40}\" alt=\"Avatar\" /><div class=\"space-y-0.5\"><HoverCardTrigger aschild><p><a class=\"text-sm font-medium hover:underline\" href=\"#\">Keith Kennedy\n              </a></p></HoverCardTrigger><p class=\"text-muted-foreground text-xs\">@k.kennedy</p></div></div><HoverCardContent><div class=\"space-y-3\"><div class=\"flex items-center gap-3\"><img class=\"shrink-0 rounded-full\" src=\"avatar-40-05.jpg\" width=\"${40}\" height=\"${40}\" alt=\"Avatar\" /><div class=\"space-y-0.5\"><p class=\"text-sm font-medium\">Keith Kennedy</p><p class=\"text-muted-foreground text-xs\">@k.kennedy</p></div></div><p class=\"text-muted-foreground text-sm\">Designer at <strong class=\"text-foreground font-medium\">@Timkit UI</strong>.\n            Crafting web experiences with Tailwind CSS.\n          </p><div class=\"flex items-center gap-2\"><div class=\"flex -space-x-1.5\"><img class=\"ring-background rounded-full ring-1\" src=\"/avatar-20-04.jpg\" width=\"${20}\" height=\"${20}\" alt=\"Friend 01\" /><img class=\"ring-background rounded-full ring-1\" src=\"/avatar-20-05.jpg\" width=\"${20}\" height=\"${20}\" alt=\"Friend 02\" /><img class=\"ring-background rounded-full ring-1\" src=\"/avatar-20-06.jpg\" width=\"${20}\" height=\"${20}\" alt=\"Friend 03\" /></div><div class=\"text-muted-foreground text-xs\">3 mutual friends</div></div></div></HoverCardContent></HoverCard>\n</template>"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-11.wxml",
          "target": "components/ui/tooltip-11/tooltip-11.wxml",
          "type": "registry:component",
          "content": "<view>\n  <hovercard><view class=\"flex items-center gap-3\"><image class=\"shrink-0 rounded-full\" src=\"avatar-40-05.jpg\" width=\"{{40}}\" height=\"{{40}}\" alt=\"Avatar\" /><view class=\"space-y-0.5\"><hovercardtrigger aschild><text><a class=\"text-sm font-medium hover:underline\" href=\"#\">Keith Kennedy\n              </a></text></hovercardtrigger><text class=\"text-muted-foreground text-xs\">@k.kennedy</text></view></view><hovercardcontent><view class=\"space-y-3\"><view class=\"flex items-center gap-3\"><image class=\"shrink-0 rounded-full\" src=\"avatar-40-05.jpg\" width=\"{{40}}\" height=\"{{40}}\" alt=\"Avatar\" /><view class=\"space-y-0.5\"><text class=\"text-sm font-medium\">Keith Kennedy</text><text class=\"text-muted-foreground text-xs\">@k.kennedy</text></view></view><text class=\"text-muted-foreground text-sm\">Designer at <strong class=\"text-foreground font-medium\">@Timkit UI</strong>.\n            Crafting web experiences with Tailwind CSS.\n          </text><view class=\"flex items-center gap-2\"><view class=\"flex -space-x-1.5\"><image class=\"ring-background rounded-full ring-1\" src=\"/avatar-20-04.jpg\" width=\"{{20}}\" height=\"{{20}}\" alt=\"Friend 01\" /><image class=\"ring-background rounded-full ring-1\" src=\"/avatar-20-05.jpg\" width=\"{{20}}\" height=\"{{20}}\" alt=\"Friend 02\" /><image class=\"ring-background rounded-full ring-1\" src=\"/avatar-20-06.jpg\" width=\"{{20}}\" height=\"{{20}}\" alt=\"Friend 03\" /></view><view class=\"text-muted-foreground text-xs\">3 mutual friends</view></view></view></hovercardcontent></hovercard>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tooltip",
          "hover card",
          "user",
          "avatar",
          "profile",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tooltip-11",
          "group": "tooltip",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tooltip-11",
              "path": "registry/default/components/tooltip/tooltip-11.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tooltip-11",
              "path": "registry/default/components/tooltip/tooltip-11.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tooltip-11",
              "path": "registry/default/components/tooltip/tooltip-11.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tooltip-11",
              "path": "registry/default/components/tooltip/tooltip-11.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tooltip",
        "title": "Tooltip · Interactive State"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "tooltip"
      ]
    },
    {
      "name": "tooltip-12",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/hover-card.json"
      ],
      "files": [
        {
          "path": "registry/default/components/tooltip/tooltip-12.tsx",
          "type": "registry:component",
          "target": "components/ui/tooltip-12.tsx",
          "content": "import { HoverCard, HoverCardContent, HoverCardTrigger } from '@timui/react'\n\nexport default function HoverCardDemo() {\n  return (\n    <div className=\"max-w-md text-sm\">\n      <HoverCard>\n        <HoverCardTrigger asChild>\n          <a className=\"flex size-16 overflow-hidden rounded-md\" href=\"#\">\n            <img\n              className=\"size-full object-cover\"\n              src=\"/dialog-content.png\"\n              width={382}\n              height={216}\n              alt=\"Content image\"\n            />\n          </a>\n        </HoverCardTrigger>\n        <HoverCardContent className=\"w-[320px]\" showArrow>\n          <div className=\"space-y-3\">\n            <div className=\"space-y-1\">\n              <h2 className=\"font-semibold\">\n                Building a Design System with Next.js and Tailwind CSS\n              </h2>\n              <p className=\"text-muted-foreground text-sm\">\n                Learn how to build a comprehensive design system using Tailwind CSS, including\n                component architecture, and theme customization.\n              </p>\n            </div>\n            <div className=\"text-muted-foreground flex items-center gap-2 text-xs\">\n              <span>8 min read</span>\n              <span>·</span>\n              <span>Updated 2 days ago</span>\n            </div>\n          </div>\n        </HoverCardContent>\n      </HoverCard>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-12.vue",
          "target": "components/ui/tooltip-12.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { HoverCard } from '@timui/vue';\nimport { HoverCardContent } from '@timui/vue';\nimport { HoverCardTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"max-w-md text-sm\"><HoverCard><HoverCardTrigger as-child><a class=\"flex size-16 overflow-hidden rounded-md\" href=\"#\"><img class=\"size-full object-cover\" src=\"/dialog-content.png\" :width=\"382\" :height=\"216\" alt=\"Content image\" /></a></HoverCardTrigger><HoverCardContent class=\"w-[320px]\" showArrow><div class=\"space-y-3\"><div class=\"space-y-1\"><h2 class=\"font-semibold\">Building a Design System with Next.js and Tailwind CSS\n              </h2><p class=\"text-muted-foreground text-sm\">Learn how to build a comprehensive design system using Tailwind CSS, including\n                component architecture, and theme customization.\n              </p></div><div class=\"text-muted-foreground flex items-center gap-2 text-xs\"><span>8 min read</span><span>·</span><span>Updated 2 days ago</span></div></div></HoverCardContent></HoverCard></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-12.html",
          "target": "components/ui/tooltip-12.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"max-w-md text-sm\"><HoverCard><HoverCardTrigger aschild><a class=\"flex size-16 overflow-hidden rounded-md\" href=\"#\"><img class=\"size-full object-cover\" src=\"/dialog-content.png\" width=\"${382}\" height=\"${216}\" alt=\"Content image\" /></a></HoverCardTrigger><HoverCardContent class=\"w-[320px]\" showarrow><div class=\"space-y-3\"><div class=\"space-y-1\"><h2 class=\"font-semibold\">Building a Design System with Next.js and Tailwind CSS\n              </h2><p class=\"text-muted-foreground text-sm\">Learn how to build a comprehensive design system using Tailwind CSS, including\n                component architecture, and theme customization.\n              </p></div><div class=\"text-muted-foreground flex items-center gap-2 text-xs\"><span>8 min read</span><span>·</span><span>Updated 2 days ago</span></div></div></HoverCardContent></HoverCard></div>\n</template>"
        },
        {
          "path": "registry/default/components/tooltip/tooltip-12.wxml",
          "target": "components/ui/tooltip-12/tooltip-12.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"max-w-md text-sm\"><hovercard><hovercardtrigger aschild><a class=\"flex size-16 overflow-hidden rounded-md\" href=\"#\"><image class=\"size-full object-cover\" src=\"/dialog-content.png\" width=\"{{382}}\" height=\"{{216}}\" alt=\"Content image\" /></a></hovercardtrigger><hovercardcontent class=\"w-[320px]\" showarrow><view class=\"space-y-3\"><view class=\"space-y-1\"><h2 class=\"font-semibold\">Building a Design System with Next.js and Tailwind CSS\n              </h2><text class=\"text-muted-foreground text-sm\">Learn how to build a comprehensive design system using Tailwind CSS, including\n                component architecture, and theme customization.\n              </text></view><view class=\"text-muted-foreground flex items-center gap-2 text-xs\"><text>8 min read</text><text>·</text><text>Updated 2 days ago</text></view></view></hovercardcontent></hovercard></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tooltip",
          "hover card",
          "image",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tooltip-12",
          "group": "tooltip",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tooltip-12",
              "path": "registry/default/components/tooltip/tooltip-12.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tooltip-12",
              "path": "registry/default/components/tooltip/tooltip-12.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tooltip-12",
              "path": "registry/default/components/tooltip/tooltip-12.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tooltip-12",
              "path": "registry/default/components/tooltip/tooltip-12.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tooltip",
        "title": "Tooltip · Building a Design System with Next.js and Tailwind CSS"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "tooltip"
      ]
    },
    {
      "name": "dropdown-01",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dropdown-menu.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/dropdown/dropdown-01.tsx",
          "type": "registry:component",
          "target": "components/ui/dropdown-01.tsx",
          "content": "import {\n  Button,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuTrigger,\n} from '@timui/react'\nimport { EllipsisIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button\n          size=\"icon\"\n          variant=\"ghost\"\n          className=\"rounded-full shadow-none\"\n          aria-label=\"Open edit menu\"\n        >\n          <EllipsisIcon size={16} aria-hidden=\"true\" />\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent>\n        <DropdownMenuItem>Option 1</DropdownMenuItem>\n        <DropdownMenuItem>Option 2</DropdownMenuItem>\n        <DropdownMenuItem>Option 3</DropdownMenuItem>\n        <DropdownMenuItem>Option 4</DropdownMenuItem>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-01.vue",
          "target": "components/ui/dropdown-01.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { EllipsisIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <DropdownMenu><DropdownMenuTrigger as-child><Button size=\"icon\" variant=\"ghost\" class=\"rounded-full shadow-none\" aria-label=\"Open edit menu\"><EllipsisIcon :size=\"16\" aria-hidden=\"true\" /></Button></DropdownMenuTrigger><DropdownMenuContent><DropdownMenuItem>Option 1</DropdownMenuItem><DropdownMenuItem>Option 2</DropdownMenuItem><DropdownMenuItem>Option 3</DropdownMenuItem><DropdownMenuItem>Option 4</DropdownMenuItem></DropdownMenuContent></DropdownMenu>\n</template>\n"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-01.html",
          "target": "components/ui/dropdown-01.html",
          "type": "registry:component",
          "content": "<template>\n  <DropdownMenu><DropdownMenuTrigger aschild><Button size=\"icon\" variant=\"ghost\" class=\"rounded-full shadow-none\" aria-label=\"Open edit menu\"><EllipsisIcon size=\"${16}\" aria-hidden=\"true\" /></Button></DropdownMenuTrigger><DropdownMenuContent><DropdownMenuItem>Option 1</DropdownMenuItem><DropdownMenuItem>Option 2</DropdownMenuItem><DropdownMenuItem>Option 3</DropdownMenuItem><DropdownMenuItem>Option 4</DropdownMenuItem></DropdownMenuContent></DropdownMenu>\n</template>"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-01.wxml",
          "target": "components/ui/dropdown-01/dropdown-01.wxml",
          "type": "registry:component",
          "content": "<view>\n  <dropdownmenu><dropdownmenutrigger aschild><button size=\"icon\" variant=\"ghost\" class=\"rounded-full shadow-none\" aria-label=\"Open edit menu\"><ellipsisicon size=\"{{16}}\" aria-hidden=\"true\" /></button></dropdownmenutrigger><dropdownmenucontent><dropdownmenuitem>Option 1</dropdownmenuitem><dropdownmenuitem>Option 2</dropdownmenuitem><dropdownmenuitem>Option 3</dropdownmenuitem><dropdownmenuitem>Option 4</dropdownmenuitem></dropdownmenucontent></dropdownmenu>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dropdown",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dropdown-01",
          "group": "dropdown",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dropdown-01",
              "path": "registry/default/components/dropdown/dropdown-01.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dropdown-01",
              "path": "registry/default/components/dropdown/dropdown-01.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dropdown-01",
              "path": "registry/default/components/dropdown/dropdown-01.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dropdown-01",
              "path": "registry/default/components/dropdown/dropdown-01.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dropdown",
        "title": "Dropdown · Open edit menu"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "dropdown"
      ]
    },
    {
      "name": "dropdown-02",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dropdown-menu.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/dropdown/dropdown-02.tsx",
          "type": "registry:component",
          "target": "components/ui/dropdown-02.tsx",
          "content": "import {\n  Button,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuTrigger,\n} from '@timui/react'\nimport { ChevronDownIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button variant=\"outline\">\n          Same width of trigger\n          <ChevronDownIcon className=\"-me-1 opacity-60\" size={16} aria-hidden=\"true\" />\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent className=\"min-w-(--radix-dropdown-menu-trigger-width)\">\n        <DropdownMenuItem>Option 1</DropdownMenuItem>\n        <DropdownMenuItem>Option 2</DropdownMenuItem>\n        <DropdownMenuItem>Option 3</DropdownMenuItem>\n        <DropdownMenuItem>Option 4</DropdownMenuItem>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-02.vue",
          "target": "components/ui/dropdown-02.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ChevronDownIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <DropdownMenu><DropdownMenuTrigger as-child><Button variant=\"outline\">Same width of trigger\n          <ChevronDownIcon class=\"-me-1 opacity-60\" :size=\"16\" aria-hidden=\"true\" /></Button></DropdownMenuTrigger><DropdownMenuContent class=\"min-w-(--radix-dropdown-menu-trigger-width)\"><DropdownMenuItem>Option 1</DropdownMenuItem><DropdownMenuItem>Option 2</DropdownMenuItem><DropdownMenuItem>Option 3</DropdownMenuItem><DropdownMenuItem>Option 4</DropdownMenuItem></DropdownMenuContent></DropdownMenu>\n</template>\n"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-02.html",
          "target": "components/ui/dropdown-02.html",
          "type": "registry:component",
          "content": "<template>\n  <DropdownMenu><DropdownMenuTrigger aschild><Button variant=\"outline\">Same width of trigger\n          <ChevronDownIcon class=\"-me-1 opacity-60\" size=\"${16}\" aria-hidden=\"true\" /></Button></DropdownMenuTrigger><DropdownMenuContent class=\"min-w-(--radix-dropdown-menu-trigger-width)\"><DropdownMenuItem>Option 1</DropdownMenuItem><DropdownMenuItem>Option 2</DropdownMenuItem><DropdownMenuItem>Option 3</DropdownMenuItem><DropdownMenuItem>Option 4</DropdownMenuItem></DropdownMenuContent></DropdownMenu>\n</template>"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-02.wxml",
          "target": "components/ui/dropdown-02/dropdown-02.wxml",
          "type": "registry:component",
          "content": "<view>\n  <dropdownmenu><dropdownmenutrigger aschild><button variant=\"outline\">Same width of trigger\n          <chevrondownicon class=\"-me-1 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" /></button></dropdownmenutrigger><dropdownmenucontent class=\"min-w-(--radix-dropdown-menu-trigger-width)\"><dropdownmenuitem>Option 1</dropdownmenuitem><dropdownmenuitem>Option 2</dropdownmenuitem><dropdownmenuitem>Option 3</dropdownmenuitem><dropdownmenuitem>Option 4</dropdownmenuitem></dropdownmenucontent></dropdownmenu>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dropdown",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dropdown-02",
          "group": "dropdown",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dropdown-02",
              "path": "registry/default/components/dropdown/dropdown-02.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dropdown-02",
              "path": "registry/default/components/dropdown/dropdown-02.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dropdown-02",
              "path": "registry/default/components/dropdown/dropdown-02.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dropdown-02",
              "path": "registry/default/components/dropdown/dropdown-02.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dropdown",
        "title": "Dropdown · With icon"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "dropdown"
      ]
    },
    {
      "name": "dropdown-03",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dropdown-menu.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/dropdown/dropdown-03.tsx",
          "type": "registry:component",
          "target": "components/ui/dropdown-03.tsx",
          "content": "import {\n  Button,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuTrigger,\n} from '@timui/react'\nimport { BoltIcon, ChevronDownIcon, CopyPlusIcon, FilesIcon, Layers2Icon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button variant=\"outline\">\n          Menu with icons\n          <ChevronDownIcon className=\"-me-1 opacity-60\" size={16} aria-hidden=\"true\" />\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent>\n        <DropdownMenuItem>\n          <CopyPlusIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n          Copy\n        </DropdownMenuItem>\n        <DropdownMenuItem>\n          <BoltIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n          Edit\n        </DropdownMenuItem>\n        <DropdownMenuItem>\n          <Layers2Icon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n          Group\n        </DropdownMenuItem>\n        <DropdownMenuItem>\n          <FilesIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n          Clone\n        </DropdownMenuItem>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-03.vue",
          "target": "components/ui/dropdown-03.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { BoltIcon, ChevronDownIcon, CopyPlusIcon, FilesIcon, Layers2Icon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <DropdownMenu><DropdownMenuTrigger as-child><Button variant=\"outline\">Menu with icons\n          <ChevronDownIcon class=\"-me-1 opacity-60\" :size=\"16\" aria-hidden=\"true\" /></Button></DropdownMenuTrigger><DropdownMenuContent><DropdownMenuItem><CopyPlusIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" />Copy\n        </DropdownMenuItem><DropdownMenuItem><BoltIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" />Edit\n        </DropdownMenuItem><DropdownMenuItem><Layers2Icon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" />Group\n        </DropdownMenuItem><DropdownMenuItem><FilesIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" />Clone\n        </DropdownMenuItem></DropdownMenuContent></DropdownMenu>\n</template>\n"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-03.html",
          "target": "components/ui/dropdown-03.html",
          "type": "registry:component",
          "content": "<template>\n  <DropdownMenu><DropdownMenuTrigger aschild><Button variant=\"outline\">Menu with icons\n          <ChevronDownIcon class=\"-me-1 opacity-60\" size=\"${16}\" aria-hidden=\"true\" /></Button></DropdownMenuTrigger><DropdownMenuContent><DropdownMenuItem><CopyPlusIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" />Copy\n        </DropdownMenuItem><DropdownMenuItem><BoltIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" />Edit\n        </DropdownMenuItem><DropdownMenuItem><Layers2Icon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" />Group\n        </DropdownMenuItem><DropdownMenuItem><FilesIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" />Clone\n        </DropdownMenuItem></DropdownMenuContent></DropdownMenu>\n</template>"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-03.wxml",
          "target": "components/ui/dropdown-03/dropdown-03.wxml",
          "type": "registry:component",
          "content": "<view>\n  <dropdownmenu><dropdownmenutrigger aschild><button variant=\"outline\">Menu with icons\n          <chevrondownicon class=\"-me-1 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" /></button></dropdownmenutrigger><dropdownmenucontent><dropdownmenuitem><copyplusicon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" />Copy\n        </dropdownmenuitem><dropdownmenuitem><bolticon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" />Edit\n        </dropdownmenuitem><dropdownmenuitem><layers2icon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" />Group\n        </dropdownmenuitem><dropdownmenuitem><filesicon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" />Clone\n        </dropdownmenuitem></dropdownmenucontent></dropdownmenu>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dropdown",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dropdown-03",
          "group": "dropdown",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dropdown-03",
              "path": "registry/default/components/dropdown/dropdown-03.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dropdown-03",
              "path": "registry/default/components/dropdown/dropdown-03.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dropdown-03",
              "path": "registry/default/components/dropdown/dropdown-03.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dropdown-03",
              "path": "registry/default/components/dropdown/dropdown-03.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dropdown",
        "title": "Dropdown · With icon"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "dropdown"
      ]
    },
    {
      "name": "dropdown-04",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dropdown-menu.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/dropdown/dropdown-04.tsx",
          "type": "registry:component",
          "target": "components/ui/dropdown-04.tsx",
          "content": "import {\n  Button,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from '@timui/react'\nimport {\n  BoltIcon,\n  ChevronDownIcon,\n  CopyPlusIcon,\n  FilesIcon,\n  Layers2Icon,\n  TrashIcon,\n} from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button variant=\"outline\">\n          Grouped items\n          <ChevronDownIcon className=\"-me-1 opacity-60\" size={16} aria-hidden=\"true\" />\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent>\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <CopyPlusIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            Copy\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <BoltIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            Edit\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <Layers2Icon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            Group\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <FilesIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            Clone\n          </DropdownMenuItem>\n          <DropdownMenuItem variant=\"destructive\">\n            <TrashIcon size={16} aria-hidden=\"true\" />\n            Delete\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-04.vue",
          "target": "components/ui/dropdown-04.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { BoltIcon, ChevronDownIcon, CopyPlusIcon, FilesIcon, Layers2Icon, TrashIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <DropdownMenu><DropdownMenuTrigger as-child><Button variant=\"outline\">Grouped items\n          <ChevronDownIcon class=\"-me-1 opacity-60\" :size=\"16\" aria-hidden=\"true\" /></Button></DropdownMenuTrigger><DropdownMenuContent><DropdownMenuGroup><DropdownMenuItem><CopyPlusIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" />Copy\n          </DropdownMenuItem><DropdownMenuItem><BoltIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" />Edit\n          </DropdownMenuItem></DropdownMenuGroup><DropdownMenuSeparator /><DropdownMenuGroup><DropdownMenuItem><Layers2Icon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" />Group\n          </DropdownMenuItem><DropdownMenuItem><FilesIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" />Clone\n          </DropdownMenuItem><DropdownMenuItem variant=\"destructive\"><TrashIcon :size=\"16\" aria-hidden=\"true\" />Delete\n          </DropdownMenuItem></DropdownMenuGroup></DropdownMenuContent></DropdownMenu>\n</template>\n"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-04.html",
          "target": "components/ui/dropdown-04.html",
          "type": "registry:component",
          "content": "<template>\n  <DropdownMenu><DropdownMenuTrigger aschild><Button variant=\"outline\">Grouped items\n          <ChevronDownIcon class=\"-me-1 opacity-60\" size=\"${16}\" aria-hidden=\"true\" /></Button></DropdownMenuTrigger><DropdownMenuContent><DropdownMenuGroup><DropdownMenuItem><CopyPlusIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" />Copy\n          </DropdownMenuItem><DropdownMenuItem><BoltIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" />Edit\n          </DropdownMenuItem></DropdownMenuGroup><DropdownMenuSeparator /><DropdownMenuGroup><DropdownMenuItem><Layers2Icon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" />Group\n          </DropdownMenuItem><DropdownMenuItem><FilesIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" />Clone\n          </DropdownMenuItem><DropdownMenuItem variant=\"destructive\"><TrashIcon size=\"${16}\" aria-hidden=\"true\" />Delete\n          </DropdownMenuItem></DropdownMenuGroup></DropdownMenuContent></DropdownMenu>\n</template>"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-04.wxml",
          "target": "components/ui/dropdown-04/dropdown-04.wxml",
          "type": "registry:component",
          "content": "<view>\n  <dropdownmenu><dropdownmenutrigger aschild><button variant=\"outline\">Grouped items\n          <chevrondownicon class=\"-me-1 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" /></button></dropdownmenutrigger><dropdownmenucontent><dropdownmenugroup><dropdownmenuitem><copyplusicon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" />Copy\n          </dropdownmenuitem><dropdownmenuitem><bolticon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" />Edit\n          </dropdownmenuitem></dropdownmenugroup><dropdownmenuseparator /><dropdownmenugroup><dropdownmenuitem><layers2icon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" />Group\n          </dropdownmenuitem><dropdownmenuitem><filesicon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" />Clone\n          </dropdownmenuitem><dropdownmenuitem variant=\"destructive\"><trashicon size=\"{{16}}\" aria-hidden=\"true\" />Delete\n          </dropdownmenuitem></dropdownmenugroup></dropdownmenucontent></dropdownmenu>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dropdown",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dropdown-04",
          "group": "dropdown",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dropdown-04",
              "path": "registry/default/components/dropdown/dropdown-04.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dropdown-04",
              "path": "registry/default/components/dropdown/dropdown-04.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dropdown-04",
              "path": "registry/default/components/dropdown/dropdown-04.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dropdown-04",
              "path": "registry/default/components/dropdown/dropdown-04.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dropdown",
        "title": "Dropdown · With icon"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "dropdown"
      ]
    },
    {
      "name": "dropdown-05",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dropdown-menu.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/dropdown/dropdown-05.tsx",
          "type": "registry:component",
          "target": "components/ui/dropdown-05.tsx",
          "content": "import {\n  Button,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from '@timui/react'\nimport {\n  BoltIcon,\n  ChevronDownIcon,\n  CopyPlusIcon,\n  FilesIcon,\n  Layers2Icon,\n  TrashIcon,\n} from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button variant=\"outline\">\n          Labeled grouped items\n          <ChevronDownIcon className=\"-me-1 opacity-60\" size={16} aria-hidden=\"true\" />\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent>\n        <DropdownMenuLabel>Label</DropdownMenuLabel>\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <CopyPlusIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            Copy\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <BoltIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            Edit\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuLabel>Label</DropdownMenuLabel>\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <Layers2Icon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            Group\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <FilesIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            Clone\n          </DropdownMenuItem>\n          <DropdownMenuItem variant=\"destructive\">\n            <TrashIcon size={16} aria-hidden=\"true\" />\n            Delete\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-05.vue",
          "target": "components/ui/dropdown-05.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { BoltIcon, ChevronDownIcon, CopyPlusIcon, FilesIcon, Layers2Icon, TrashIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <DropdownMenu><DropdownMenuTrigger as-child><Button variant=\"outline\">Labeled grouped items\n          <ChevronDownIcon class=\"-me-1 opacity-60\" :size=\"16\" aria-hidden=\"true\" /></Button></DropdownMenuTrigger><DropdownMenuContent><DropdownMenuLabel>Label</DropdownMenuLabel><DropdownMenuGroup><DropdownMenuItem><CopyPlusIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" />Copy\n          </DropdownMenuItem><DropdownMenuItem><BoltIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" />Edit\n          </DropdownMenuItem></DropdownMenuGroup><DropdownMenuSeparator /><DropdownMenuLabel>Label</DropdownMenuLabel><DropdownMenuGroup><DropdownMenuItem><Layers2Icon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" />Group\n          </DropdownMenuItem><DropdownMenuItem><FilesIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" />Clone\n          </DropdownMenuItem><DropdownMenuItem variant=\"destructive\"><TrashIcon :size=\"16\" aria-hidden=\"true\" />Delete\n          </DropdownMenuItem></DropdownMenuGroup></DropdownMenuContent></DropdownMenu>\n</template>\n"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-05.html",
          "target": "components/ui/dropdown-05.html",
          "type": "registry:component",
          "content": "<template>\n  <DropdownMenu><DropdownMenuTrigger aschild><Button variant=\"outline\">Labeled grouped items\n          <ChevronDownIcon class=\"-me-1 opacity-60\" size=\"${16}\" aria-hidden=\"true\" /></Button></DropdownMenuTrigger><DropdownMenuContent><DropdownMenuLabel>Label</DropdownMenuLabel><DropdownMenuGroup><DropdownMenuItem><CopyPlusIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" />Copy\n          </DropdownMenuItem><DropdownMenuItem><BoltIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" />Edit\n          </DropdownMenuItem></DropdownMenuGroup><DropdownMenuSeparator /><DropdownMenuLabel>Label</DropdownMenuLabel><DropdownMenuGroup><DropdownMenuItem><Layers2Icon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" />Group\n          </DropdownMenuItem><DropdownMenuItem><FilesIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" />Clone\n          </DropdownMenuItem><DropdownMenuItem variant=\"destructive\"><TrashIcon size=\"${16}\" aria-hidden=\"true\" />Delete\n          </DropdownMenuItem></DropdownMenuGroup></DropdownMenuContent></DropdownMenu>\n</template>"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-05.wxml",
          "target": "components/ui/dropdown-05/dropdown-05.wxml",
          "type": "registry:component",
          "content": "<view>\n  <dropdownmenu><dropdownmenutrigger aschild><button variant=\"outline\">Labeled grouped items\n          <chevrondownicon class=\"-me-1 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" /></button></dropdownmenutrigger><dropdownmenucontent><dropdownmenulabel>Label</dropdownmenulabel><dropdownmenugroup><dropdownmenuitem><copyplusicon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" />Copy\n          </dropdownmenuitem><dropdownmenuitem><bolticon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" />Edit\n          </dropdownmenuitem></dropdownmenugroup><dropdownmenuseparator /><dropdownmenulabel>Label</dropdownmenulabel><dropdownmenugroup><dropdownmenuitem><layers2icon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" />Group\n          </dropdownmenuitem><dropdownmenuitem><filesicon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" />Clone\n          </dropdownmenuitem><dropdownmenuitem variant=\"destructive\"><trashicon size=\"{{16}}\" aria-hidden=\"true\" />Delete\n          </dropdownmenuitem></dropdownmenugroup></dropdownmenucontent></dropdownmenu>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dropdown",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dropdown-05",
          "group": "dropdown",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dropdown-05",
              "path": "registry/default/components/dropdown/dropdown-05.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dropdown-05",
              "path": "registry/default/components/dropdown/dropdown-05.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dropdown-05",
              "path": "registry/default/components/dropdown/dropdown-05.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dropdown-05",
              "path": "registry/default/components/dropdown/dropdown-05.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dropdown",
        "title": "Dropdown · With icon"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "dropdown"
      ]
    },
    {
      "name": "dropdown-06",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dropdown-menu.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/dropdown/dropdown-06.tsx",
          "type": "registry:component",
          "target": "components/ui/dropdown-06.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport {\n  Button,\n  DropdownMenu,\n  DropdownMenuCheckboxItem,\n  DropdownMenuContent,\n  DropdownMenuTrigger,\n} from '@timui/react'\nimport { ChevronDownIcon } from 'lucide-react'\n\ntype Checked = boolean\n\nexport default function Component() {\n  const [nextjs, setNextjs] = useState<Checked>(false)\n  const [sveltekit, setSveltekit] = useState<Checked>(true)\n  const [astro, setAstro] = useState<Checked>(false)\n  const [remix, setRemix] = useState<Checked>(false)\n\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button variant=\"outline\">\n          Checkbox items\n          <ChevronDownIcon className=\"-me-1 opacity-60\" size={16} aria-hidden=\"true\" />\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent>\n        <DropdownMenuCheckboxItem checked={nextjs} onCheckedChange={setNextjs}>\n          Next.js\n        </DropdownMenuCheckboxItem>\n        <DropdownMenuCheckboxItem checked={sveltekit} onCheckedChange={setSveltekit}>\n          SvelteKit\n        </DropdownMenuCheckboxItem>\n        <DropdownMenuCheckboxItem checked={remix} onCheckedChange={setRemix} disabled>\n          Remix\n        </DropdownMenuCheckboxItem>\n        <DropdownMenuCheckboxItem checked={astro} onCheckedChange={setAstro}>\n          Astro\n        </DropdownMenuCheckboxItem>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-06.vue",
          "target": "components/ui/dropdown-06.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { ChevronDownIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuTrigger } from '@timui/vue';\n\n\n\nconst nextjs = ref<Checked>(false);\nconst sveltekit = ref<Checked>(true);\nconst astro = ref<Checked>(false);\nconst remix = ref<Checked>(false);\n\n\nfunction setNextjs(next: typeof nextjs.value | ((prev: typeof nextjs.value) => typeof nextjs.value)) {\n  nextjs.value = typeof next === 'function'\n    ? (next as (prev: typeof nextjs.value) => typeof nextjs.value)(nextjs.value)\n    : next;\n}\n\nfunction setSveltekit(next: typeof sveltekit.value | ((prev: typeof sveltekit.value) => typeof sveltekit.value)) {\n  sveltekit.value = typeof next === 'function'\n    ? (next as (prev: typeof sveltekit.value) => typeof sveltekit.value)(sveltekit.value)\n    : next;\n}\n\nfunction setRemix(next: typeof remix.value | ((prev: typeof remix.value) => typeof remix.value)) {\n  remix.value = typeof next === 'function'\n    ? (next as (prev: typeof remix.value) => typeof remix.value)(remix.value)\n    : next;\n}\n\nfunction setAstro(next: typeof astro.value | ((prev: typeof astro.value) => typeof astro.value)) {\n  astro.value = typeof next === 'function'\n    ? (next as (prev: typeof astro.value) => typeof astro.value)(astro.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <DropdownMenu><DropdownMenuTrigger as-child><Button variant=\"outline\">Checkbox items\n          <ChevronDownIcon class=\"-me-1 opacity-60\" :size=\"16\" aria-hidden=\"true\" /></Button></DropdownMenuTrigger><DropdownMenuContent><DropdownMenuCheckboxItem :checked=\"nextjs\" :onCheckedChange=\"setNextjs\">Next.js\n        </DropdownMenuCheckboxItem><DropdownMenuCheckboxItem :checked=\"sveltekit\" :onCheckedChange=\"setSveltekit\">SvelteKit\n        </DropdownMenuCheckboxItem><DropdownMenuCheckboxItem :checked=\"remix\" :onCheckedChange=\"setRemix\" disabled>Remix\n        </DropdownMenuCheckboxItem><DropdownMenuCheckboxItem :checked=\"astro\" :onCheckedChange=\"setAstro\">Astro\n        </DropdownMenuCheckboxItem></DropdownMenuContent></DropdownMenu>\n</template>\n"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-06.html",
          "target": "components/ui/dropdown-06.html",
          "type": "registry:component",
          "content": "<template>\n  <DropdownMenu><DropdownMenuTrigger aschild><Button variant=\"outline\">Checkbox items\n          <ChevronDownIcon class=\"-me-1 opacity-60\" size=\"${16}\" aria-hidden=\"true\" /></Button></DropdownMenuTrigger><DropdownMenuContent><DropdownMenuCheckboxItem checked=\"${nextjs}\" oncheckedchange=\"${setNextjs}\">Next.js\n        </DropdownMenuCheckboxItem><DropdownMenuCheckboxItem checked=\"${sveltekit}\" oncheckedchange=\"${setSveltekit}\">SvelteKit\n        </DropdownMenuCheckboxItem><DropdownMenuCheckboxItem checked=\"${remix}\" oncheckedchange=\"${setRemix}\" disabled>Remix\n        </DropdownMenuCheckboxItem><DropdownMenuCheckboxItem checked=\"${astro}\" oncheckedchange=\"${setAstro}\">Astro\n        </DropdownMenuCheckboxItem></DropdownMenuContent></DropdownMenu>\n</template>"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-06.wxml",
          "target": "components/ui/dropdown-06/dropdown-06.wxml",
          "type": "registry:component",
          "content": "<view>\n  <dropdownmenu><dropdownmenutrigger aschild><button variant=\"outline\">Checkbox items\n          <chevrondownicon class=\"-me-1 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" /></button></dropdownmenutrigger><dropdownmenucontent><dropdownmenucheckboxitem checked=\"{{nextjs}}\" oncheckedchange=\"{{setNextjs}}\">Next.js\n        </dropdownmenucheckboxitem><dropdownmenucheckboxitem checked=\"{{sveltekit}}\" oncheckedchange=\"{{setSveltekit}}\">SvelteKit\n        </dropdownmenucheckboxitem><dropdownmenucheckboxitem checked=\"{{remix}}\" oncheckedchange=\"{{setRemix}}\" disabled>Remix\n        </dropdownmenucheckboxitem><dropdownmenucheckboxitem checked=\"{{astro}}\" oncheckedchange=\"{{setAstro}}\">Astro\n        </dropdownmenucheckboxitem></dropdownmenucontent></dropdownmenu>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dropdown",
          "checkbox",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dropdown-06",
          "group": "dropdown",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dropdown-06",
              "path": "registry/default/components/dropdown/dropdown-06.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dropdown-06",
              "path": "registry/default/components/dropdown/dropdown-06.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dropdown-06",
              "path": "registry/default/components/dropdown/dropdown-06.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dropdown-06",
              "path": "registry/default/components/dropdown/dropdown-06.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dropdown",
        "title": "Dropdown · Disabled State"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "dropdown"
      ]
    },
    {
      "name": "dropdown-07",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dropdown-menu.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/dropdown/dropdown-07.tsx",
          "type": "registry:component",
          "target": "components/ui/dropdown-07.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport {\n  Button,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuRadioGroup,\n  DropdownMenuRadioItem,\n  DropdownMenuTrigger,\n} from '@timui/react'\nimport { ChevronDownIcon } from 'lucide-react'\n\nexport default function Component() {\n  const [framework, setFramework] = useState('nextjs')\n\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button variant=\"outline\">\n          Radio items\n          <ChevronDownIcon className=\"-me-1 opacity-60\" size={16} aria-hidden=\"true\" />\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent>\n        <DropdownMenuRadioGroup value={framework} onValueChange={setFramework}>\n          <DropdownMenuRadioItem value=\"nextjs\">Next.js</DropdownMenuRadioItem>\n          <DropdownMenuRadioItem value=\"sveltekit\" disabled>\n            SvelteKit\n          </DropdownMenuRadioItem>\n          <DropdownMenuRadioItem value=\"remix\">Remix</DropdownMenuRadioItem>\n          <DropdownMenuRadioItem value=\"astro\">Astro</DropdownMenuRadioItem>\n        </DropdownMenuRadioGroup>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-07.vue",
          "target": "components/ui/dropdown-07.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { ChevronDownIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuTrigger } from '@timui/vue';\n\n\n\nconst framework = ref('nextjs');\n\n\nfunction setFramework(next: typeof framework.value | ((prev: typeof framework.value) => typeof framework.value)) {\n  framework.value = typeof next === 'function'\n    ? (next as (prev: typeof framework.value) => typeof framework.value)(framework.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <DropdownMenu><DropdownMenuTrigger as-child><Button variant=\"outline\">Radio items\n          <ChevronDownIcon class=\"-me-1 opacity-60\" :size=\"16\" aria-hidden=\"true\" /></Button></DropdownMenuTrigger><DropdownMenuContent><DropdownMenuRadioGroup :value=\"framework\" @update:modelValue=\"setFramework\"><DropdownMenuRadioItem value=\"nextjs\">Next.js</DropdownMenuRadioItem><DropdownMenuRadioItem value=\"sveltekit\" disabled>SvelteKit\n          </DropdownMenuRadioItem><DropdownMenuRadioItem value=\"remix\">Remix</DropdownMenuRadioItem><DropdownMenuRadioItem value=\"astro\">Astro</DropdownMenuRadioItem></DropdownMenuRadioGroup></DropdownMenuContent></DropdownMenu>\n</template>\n"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-07.html",
          "target": "components/ui/dropdown-07.html",
          "type": "registry:component",
          "content": "<template>\n  <DropdownMenu><DropdownMenuTrigger aschild><Button variant=\"outline\">Radio items\n          <ChevronDownIcon class=\"-me-1 opacity-60\" size=\"${16}\" aria-hidden=\"true\" /></Button></DropdownMenuTrigger><DropdownMenuContent><DropdownMenuRadioGroup value=\"${framework}\" on-value-change=\"${setFramework}\"><DropdownMenuRadioItem value=\"nextjs\">Next.js</DropdownMenuRadioItem><DropdownMenuRadioItem value=\"sveltekit\" disabled>SvelteKit\n          </DropdownMenuRadioItem><DropdownMenuRadioItem value=\"remix\">Remix</DropdownMenuRadioItem><DropdownMenuRadioItem value=\"astro\">Astro</DropdownMenuRadioItem></DropdownMenuRadioGroup></DropdownMenuContent></DropdownMenu>\n</template>"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-07.wxml",
          "target": "components/ui/dropdown-07/dropdown-07.wxml",
          "type": "registry:component",
          "content": "<view>\n  <dropdownmenu><dropdownmenutrigger aschild><button variant=\"outline\">Radio items\n          <chevrondownicon class=\"-me-1 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" /></button></dropdownmenutrigger><dropdownmenucontent><dropdownmenuradiogroup value=\"{{framework}}\" bindchange=\"setFramework\"><dropdownmenuradioitem value=\"nextjs\">Next.js</dropdownmenuradioitem><dropdownmenuradioitem value=\"sveltekit\" disabled>SvelteKit\n          </dropdownmenuradioitem><dropdownmenuradioitem value=\"remix\">Remix</dropdownmenuradioitem><dropdownmenuradioitem value=\"astro\">Astro</dropdownmenuradioitem></dropdownmenuradiogroup></dropdownmenucontent></dropdownmenu>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dropdown",
          "radio",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dropdown-07",
          "group": "dropdown",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dropdown-07",
              "path": "registry/default/components/dropdown/dropdown-07.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dropdown-07",
              "path": "registry/default/components/dropdown/dropdown-07.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dropdown-07",
              "path": "registry/default/components/dropdown/dropdown-07.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dropdown-07",
              "path": "registry/default/components/dropdown/dropdown-07.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dropdown",
        "title": "Dropdown · Disabled State"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "dropdown"
      ]
    },
    {
      "name": "dropdown-08",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dropdown-menu.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/dropdown/dropdown-08.tsx",
          "type": "registry:component",
          "target": "components/ui/dropdown-08.tsx",
          "content": "import {\n  Button,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuPortal,\n  DropdownMenuSeparator,\n  DropdownMenuShortcut,\n  DropdownMenuSub,\n  DropdownMenuSubContent,\n  DropdownMenuSubTrigger,\n  DropdownMenuTrigger,\n} from '@timui/react'\nimport { ChevronDownIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button variant=\"outline\">\n          Rich menu\n          <ChevronDownIcon className=\"-me-1 opacity-60\" size={16} aria-hidden=\"true\" />\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent>\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <span>Edit</span>\n            <DropdownMenuShortcut>⌘E</DropdownMenuShortcut>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <span>Duplicate</span>\n            <DropdownMenuShortcut>⌘D</DropdownMenuShortcut>\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <span>Archive</span>\n            <DropdownMenuShortcut>⌘A</DropdownMenuShortcut>\n          </DropdownMenuItem>\n          <DropdownMenuSub>\n            <DropdownMenuSubTrigger>More</DropdownMenuSubTrigger>\n            <DropdownMenuPortal>\n              <DropdownMenuSubContent>\n                <DropdownMenuItem>Move to project</DropdownMenuItem>\n                <DropdownMenuItem>Move to folder</DropdownMenuItem>\n                <DropdownMenuSeparator />\n                <DropdownMenuItem>Advanced options</DropdownMenuItem>\n              </DropdownMenuSubContent>\n            </DropdownMenuPortal>\n          </DropdownMenuSub>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuItem>Share</DropdownMenuItem>\n          <DropdownMenuItem>Add to favorites</DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuItem variant=\"destructive\">\n          <span>Delete</span>\n          <DropdownMenuShortcut>⌘⌫</DropdownMenuShortcut>\n        </DropdownMenuItem>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-08.vue",
          "target": "components/ui/dropdown-08.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ChevronDownIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuPortal, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <DropdownMenu><DropdownMenuTrigger as-child><Button variant=\"outline\">Rich menu\n          <ChevronDownIcon class=\"-me-1 opacity-60\" :size=\"16\" aria-hidden=\"true\" /></Button></DropdownMenuTrigger><DropdownMenuContent><DropdownMenuGroup><DropdownMenuItem><span>Edit</span><DropdownMenuShortcut>⌘E</DropdownMenuShortcut></DropdownMenuItem><DropdownMenuItem><span>Duplicate</span><DropdownMenuShortcut>⌘D</DropdownMenuShortcut></DropdownMenuItem></DropdownMenuGroup><DropdownMenuSeparator /><DropdownMenuGroup><DropdownMenuItem><span>Archive</span><DropdownMenuShortcut>⌘A</DropdownMenuShortcut></DropdownMenuItem><DropdownMenuSub><DropdownMenuSubTrigger>More</DropdownMenuSubTrigger><DropdownMenuPortal><DropdownMenuSubContent><DropdownMenuItem>Move to project</DropdownMenuItem><DropdownMenuItem>Move to folder</DropdownMenuItem><DropdownMenuSeparator /><DropdownMenuItem>Advanced options</DropdownMenuItem></DropdownMenuSubContent></DropdownMenuPortal></DropdownMenuSub></DropdownMenuGroup><DropdownMenuSeparator /><DropdownMenuGroup><DropdownMenuItem>Share</DropdownMenuItem><DropdownMenuItem>Add to favorites</DropdownMenuItem></DropdownMenuGroup><DropdownMenuSeparator /><DropdownMenuItem variant=\"destructive\"><span>Delete</span><DropdownMenuShortcut>⌘⌫</DropdownMenuShortcut></DropdownMenuItem></DropdownMenuContent></DropdownMenu>\n</template>\n"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-08.html",
          "target": "components/ui/dropdown-08.html",
          "type": "registry:component",
          "content": "<template>\n  <DropdownMenu><DropdownMenuTrigger aschild><Button variant=\"outline\">Rich menu\n          <ChevronDownIcon class=\"-me-1 opacity-60\" size=\"${16}\" aria-hidden=\"true\" /></Button></DropdownMenuTrigger><DropdownMenuContent><DropdownMenuGroup><DropdownMenuItem><span>Edit</span><DropdownMenuShortcut>⌘E</DropdownMenuShortcut></DropdownMenuItem><DropdownMenuItem><span>Duplicate</span><DropdownMenuShortcut>⌘D</DropdownMenuShortcut></DropdownMenuItem></DropdownMenuGroup><DropdownMenuSeparator /><DropdownMenuGroup><DropdownMenuItem><span>Archive</span><DropdownMenuShortcut>⌘A</DropdownMenuShortcut></DropdownMenuItem><DropdownMenuSub><DropdownMenuSubTrigger>More</DropdownMenuSubTrigger><DropdownMenuPortal><DropdownMenuSubContent><DropdownMenuItem>Move to project</DropdownMenuItem><DropdownMenuItem>Move to folder</DropdownMenuItem><DropdownMenuSeparator /><DropdownMenuItem>Advanced options</DropdownMenuItem></DropdownMenuSubContent></DropdownMenuPortal></DropdownMenuSub></DropdownMenuGroup><DropdownMenuSeparator /><DropdownMenuGroup><DropdownMenuItem>Share</DropdownMenuItem><DropdownMenuItem>Add to favorites</DropdownMenuItem></DropdownMenuGroup><DropdownMenuSeparator /><DropdownMenuItem variant=\"destructive\"><span>Delete</span><DropdownMenuShortcut>⌘⌫</DropdownMenuShortcut></DropdownMenuItem></DropdownMenuContent></DropdownMenu>\n</template>"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-08.wxml",
          "target": "components/ui/dropdown-08/dropdown-08.wxml",
          "type": "registry:component",
          "content": "<view>\n  <dropdownmenu><dropdownmenutrigger aschild><button variant=\"outline\">Rich menu\n          <chevrondownicon class=\"-me-1 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" /></button></dropdownmenutrigger><dropdownmenucontent><dropdownmenugroup><dropdownmenuitem><text>Edit</text><dropdownmenushortcut>⌘E</dropdownmenushortcut></dropdownmenuitem><dropdownmenuitem><text>Duplicate</text><dropdownmenushortcut>⌘D</dropdownmenushortcut></dropdownmenuitem></dropdownmenugroup><dropdownmenuseparator /><dropdownmenugroup><dropdownmenuitem><text>Archive</text><dropdownmenushortcut>⌘A</dropdownmenushortcut></dropdownmenuitem><dropdownmenusub><dropdownmenusubtrigger>More</dropdownmenusubtrigger><dropdownmenuportal><dropdownmenusubcontent><dropdownmenuitem>Move to project</dropdownmenuitem><dropdownmenuitem>Move to folder</dropdownmenuitem><dropdownmenuseparator /><dropdownmenuitem>Advanced options</dropdownmenuitem></dropdownmenusubcontent></dropdownmenuportal></dropdownmenusub></dropdownmenugroup><dropdownmenuseparator /><dropdownmenugroup><dropdownmenuitem>Share</dropdownmenuitem><dropdownmenuitem>Add to favorites</dropdownmenuitem></dropdownmenugroup><dropdownmenuseparator /><dropdownmenuitem variant=\"destructive\"><text>Delete</text><dropdownmenushortcut>⌘⌫</dropdownmenushortcut></dropdownmenuitem></dropdownmenucontent></dropdownmenu>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dropdown",
          "kbd",
          "delete",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dropdown-08",
          "group": "dropdown",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dropdown-08",
              "path": "registry/default/components/dropdown/dropdown-08.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dropdown-08",
              "path": "registry/default/components/dropdown/dropdown-08.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dropdown-08",
              "path": "registry/default/components/dropdown/dropdown-08.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dropdown-08",
              "path": "registry/default/components/dropdown/dropdown-08.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dropdown",
        "title": "Dropdown · With icon"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "dropdown"
      ]
    },
    {
      "name": "dropdown-09",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dropdown-menu.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/dropdown/dropdown-09.tsx",
          "type": "registry:component",
          "target": "components/ui/dropdown-09.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport {\n  Button,\n  DropdownMenu,\n  DropdownMenuCheckboxItem,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuPortal,\n  DropdownMenuRadioGroup,\n  DropdownMenuRadioItem,\n  DropdownMenuSeparator,\n  DropdownMenuShortcut,\n  DropdownMenuSub,\n  DropdownMenuSubContent,\n  DropdownMenuSubTrigger,\n  DropdownMenuTrigger,\n} from '@timui/react'\nimport { ArchiveRestoreIcon, ChevronDownIcon, PlusIcon, Share2Icon, TrashIcon } from 'lucide-react'\n\nexport default function Component() {\n  const [framework, setFramework] = useState('nextjs')\n  const [emailNotifications, setEmailNotifications] = useState(false)\n  const [pushNotifications, setPushNotifications] = useState(true)\n\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button variant=\"outline\">\n          Rich menu with icons\n          <ChevronDownIcon className=\"-me-1 opacity-60\" size={16} aria-hidden=\"true\" />\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent>\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <PlusIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>New</span>\n            <DropdownMenuShortcut>⌘N</DropdownMenuShortcut>\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuSub>\n            <DropdownMenuSubTrigger inset>Framework</DropdownMenuSubTrigger>\n            <DropdownMenuPortal>\n              <DropdownMenuSubContent>\n                <DropdownMenuRadioGroup value={framework} onValueChange={setFramework}>\n                  <DropdownMenuRadioItem value=\"nextjs\">Next.js</DropdownMenuRadioItem>\n                  <DropdownMenuRadioItem value=\"sveltekit\" disabled>\n                    SvelteKit\n                  </DropdownMenuRadioItem>\n                  <DropdownMenuRadioItem value=\"remix\">Remix</DropdownMenuRadioItem>\n                  <DropdownMenuRadioItem value=\"astro\">Astro</DropdownMenuRadioItem>\n                </DropdownMenuRadioGroup>\n              </DropdownMenuSubContent>\n            </DropdownMenuPortal>\n          </DropdownMenuSub>\n          <DropdownMenuSub>\n            <DropdownMenuSubTrigger inset>Notifications</DropdownMenuSubTrigger>\n            <DropdownMenuPortal>\n              <DropdownMenuSubContent>\n                <DropdownMenuCheckboxItem\n                  checked={emailNotifications}\n                  onCheckedChange={setEmailNotifications}\n                >\n                  Email\n                </DropdownMenuCheckboxItem>\n                <DropdownMenuCheckboxItem\n                  checked={pushNotifications}\n                  onCheckedChange={setPushNotifications}\n                >\n                  Push\n                </DropdownMenuCheckboxItem>\n              </DropdownMenuSubContent>\n            </DropdownMenuPortal>\n          </DropdownMenuSub>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <Share2Icon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Share</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <ArchiveRestoreIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Archive</span>\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuItem variant=\"destructive\">\n          <TrashIcon size={16} aria-hidden=\"true\" />\n          <span>Delete</span>\n          <DropdownMenuShortcut>⌘⌫</DropdownMenuShortcut>\n        </DropdownMenuItem>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-09.vue",
          "target": "components/ui/dropdown-09.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { ArchiveRestoreIcon, ChevronDownIcon, PlusIcon, Share2Icon, TrashIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger } from '@timui/vue';\n\n\n\nconst framework = ref('nextjs');\nconst emailNotifications = ref(false);\nconst pushNotifications = ref(true);\n\n\nfunction setFramework(next: typeof framework.value | ((prev: typeof framework.value) => typeof framework.value)) {\n  framework.value = typeof next === 'function'\n    ? (next as (prev: typeof framework.value) => typeof framework.value)(framework.value)\n    : next;\n}\n\nfunction setEmailNotifications(next: typeof emailNotifications.value | ((prev: typeof emailNotifications.value) => typeof emailNotifications.value)) {\n  emailNotifications.value = typeof next === 'function'\n    ? (next as (prev: typeof emailNotifications.value) => typeof emailNotifications.value)(emailNotifications.value)\n    : next;\n}\n\nfunction setPushNotifications(next: typeof pushNotifications.value | ((prev: typeof pushNotifications.value) => typeof pushNotifications.value)) {\n  pushNotifications.value = typeof next === 'function'\n    ? (next as (prev: typeof pushNotifications.value) => typeof pushNotifications.value)(pushNotifications.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <DropdownMenu><DropdownMenuTrigger as-child><Button variant=\"outline\">Rich menu with icons\n          <ChevronDownIcon class=\"-me-1 opacity-60\" :size=\"16\" aria-hidden=\"true\" /></Button></DropdownMenuTrigger><DropdownMenuContent><DropdownMenuGroup><DropdownMenuItem><PlusIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" /><span>New</span><DropdownMenuShortcut>⌘N</DropdownMenuShortcut></DropdownMenuItem></DropdownMenuGroup><DropdownMenuSeparator /><DropdownMenuGroup><DropdownMenuSub><DropdownMenuSubTrigger inset>Framework</DropdownMenuSubTrigger><DropdownMenuPortal><DropdownMenuSubContent><DropdownMenuRadioGroup :value=\"framework\" @update:modelValue=\"setFramework\"><DropdownMenuRadioItem value=\"nextjs\">Next.js</DropdownMenuRadioItem><DropdownMenuRadioItem value=\"sveltekit\" disabled>SvelteKit\n                  </DropdownMenuRadioItem><DropdownMenuRadioItem value=\"remix\">Remix</DropdownMenuRadioItem><DropdownMenuRadioItem value=\"astro\">Astro</DropdownMenuRadioItem></DropdownMenuRadioGroup></DropdownMenuSubContent></DropdownMenuPortal></DropdownMenuSub><DropdownMenuSub><DropdownMenuSubTrigger inset>Notifications</DropdownMenuSubTrigger><DropdownMenuPortal><DropdownMenuSubContent><DropdownMenuCheckboxItem :checked=\"emailNotifications\" :onCheckedChange=\"setEmailNotifications\">Email\n                </DropdownMenuCheckboxItem><DropdownMenuCheckboxItem :checked=\"pushNotifications\" :onCheckedChange=\"setPushNotifications\">Push\n                </DropdownMenuCheckboxItem></DropdownMenuSubContent></DropdownMenuPortal></DropdownMenuSub></DropdownMenuGroup><DropdownMenuSeparator /><DropdownMenuGroup><DropdownMenuItem><Share2Icon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Share</span></DropdownMenuItem><DropdownMenuItem><ArchiveRestoreIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Archive</span></DropdownMenuItem></DropdownMenuGroup><DropdownMenuSeparator /><DropdownMenuItem variant=\"destructive\"><TrashIcon :size=\"16\" aria-hidden=\"true\" /><span>Delete</span><DropdownMenuShortcut>⌘⌫</DropdownMenuShortcut></DropdownMenuItem></DropdownMenuContent></DropdownMenu>\n</template>\n"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-09.html",
          "target": "components/ui/dropdown-09.html",
          "type": "registry:component",
          "content": "<template>\n  <DropdownMenu><DropdownMenuTrigger aschild><Button variant=\"outline\">Rich menu with icons\n          <ChevronDownIcon class=\"-me-1 opacity-60\" size=\"${16}\" aria-hidden=\"true\" /></Button></DropdownMenuTrigger><DropdownMenuContent><DropdownMenuGroup><DropdownMenuItem><PlusIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" /><span>New</span><DropdownMenuShortcut>⌘N</DropdownMenuShortcut></DropdownMenuItem></DropdownMenuGroup><DropdownMenuSeparator /><DropdownMenuGroup><DropdownMenuSub><DropdownMenuSubTrigger inset>Framework</DropdownMenuSubTrigger><DropdownMenuPortal><DropdownMenuSubContent><DropdownMenuRadioGroup value=\"${framework}\" on-value-change=\"${setFramework}\"><DropdownMenuRadioItem value=\"nextjs\">Next.js</DropdownMenuRadioItem><DropdownMenuRadioItem value=\"sveltekit\" disabled>SvelteKit\n                  </DropdownMenuRadioItem><DropdownMenuRadioItem value=\"remix\">Remix</DropdownMenuRadioItem><DropdownMenuRadioItem value=\"astro\">Astro</DropdownMenuRadioItem></DropdownMenuRadioGroup></DropdownMenuSubContent></DropdownMenuPortal></DropdownMenuSub><DropdownMenuSub><DropdownMenuSubTrigger inset>Notifications</DropdownMenuSubTrigger><DropdownMenuPortal><DropdownMenuSubContent><DropdownMenuCheckboxItem checked=\"${emailNotifications}\" oncheckedchange=\"${setEmailNotifications}\">Email\n                </DropdownMenuCheckboxItem><DropdownMenuCheckboxItem checked=\"${pushNotifications}\" oncheckedchange=\"${setPushNotifications}\">Push\n                </DropdownMenuCheckboxItem></DropdownMenuSubContent></DropdownMenuPortal></DropdownMenuSub></DropdownMenuGroup><DropdownMenuSeparator /><DropdownMenuGroup><DropdownMenuItem><Share2Icon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Share</span></DropdownMenuItem><DropdownMenuItem><ArchiveRestoreIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Archive</span></DropdownMenuItem></DropdownMenuGroup><DropdownMenuSeparator /><DropdownMenuItem variant=\"destructive\"><TrashIcon size=\"${16}\" aria-hidden=\"true\" /><span>Delete</span><DropdownMenuShortcut>⌘⌫</DropdownMenuShortcut></DropdownMenuItem></DropdownMenuContent></DropdownMenu>\n</template>"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-09.wxml",
          "target": "components/ui/dropdown-09/dropdown-09.wxml",
          "type": "registry:component",
          "content": "<view>\n  <dropdownmenu><dropdownmenutrigger aschild><button variant=\"outline\">Rich menu with icons\n          <chevrondownicon class=\"-me-1 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" /></button></dropdownmenutrigger><dropdownmenucontent><dropdownmenugroup><dropdownmenuitem><plusicon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" /><text>New</text><dropdownmenushortcut>⌘N</dropdownmenushortcut></dropdownmenuitem></dropdownmenugroup><dropdownmenuseparator /><dropdownmenugroup><dropdownmenusub><dropdownmenusubtrigger inset>Framework</dropdownmenusubtrigger><dropdownmenuportal><dropdownmenusubcontent><dropdownmenuradiogroup value=\"{{framework}}\" bindchange=\"setFramework\"><dropdownmenuradioitem value=\"nextjs\">Next.js</dropdownmenuradioitem><dropdownmenuradioitem value=\"sveltekit\" disabled>SvelteKit\n                  </dropdownmenuradioitem><dropdownmenuradioitem value=\"remix\">Remix</dropdownmenuradioitem><dropdownmenuradioitem value=\"astro\">Astro</dropdownmenuradioitem></dropdownmenuradiogroup></dropdownmenusubcontent></dropdownmenuportal></dropdownmenusub><dropdownmenusub><dropdownmenusubtrigger inset>Notifications</dropdownmenusubtrigger><dropdownmenuportal><dropdownmenusubcontent><dropdownmenucheckboxitem checked=\"{{emailNotifications}}\" oncheckedchange=\"{{setEmailNotifications}}\">Email\n                </dropdownmenucheckboxitem><dropdownmenucheckboxitem checked=\"{{pushNotifications}}\" oncheckedchange=\"{{setPushNotifications}}\">Push\n                </dropdownmenucheckboxitem></dropdownmenusubcontent></dropdownmenuportal></dropdownmenusub></dropdownmenugroup><dropdownmenuseparator /><dropdownmenugroup><dropdownmenuitem><share2icon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" /><text>Share</text></dropdownmenuitem><dropdownmenuitem><archiverestoreicon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" /><text>Archive</text></dropdownmenuitem></dropdownmenugroup><dropdownmenuseparator /><dropdownmenuitem variant=\"destructive\"><trashicon size=\"{{16}}\" aria-hidden=\"true\" /><text>Delete</text><dropdownmenushortcut>⌘⌫</dropdownmenushortcut></dropdownmenuitem></dropdownmenucontent></dropdownmenu>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dropdown",
          "checkbox",
          "radio",
          "delete",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dropdown-09",
          "group": "dropdown",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dropdown-09",
              "path": "registry/default/components/dropdown/dropdown-09.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dropdown-09",
              "path": "registry/default/components/dropdown/dropdown-09.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dropdown-09",
              "path": "registry/default/components/dropdown/dropdown-09.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dropdown-09",
              "path": "registry/default/components/dropdown/dropdown-09.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dropdown",
        "title": "Dropdown · Disabled State"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "dropdown"
      ]
    },
    {
      "name": "dropdown-10",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dropdown-menu.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/dropdown/dropdown-10.tsx",
          "type": "registry:component",
          "target": "components/ui/dropdown-10.tsx",
          "content": "import {\n  Button,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from '@timui/react'\nimport { CircleUserRoundIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button size=\"icon\" variant=\"outline\" aria-label=\"Open account menu\">\n          <CircleUserRoundIcon size={16} aria-hidden=\"true\" />\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent className=\"max-w-64\">\n        <DropdownMenuLabel className=\"flex flex-col\">\n          <span>Signed in as</span>\n          <span className=\"text-foreground text-xs font-normal\">k.kennedy@ui.timkit.cn</span>\n        </DropdownMenuLabel>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuItem>Option 1</DropdownMenuItem>\n          <DropdownMenuItem>Option 2</DropdownMenuItem>\n          <DropdownMenuItem>Option 3</DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuItem>Logout</DropdownMenuItem>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-10.vue",
          "target": "components/ui/dropdown-10.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { CircleUserRoundIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <DropdownMenu><DropdownMenuTrigger as-child><Button size=\"icon\" variant=\"outline\" aria-label=\"Open account menu\"><CircleUserRoundIcon :size=\"16\" aria-hidden=\"true\" /></Button></DropdownMenuTrigger><DropdownMenuContent class=\"max-w-64\"><DropdownMenuLabel class=\"flex flex-col\"><span>Signed in as</span><span class=\"text-foreground text-xs font-normal\">k.kennedy@ui.timkit.cn</span></DropdownMenuLabel><DropdownMenuSeparator /><DropdownMenuGroup><DropdownMenuItem>Option 1</DropdownMenuItem><DropdownMenuItem>Option 2</DropdownMenuItem><DropdownMenuItem>Option 3</DropdownMenuItem></DropdownMenuGroup><DropdownMenuSeparator /><DropdownMenuItem>Logout</DropdownMenuItem></DropdownMenuContent></DropdownMenu>\n</template>\n"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-10.html",
          "target": "components/ui/dropdown-10.html",
          "type": "registry:component",
          "content": "<template>\n  <DropdownMenu><DropdownMenuTrigger aschild><Button size=\"icon\" variant=\"outline\" aria-label=\"Open account menu\"><CircleUserRoundIcon size=\"${16}\" aria-hidden=\"true\" /></Button></DropdownMenuTrigger><DropdownMenuContent class=\"max-w-64\"><DropdownMenuLabel class=\"flex flex-col\"><span>Signed in as</span><span class=\"text-foreground text-xs font-normal\">k.kennedy@ui.timkit.cn</span></DropdownMenuLabel><DropdownMenuSeparator /><DropdownMenuGroup><DropdownMenuItem>Option 1</DropdownMenuItem><DropdownMenuItem>Option 2</DropdownMenuItem><DropdownMenuItem>Option 3</DropdownMenuItem></DropdownMenuGroup><DropdownMenuSeparator /><DropdownMenuItem>Logout</DropdownMenuItem></DropdownMenuContent></DropdownMenu>\n</template>"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-10.wxml",
          "target": "components/ui/dropdown-10/dropdown-10.wxml",
          "type": "registry:component",
          "content": "<view>\n  <dropdownmenu><dropdownmenutrigger aschild><button size=\"icon\" variant=\"outline\" aria-label=\"Open account menu\"><circleuserroundicon size=\"{{16}}\" aria-hidden=\"true\" /></button></dropdownmenutrigger><dropdownmenucontent class=\"max-w-64\"><dropdownmenulabel class=\"flex flex-col\"><text>Signed in as</text><text class=\"text-foreground text-xs font-normal\">k.kennedy@ui.timkit.cn</text></dropdownmenulabel><dropdownmenuseparator /><dropdownmenugroup><dropdownmenuitem>Option 1</dropdownmenuitem><dropdownmenuitem>Option 2</dropdownmenuitem><dropdownmenuitem>Option 3</dropdownmenuitem></dropdownmenugroup><dropdownmenuseparator /><dropdownmenuitem>Logout</dropdownmenuitem></dropdownmenucontent></dropdownmenu>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dropdown",
          "user",
          "profile",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dropdown-10",
          "group": "dropdown",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dropdown-10",
              "path": "registry/default/components/dropdown/dropdown-10.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dropdown-10",
              "path": "registry/default/components/dropdown/dropdown-10.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dropdown-10",
              "path": "registry/default/components/dropdown/dropdown-10.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dropdown-10",
              "path": "registry/default/components/dropdown/dropdown-10.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dropdown",
        "title": "Dropdown · Open account menu"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "dropdown"
      ]
    },
    {
      "name": "dropdown-11",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dropdown-menu.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/dropdown/dropdown-11.tsx",
          "type": "registry:component",
          "target": "components/ui/dropdown-11.tsx",
          "content": "import {\n  Button,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from '@timui/react'\nimport {\n  BoltIcon,\n  BookOpenIcon,\n  CircleUserRoundIcon,\n  Layers2Icon,\n  LogOutIcon,\n  PinIcon,\n  UserPenIcon,\n} from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button size=\"icon\" variant=\"outline\" aria-label=\"Open account menu\">\n          <CircleUserRoundIcon size={16} aria-hidden=\"true\" />\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent className=\"max-w-64\">\n        <DropdownMenuLabel className=\"flex items-start gap-3\">\n          <img\n            src=\"avatar.jpg\"\n            alt=\"Avatar\"\n            width={32}\n            height={32}\n            className=\"shrink-0 rounded-full\"\n          />\n          <div className=\"flex min-w-0 flex-col\">\n            <span className=\"text-foreground truncate text-sm font-medium\">Keith Kennedy</span>\n            <span className=\"text-muted-foreground truncate text-xs font-normal\">\n              k.kennedy@ui.timkit.cn\n            </span>\n          </div>\n        </DropdownMenuLabel>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <BoltIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 1</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <Layers2Icon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 2</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <BookOpenIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 3</span>\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <PinIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 4</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <UserPenIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 5</span>\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuItem>\n          <LogOutIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n          <span>Logout</span>\n        </DropdownMenuItem>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-11.vue",
          "target": "components/ui/dropdown-11.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { BoltIcon, BookOpenIcon, CircleUserRoundIcon, Layers2Icon, LogOutIcon, PinIcon, UserPenIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <DropdownMenu><DropdownMenuTrigger as-child><Button size=\"icon\" variant=\"outline\" aria-label=\"Open account menu\"><CircleUserRoundIcon :size=\"16\" aria-hidden=\"true\" /></Button></DropdownMenuTrigger><DropdownMenuContent class=\"max-w-64\"><DropdownMenuLabel class=\"flex items-start gap-3\"><img src=\"avatar.jpg\" alt=\"Avatar\" :width=\"32\" :height=\"32\" class=\"shrink-0 rounded-full\" /><div class=\"flex min-w-0 flex-col\"><span class=\"text-foreground truncate text-sm font-medium\">Keith Kennedy</span><span class=\"text-muted-foreground truncate text-xs font-normal\">k.kennedy@ui.timkit.cn\n            </span></div></DropdownMenuLabel><DropdownMenuSeparator /><DropdownMenuGroup><DropdownMenuItem><BoltIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Option 1</span></DropdownMenuItem><DropdownMenuItem><Layers2Icon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Option 2</span></DropdownMenuItem><DropdownMenuItem><BookOpenIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Option 3</span></DropdownMenuItem></DropdownMenuGroup><DropdownMenuSeparator /><DropdownMenuGroup><DropdownMenuItem><PinIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Option 4</span></DropdownMenuItem><DropdownMenuItem><UserPenIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Option 5</span></DropdownMenuItem></DropdownMenuGroup><DropdownMenuSeparator /><DropdownMenuItem><LogOutIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Logout</span></DropdownMenuItem></DropdownMenuContent></DropdownMenu>\n</template>\n"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-11.html",
          "target": "components/ui/dropdown-11.html",
          "type": "registry:component",
          "content": "<template>\n  <DropdownMenu><DropdownMenuTrigger aschild><Button size=\"icon\" variant=\"outline\" aria-label=\"Open account menu\"><CircleUserRoundIcon size=\"${16}\" aria-hidden=\"true\" /></Button></DropdownMenuTrigger><DropdownMenuContent class=\"max-w-64\"><DropdownMenuLabel class=\"flex items-start gap-3\"><img src=\"avatar.jpg\" alt=\"Avatar\" width=\"${32}\" height=\"${32}\" class=\"shrink-0 rounded-full\" /><div class=\"flex min-w-0 flex-col\"><span class=\"text-foreground truncate text-sm font-medium\">Keith Kennedy</span><span class=\"text-muted-foreground truncate text-xs font-normal\">k.kennedy@ui.timkit.cn\n            </span></div></DropdownMenuLabel><DropdownMenuSeparator /><DropdownMenuGroup><DropdownMenuItem><BoltIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Option 1</span></DropdownMenuItem><DropdownMenuItem><Layers2Icon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Option 2</span></DropdownMenuItem><DropdownMenuItem><BookOpenIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Option 3</span></DropdownMenuItem></DropdownMenuGroup><DropdownMenuSeparator /><DropdownMenuGroup><DropdownMenuItem><PinIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Option 4</span></DropdownMenuItem><DropdownMenuItem><UserPenIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Option 5</span></DropdownMenuItem></DropdownMenuGroup><DropdownMenuSeparator /><DropdownMenuItem><LogOutIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Logout</span></DropdownMenuItem></DropdownMenuContent></DropdownMenu>\n</template>"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-11.wxml",
          "target": "components/ui/dropdown-11/dropdown-11.wxml",
          "type": "registry:component",
          "content": "<view>\n  <dropdownmenu><dropdownmenutrigger aschild><button size=\"icon\" variant=\"outline\" aria-label=\"Open account menu\"><circleuserroundicon size=\"{{16}}\" aria-hidden=\"true\" /></button></dropdownmenutrigger><dropdownmenucontent class=\"max-w-64\"><dropdownmenulabel class=\"flex items-start gap-3\"><image src=\"avatar.jpg\" alt=\"Avatar\" width=\"{{32}}\" height=\"{{32}}\" class=\"shrink-0 rounded-full\" /><view class=\"flex min-w-0 flex-col\"><text class=\"text-foreground truncate text-sm font-medium\">Keith Kennedy</text><text class=\"text-muted-foreground truncate text-xs font-normal\">k.kennedy@ui.timkit.cn\n            </text></view></dropdownmenulabel><dropdownmenuseparator /><dropdownmenugroup><dropdownmenuitem><bolticon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" /><text>Option 1</text></dropdownmenuitem><dropdownmenuitem><layers2icon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" /><text>Option 2</text></dropdownmenuitem><dropdownmenuitem><bookopenicon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" /><text>Option 3</text></dropdownmenuitem></dropdownmenugroup><dropdownmenuseparator /><dropdownmenugroup><dropdownmenuitem><pinicon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" /><text>Option 4</text></dropdownmenuitem><dropdownmenuitem><userpenicon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" /><text>Option 5</text></dropdownmenuitem></dropdownmenugroup><dropdownmenuseparator /><dropdownmenuitem><logouticon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" /><text>Logout</text></dropdownmenuitem></dropdownmenucontent></dropdownmenu>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dropdown",
          "user",
          "profile",
          "avatar",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dropdown-11",
          "group": "dropdown",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dropdown-11",
              "path": "registry/default/components/dropdown/dropdown-11.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dropdown-11",
              "path": "registry/default/components/dropdown/dropdown-11.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dropdown-11",
              "path": "registry/default/components/dropdown/dropdown-11.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dropdown-11",
              "path": "registry/default/components/dropdown/dropdown-11.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dropdown",
        "title": "Dropdown · Open account menu"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "dropdown"
      ]
    },
    {
      "name": "dropdown-12",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dropdown-menu.json",
        "https://ui.timkit.cn/r/avatar.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/dropdown/dropdown-12.tsx",
          "type": "registry:component",
          "target": "components/ui/dropdown-12.tsx",
          "content": "import {\n  Avatar,\n  AvatarFallback,\n  AvatarImage,\n  Button,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from '@timui/react'\nimport {\n  BoltIcon,\n  BookOpenIcon,\n  ChevronDownIcon,\n  Layers2Icon,\n  LogOutIcon,\n  PinIcon,\n  UserPenIcon,\n} from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button variant=\"ghost\" className=\"h-auto p-0 hover:bg-transparent\">\n          <Avatar>\n            <AvatarImage src=\"./avatar.jpg\" alt=\"Profile image\" />\n            <AvatarFallback>KK</AvatarFallback>\n          </Avatar>\n          <ChevronDownIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent className=\"max-w-64\">\n        <DropdownMenuLabel className=\"flex min-w-0 flex-col\">\n          <span className=\"text-foreground truncate text-sm font-medium\">Keith Kennedy</span>\n          <span className=\"text-muted-foreground truncate text-xs font-normal\">\n            k.kennedy@ui.timkit.cn\n          </span>\n        </DropdownMenuLabel>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <BoltIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 1</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <Layers2Icon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 2</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <BookOpenIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 3</span>\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <PinIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 4</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <UserPenIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 5</span>\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuItem>\n          <LogOutIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n          <span>Logout</span>\n        </DropdownMenuItem>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-12.vue",
          "target": "components/ui/dropdown-12.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { BoltIcon, BookOpenIcon, ChevronDownIcon, Layers2Icon, LogOutIcon, PinIcon, UserPenIcon } from 'lucide-vue-next';\nimport { Avatar, AvatarFallback, AvatarImage } from '@timui/vue';\nimport { Button } from '@timui/vue';\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <DropdownMenu><DropdownMenuTrigger as-child><Button variant=\"ghost\" class=\"h-auto p-0 hover:bg-transparent\"><Avatar><AvatarImage src=\"./avatar.jpg\" alt=\"Profile image\" /><AvatarFallback>KK</AvatarFallback></Avatar><ChevronDownIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" /></Button></DropdownMenuTrigger><DropdownMenuContent class=\"max-w-64\"><DropdownMenuLabel class=\"flex min-w-0 flex-col\"><span class=\"text-foreground truncate text-sm font-medium\">Keith Kennedy</span><span class=\"text-muted-foreground truncate text-xs font-normal\">k.kennedy@ui.timkit.cn\n          </span></DropdownMenuLabel><DropdownMenuSeparator /><DropdownMenuGroup><DropdownMenuItem><BoltIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Option 1</span></DropdownMenuItem><DropdownMenuItem><Layers2Icon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Option 2</span></DropdownMenuItem><DropdownMenuItem><BookOpenIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Option 3</span></DropdownMenuItem></DropdownMenuGroup><DropdownMenuSeparator /><DropdownMenuGroup><DropdownMenuItem><PinIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Option 4</span></DropdownMenuItem><DropdownMenuItem><UserPenIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Option 5</span></DropdownMenuItem></DropdownMenuGroup><DropdownMenuSeparator /><DropdownMenuItem><LogOutIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Logout</span></DropdownMenuItem></DropdownMenuContent></DropdownMenu>\n</template>\n"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-12.html",
          "target": "components/ui/dropdown-12.html",
          "type": "registry:component",
          "content": "<template>\n  <DropdownMenu><DropdownMenuTrigger aschild><Button variant=\"ghost\" class=\"h-auto p-0 hover:bg-transparent\"><Avatar><AvatarImage src=\"./avatar.jpg\" alt=\"Profile image\" /><AvatarFallback>KK</AvatarFallback></Avatar><ChevronDownIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" /></Button></DropdownMenuTrigger><DropdownMenuContent class=\"max-w-64\"><DropdownMenuLabel class=\"flex min-w-0 flex-col\"><span class=\"text-foreground truncate text-sm font-medium\">Keith Kennedy</span><span class=\"text-muted-foreground truncate text-xs font-normal\">k.kennedy@ui.timkit.cn\n          </span></DropdownMenuLabel><DropdownMenuSeparator /><DropdownMenuGroup><DropdownMenuItem><BoltIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Option 1</span></DropdownMenuItem><DropdownMenuItem><Layers2Icon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Option 2</span></DropdownMenuItem><DropdownMenuItem><BookOpenIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Option 3</span></DropdownMenuItem></DropdownMenuGroup><DropdownMenuSeparator /><DropdownMenuGroup><DropdownMenuItem><PinIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Option 4</span></DropdownMenuItem><DropdownMenuItem><UserPenIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Option 5</span></DropdownMenuItem></DropdownMenuGroup><DropdownMenuSeparator /><DropdownMenuItem><LogOutIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Logout</span></DropdownMenuItem></DropdownMenuContent></DropdownMenu>\n</template>"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-12.wxml",
          "target": "components/ui/dropdown-12/dropdown-12.wxml",
          "type": "registry:component",
          "content": "<view>\n  <dropdownmenu><dropdownmenutrigger aschild><button variant=\"ghost\" class=\"h-auto p-0 hover:bg-transparent\"><avatar><avatarimage src=\"./avatar.jpg\" alt=\"Profile image\" /><avatarfallback>KK</avatarfallback></avatar><chevrondownicon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" /></button></dropdownmenutrigger><dropdownmenucontent class=\"max-w-64\"><dropdownmenulabel class=\"flex min-w-0 flex-col\"><text class=\"text-foreground truncate text-sm font-medium\">Keith Kennedy</text><text class=\"text-muted-foreground truncate text-xs font-normal\">k.kennedy@ui.timkit.cn\n          </text></dropdownmenulabel><dropdownmenuseparator /><dropdownmenugroup><dropdownmenuitem><bolticon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" /><text>Option 1</text></dropdownmenuitem><dropdownmenuitem><layers2icon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" /><text>Option 2</text></dropdownmenuitem><dropdownmenuitem><bookopenicon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" /><text>Option 3</text></dropdownmenuitem></dropdownmenugroup><dropdownmenuseparator /><dropdownmenugroup><dropdownmenuitem><pinicon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" /><text>Option 4</text></dropdownmenuitem><dropdownmenuitem><userpenicon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" /><text>Option 5</text></dropdownmenuitem></dropdownmenugroup><dropdownmenuseparator /><dropdownmenuitem><logouticon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" /><text>Logout</text></dropdownmenuitem></dropdownmenucontent></dropdownmenu>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dropdown",
          "user",
          "avatar",
          "profile",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dropdown-12",
          "group": "dropdown",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dropdown-12",
              "path": "registry/default/components/dropdown/dropdown-12.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dropdown-12",
              "path": "registry/default/components/dropdown/dropdown-12.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dropdown-12",
              "path": "registry/default/components/dropdown/dropdown-12.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dropdown-12",
              "path": "registry/default/components/dropdown/dropdown-12.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dropdown",
        "title": "Dropdown · Interactive State"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "dropdown"
      ]
    },
    {
      "name": "dropdown-13",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dropdown-menu.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/dropdown/dropdown-13.tsx",
          "type": "registry:component",
          "target": "components/ui/dropdown-13.tsx",
          "content": "import {\n  Button,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuTrigger,\n} from '@timui/react'\nimport { BookIcon, InfoIcon, LifeBuoyIcon, MessageCircleMoreIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button\n          size=\"icon\"\n          variant=\"ghost\"\n          className=\"rounded-full shadow-none\"\n          aria-label=\"Open edit menu\"\n        >\n          <InfoIcon size={16} aria-hidden=\"true\" />\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent className=\"pb-2\">\n        <DropdownMenuLabel>Need help?</DropdownMenuLabel>\n        <DropdownMenuItem\n          className=\"cursor-pointer py-1 focus:bg-transparent focus:underline\"\n          asChild\n        >\n          <a href=\"#\">\n            <BookIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            Documentation\n          </a>\n        </DropdownMenuItem>\n        <DropdownMenuItem\n          className=\"cursor-pointer py-1 focus:bg-transparent focus:underline\"\n          asChild\n        >\n          <a href=\"#\">\n            <LifeBuoyIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            Support\n          </a>\n        </DropdownMenuItem>\n        <DropdownMenuItem\n          className=\"cursor-pointer py-1 focus:bg-transparent focus:underline\"\n          asChild\n        >\n          <a href=\"#\">\n            <MessageCircleMoreIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            Contact us\n          </a>\n        </DropdownMenuItem>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-13.vue",
          "target": "components/ui/dropdown-13.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { BookIcon, InfoIcon, LifeBuoyIcon, MessageCircleMoreIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <DropdownMenu><DropdownMenuTrigger as-child><Button size=\"icon\" variant=\"ghost\" class=\"rounded-full shadow-none\" aria-label=\"Open edit menu\"><InfoIcon :size=\"16\" aria-hidden=\"true\" /></Button></DropdownMenuTrigger><DropdownMenuContent class=\"pb-2\"><DropdownMenuLabel>Need help?</DropdownMenuLabel><DropdownMenuItem class=\"cursor-pointer py-1 focus:bg-transparent focus:underline\" as-child><a href=\"#\"><BookIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" />Documentation\n          </a></DropdownMenuItem><DropdownMenuItem class=\"cursor-pointer py-1 focus:bg-transparent focus:underline\" as-child><a href=\"#\"><LifeBuoyIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" />Support\n          </a></DropdownMenuItem><DropdownMenuItem class=\"cursor-pointer py-1 focus:bg-transparent focus:underline\" as-child><a href=\"#\"><MessageCircleMoreIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" />Contact us\n          </a></DropdownMenuItem></DropdownMenuContent></DropdownMenu>\n</template>\n"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-13.html",
          "target": "components/ui/dropdown-13.html",
          "type": "registry:component",
          "content": "<template>\n  <DropdownMenu><DropdownMenuTrigger aschild><Button size=\"icon\" variant=\"ghost\" class=\"rounded-full shadow-none\" aria-label=\"Open edit menu\"><InfoIcon size=\"${16}\" aria-hidden=\"true\" /></Button></DropdownMenuTrigger><DropdownMenuContent class=\"pb-2\"><DropdownMenuLabel>Need help?</DropdownMenuLabel><DropdownMenuItem class=\"cursor-pointer py-1 focus:bg-transparent focus:underline\" aschild><a href=\"#\"><BookIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" />Documentation\n          </a></DropdownMenuItem><DropdownMenuItem class=\"cursor-pointer py-1 focus:bg-transparent focus:underline\" aschild><a href=\"#\"><LifeBuoyIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" />Support\n          </a></DropdownMenuItem><DropdownMenuItem class=\"cursor-pointer py-1 focus:bg-transparent focus:underline\" aschild><a href=\"#\"><MessageCircleMoreIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" />Contact us\n          </a></DropdownMenuItem></DropdownMenuContent></DropdownMenu>\n</template>"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-13.wxml",
          "target": "components/ui/dropdown-13/dropdown-13.wxml",
          "type": "registry:component",
          "content": "<view>\n  <dropdownmenu><dropdownmenutrigger aschild><button size=\"icon\" variant=\"ghost\" class=\"rounded-full shadow-none\" aria-label=\"Open edit menu\"><infoicon size=\"{{16}}\" aria-hidden=\"true\" /></button></dropdownmenutrigger><dropdownmenucontent class=\"pb-2\"><dropdownmenulabel>Need help?</dropdownmenulabel><dropdownmenuitem class=\"cursor-pointer py-1 focus:bg-transparent focus:underline\" aschild><a href=\"#\"><bookicon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" />Documentation\n          </a></dropdownmenuitem><dropdownmenuitem class=\"cursor-pointer py-1 focus:bg-transparent focus:underline\" aschild><a href=\"#\"><lifebuoyicon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" />Support\n          </a></dropdownmenuitem><dropdownmenuitem class=\"cursor-pointer py-1 focus:bg-transparent focus:underline\" aschild><a href=\"#\"><messagecirclemoreicon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" />Contact us\n          </a></dropdownmenuitem></dropdownmenucontent></dropdownmenu>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dropdown",
          "info",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dropdown-13",
          "group": "dropdown",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dropdown-13",
              "path": "registry/default/components/dropdown/dropdown-13.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dropdown-13",
              "path": "registry/default/components/dropdown/dropdown-13.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dropdown-13",
              "path": "registry/default/components/dropdown/dropdown-13.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dropdown-13",
              "path": "registry/default/components/dropdown/dropdown-13.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dropdown",
        "title": "Dropdown · Open edit menu"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "dropdown"
      ]
    },
    {
      "name": "dropdown-14",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dropdown-menu.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/dropdown/dropdown-14.tsx",
          "type": "registry:component",
          "target": "components/ui/dropdown-14.tsx",
          "content": "import {\n  Button,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuTrigger,\n} from '@timui/react'\nimport {\n  Heading1Icon,\n  Heading2Icon,\n  MinusIcon,\n  PlusIcon,\n  TextQuoteIcon,\n  TypeIcon,\n} from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button\n          size=\"icon\"\n          variant=\"ghost\"\n          className=\"rounded-full shadow-none\"\n          aria-label=\"Open edit menu\"\n        >\n          <PlusIcon size={16} aria-hidden=\"true\" />\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent className=\"pb-2\">\n        <DropdownMenuLabel>Add block</DropdownMenuLabel>\n        <DropdownMenuItem>\n          <div\n            className=\"bg-background flex size-8 items-center justify-center rounded-md border\"\n            aria-hidden=\"true\"\n          >\n            <TypeIcon size={16} className=\"opacity-60\" />\n          </div>\n          <div>\n            <div className=\"text-sm font-medium\">Text</div>\n            <div className=\"text-muted-foreground text-xs\">Start writing with plain text</div>\n          </div>\n        </DropdownMenuItem>\n        <DropdownMenuItem>\n          <div\n            className=\"bg-background flex size-8 items-center justify-center rounded-md border\"\n            aria-hidden=\"true\"\n          >\n            <TextQuoteIcon size={16} className=\"opacity-60\" />\n          </div>\n          <div>\n            <div className=\"text-sm font-medium\">Quote</div>\n            <div className=\"text-muted-foreground text-xs\">Capture a quote</div>\n          </div>\n        </DropdownMenuItem>\n        <DropdownMenuItem>\n          <div\n            className=\"bg-background flex size-8 items-center justify-center rounded-md border\"\n            aria-hidden=\"true\"\n          >\n            <MinusIcon size={16} className=\"opacity-60\" />\n          </div>\n          <div>\n            <div className=\"text-sm font-medium\">Divider</div>\n            <div className=\"text-muted-foreground text-xs\">Visually divide blocks</div>\n          </div>\n        </DropdownMenuItem>\n        <DropdownMenuItem>\n          <div\n            className=\"bg-background flex size-8 items-center justify-center rounded-md border\"\n            aria-hidden=\"true\"\n          >\n            <Heading1Icon size={16} className=\"opacity-60\" />\n          </div>\n          <div>\n            <div className=\"text-sm font-medium\">Heading 1</div>\n            <div className=\"text-muted-foreground text-xs\">Big section heading</div>\n          </div>\n        </DropdownMenuItem>\n        <DropdownMenuItem>\n          <div\n            className=\"bg-background flex size-8 items-center justify-center rounded-md border\"\n            aria-hidden=\"true\"\n          >\n            <Heading2Icon size={16} className=\"opacity-60\" />\n          </div>\n          <div>\n            <div className=\"text-sm font-medium\">Heading 2</div>\n            <div className=\"text-muted-foreground text-xs\">Medium section subheading</div>\n          </div>\n        </DropdownMenuItem>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-14.vue",
          "target": "components/ui/dropdown-14.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Heading1Icon, Heading2Icon, MinusIcon, PlusIcon, TextQuoteIcon, TypeIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <DropdownMenu><DropdownMenuTrigger as-child><Button size=\"icon\" variant=\"ghost\" class=\"rounded-full shadow-none\" aria-label=\"Open edit menu\"><PlusIcon :size=\"16\" aria-hidden=\"true\" /></Button></DropdownMenuTrigger><DropdownMenuContent class=\"pb-2\"><DropdownMenuLabel>Add block</DropdownMenuLabel><DropdownMenuItem><div class=\"bg-background flex size-8 items-center justify-center rounded-md border\" aria-hidden=\"true\"><TypeIcon :size=\"16\" class=\"opacity-60\" /></div><div><div class=\"text-sm font-medium\">Text</div><div class=\"text-muted-foreground text-xs\">Start writing with plain text</div></div></DropdownMenuItem><DropdownMenuItem><div class=\"bg-background flex size-8 items-center justify-center rounded-md border\" aria-hidden=\"true\"><TextQuoteIcon :size=\"16\" class=\"opacity-60\" /></div><div><div class=\"text-sm font-medium\">Quote</div><div class=\"text-muted-foreground text-xs\">Capture a quote</div></div></DropdownMenuItem><DropdownMenuItem><div class=\"bg-background flex size-8 items-center justify-center rounded-md border\" aria-hidden=\"true\"><MinusIcon :size=\"16\" class=\"opacity-60\" /></div><div><div class=\"text-sm font-medium\">Divider</div><div class=\"text-muted-foreground text-xs\">Visually divide blocks</div></div></DropdownMenuItem><DropdownMenuItem><div class=\"bg-background flex size-8 items-center justify-center rounded-md border\" aria-hidden=\"true\"><Heading1Icon :size=\"16\" class=\"opacity-60\" /></div><div><div class=\"text-sm font-medium\">Heading 1</div><div class=\"text-muted-foreground text-xs\">Big section heading</div></div></DropdownMenuItem><DropdownMenuItem><div class=\"bg-background flex size-8 items-center justify-center rounded-md border\" aria-hidden=\"true\"><Heading2Icon :size=\"16\" class=\"opacity-60\" /></div><div><div class=\"text-sm font-medium\">Heading 2</div><div class=\"text-muted-foreground text-xs\">Medium section subheading</div></div></DropdownMenuItem></DropdownMenuContent></DropdownMenu>\n</template>\n"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-14.html",
          "target": "components/ui/dropdown-14.html",
          "type": "registry:component",
          "content": "<template>\n  <DropdownMenu><DropdownMenuTrigger aschild><Button size=\"icon\" variant=\"ghost\" class=\"rounded-full shadow-none\" aria-label=\"Open edit menu\"><PlusIcon size=\"${16}\" aria-hidden=\"true\" /></Button></DropdownMenuTrigger><DropdownMenuContent class=\"pb-2\"><DropdownMenuLabel>Add block</DropdownMenuLabel><DropdownMenuItem><div class=\"bg-background flex size-8 items-center justify-center rounded-md border\" aria-hidden=\"true\"><TypeIcon size=\"${16}\" class=\"opacity-60\" /></div><div><div class=\"text-sm font-medium\">Text</div><div class=\"text-muted-foreground text-xs\">Start writing with plain text</div></div></DropdownMenuItem><DropdownMenuItem><div class=\"bg-background flex size-8 items-center justify-center rounded-md border\" aria-hidden=\"true\"><TextQuoteIcon size=\"${16}\" class=\"opacity-60\" /></div><div><div class=\"text-sm font-medium\">Quote</div><div class=\"text-muted-foreground text-xs\">Capture a quote</div></div></DropdownMenuItem><DropdownMenuItem><div class=\"bg-background flex size-8 items-center justify-center rounded-md border\" aria-hidden=\"true\"><MinusIcon size=\"${16}\" class=\"opacity-60\" /></div><div><div class=\"text-sm font-medium\">Divider</div><div class=\"text-muted-foreground text-xs\">Visually divide blocks</div></div></DropdownMenuItem><DropdownMenuItem><div class=\"bg-background flex size-8 items-center justify-center rounded-md border\" aria-hidden=\"true\"><Heading1Icon size=\"${16}\" class=\"opacity-60\" /></div><div><div class=\"text-sm font-medium\">Heading 1</div><div class=\"text-muted-foreground text-xs\">Big section heading</div></div></DropdownMenuItem><DropdownMenuItem><div class=\"bg-background flex size-8 items-center justify-center rounded-md border\" aria-hidden=\"true\"><Heading2Icon size=\"${16}\" class=\"opacity-60\" /></div><div><div class=\"text-sm font-medium\">Heading 2</div><div class=\"text-muted-foreground text-xs\">Medium section subheading</div></div></DropdownMenuItem></DropdownMenuContent></DropdownMenu>\n</template>"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-14.wxml",
          "target": "components/ui/dropdown-14/dropdown-14.wxml",
          "type": "registry:component",
          "content": "<view>\n  <dropdownmenu><dropdownmenutrigger aschild><button size=\"icon\" variant=\"ghost\" class=\"rounded-full shadow-none\" aria-label=\"Open edit menu\"><plusicon size=\"{{16}}\" aria-hidden=\"true\" /></button></dropdownmenutrigger><dropdownmenucontent class=\"pb-2\"><dropdownmenulabel>Add block</dropdownmenulabel><dropdownmenuitem><view class=\"bg-background flex size-8 items-center justify-center rounded-md border\" aria-hidden=\"true\"><typeicon size=\"{{16}}\" class=\"opacity-60\" /></view><view><view class=\"text-sm font-medium\">Text</view><view class=\"text-muted-foreground text-xs\">Start writing with plain text</view></view></dropdownmenuitem><dropdownmenuitem><view class=\"bg-background flex size-8 items-center justify-center rounded-md border\" aria-hidden=\"true\"><textquoteicon size=\"{{16}}\" class=\"opacity-60\" /></view><view><view class=\"text-sm font-medium\">Quote</view><view class=\"text-muted-foreground text-xs\">Capture a quote</view></view></dropdownmenuitem><dropdownmenuitem><view class=\"bg-background flex size-8 items-center justify-center rounded-md border\" aria-hidden=\"true\"><minusicon size=\"{{16}}\" class=\"opacity-60\" /></view><view><view class=\"text-sm font-medium\">Divider</view><view class=\"text-muted-foreground text-xs\">Visually divide blocks</view></view></dropdownmenuitem><dropdownmenuitem><view class=\"bg-background flex size-8 items-center justify-center rounded-md border\" aria-hidden=\"true\"><heading1icon size=\"{{16}}\" class=\"opacity-60\" /></view><view><view class=\"text-sm font-medium\">Heading 1</view><view class=\"text-muted-foreground text-xs\">Big section heading</view></view></dropdownmenuitem><dropdownmenuitem><view class=\"bg-background flex size-8 items-center justify-center rounded-md border\" aria-hidden=\"true\"><heading2icon size=\"{{16}}\" class=\"opacity-60\" /></view><view><view class=\"text-sm font-medium\">Heading 2</view><view class=\"text-muted-foreground text-xs\">Medium section subheading</view></view></dropdownmenuitem></dropdownmenucontent></dropdownmenu>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dropdown",
          "text editor",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dropdown-14",
          "group": "dropdown",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dropdown-14",
              "path": "registry/default/components/dropdown/dropdown-14.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dropdown-14",
              "path": "registry/default/components/dropdown/dropdown-14.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dropdown-14",
              "path": "registry/default/components/dropdown/dropdown-14.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dropdown-14",
              "path": "registry/default/components/dropdown/dropdown-14.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dropdown",
        "title": "Dropdown · Open edit menu"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "dropdown"
      ]
    },
    {
      "name": "dropdown-15",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dropdown-menu.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/dropdown/dropdown-15.tsx",
          "type": "registry:component",
          "target": "components/ui/dropdown-15.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport {\n  Button,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuTrigger,\n} from '@timui/react'\nimport { MonitorIcon, MoonIcon, SunIcon } from 'lucide-react'\n\ntype Theme = 'light' | 'dark' | 'system'\n\nexport default function Component() {\n  const [theme, setTheme] = useState<Theme>('system')\n\n  // For demo purposes, we'll simulate system preference as \"light\"\n  const systemPreference = 'light'\n  const displayTheme = theme === 'system' ? systemPreference : theme\n\n  return (\n    <div>\n      <DropdownMenu>\n        <DropdownMenuTrigger asChild>\n          <Button size=\"icon\" variant=\"outline\" aria-label=\"Select theme\">\n            {displayTheme === 'light' && <SunIcon size={16} aria-hidden=\"true\" />}\n            {displayTheme === 'dark' && <MoonIcon size={16} aria-hidden=\"true\" />}\n          </Button>\n        </DropdownMenuTrigger>\n        <DropdownMenuContent className=\"min-w-32\">\n          <DropdownMenuItem onClick={() => setTheme('light')}>\n            <SunIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Light</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem onClick={() => setTheme('dark')}>\n            <MoonIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Dark</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem onClick={() => setTheme('system')}>\n            <MonitorIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>System</span>\n          </DropdownMenuItem>\n        </DropdownMenuContent>\n      </DropdownMenu>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-15.vue",
          "target": "components/ui/dropdown-15.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { MonitorIcon, MoonIcon, SunIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@timui/vue';\n\n\n\nconst theme = ref<Theme>('system');\n\n\nfunction setTheme(next: typeof theme.value | ((prev: typeof theme.value) => typeof theme.value)) {\n  theme.value = typeof next === 'function'\n    ? (next as (prev: typeof theme.value) => typeof theme.value)(theme.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <div><DropdownMenu><DropdownMenuTrigger as-child><Button size=\"icon\" variant=\"outline\" aria-label=\"Select theme\"><SunIcon v-if=\"displayTheme === 'light'\" :size=\"16\" aria-hidden=\"true\" /><MoonIcon v-if=\"displayTheme === 'dark'\" :size=\"16\" aria-hidden=\"true\" /></Button></DropdownMenuTrigger><DropdownMenuContent class=\"min-w-32\"><DropdownMenuItem @click=\"setTheme('light')\"><SunIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Light</span></DropdownMenuItem><DropdownMenuItem @click=\"setTheme('dark')\"><MoonIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Dark</span></DropdownMenuItem><DropdownMenuItem @click=\"setTheme('system')\"><MonitorIcon :size=\"16\" class=\"opacity-60\" aria-hidden=\"true\" /><span>System</span></DropdownMenuItem></DropdownMenuContent></DropdownMenu></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-15.html",
          "target": "components/ui/dropdown-15.html",
          "type": "registry:component",
          "content": "<template>\n  <div><DropdownMenu><DropdownMenuTrigger aschild><Button size=\"icon\" variant=\"outline\" aria-label=\"Select theme\"><!-- if displayTheme === 'light' -->\n<SunIcon size=\"${16}\" aria-hidden=\"true\" />\n<!-- endif --><!-- if displayTheme === 'dark' -->\n<MoonIcon size=\"${16}\" aria-hidden=\"true\" />\n<!-- endif --></Button></DropdownMenuTrigger><DropdownMenuContent class=\"min-w-32\"><DropdownMenuItem on-click=\"${() => setTheme('light')}\"><SunIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Light</span></DropdownMenuItem><DropdownMenuItem on-click=\"${() => setTheme('dark')}\"><MoonIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" /><span>Dark</span></DropdownMenuItem><DropdownMenuItem on-click=\"${() => setTheme('system')}\"><MonitorIcon size=\"${16}\" class=\"opacity-60\" aria-hidden=\"true\" /><span>System</span></DropdownMenuItem></DropdownMenuContent></DropdownMenu></div>\n</template>"
        },
        {
          "path": "registry/default/components/dropdown/dropdown-15.wxml",
          "target": "components/ui/dropdown-15/dropdown-15.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><dropdownmenu><dropdownmenutrigger aschild><button size=\"icon\" variant=\"outline\" aria-label=\"Select theme\"><sunicon wx:if=\"{{displayTheme === 'light'}}\" size=\"{{16}}\" aria-hidden=\"true\" /><moonicon wx:if=\"{{displayTheme === 'dark'}}\" size=\"{{16}}\" aria-hidden=\"true\" /></button></dropdownmenutrigger><dropdownmenucontent class=\"min-w-32\"><dropdownmenuitem bindtap=\"setTheme('light')\"><sunicon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" /><text>Light</text></dropdownmenuitem><dropdownmenuitem bindtap=\"setTheme('dark')\"><moonicon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" /><text>Dark</text></dropdownmenuitem><dropdownmenuitem bindtap=\"setTheme('system')\"><monitoricon size=\"{{16}}\" class=\"opacity-60\" aria-hidden=\"true\" /><text>System</text></dropdownmenuitem></dropdownmenucontent></dropdownmenu></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "dropdown",
          "darkmode",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "dropdown-15",
          "group": "dropdown",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "dropdown-15",
              "path": "registry/default/components/dropdown/dropdown-15.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "dropdown-15",
              "path": "registry/default/components/dropdown/dropdown-15.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "dropdown-15",
              "path": "registry/default/components/dropdown/dropdown-15.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "dropdown-15",
              "path": "registry/default/components/dropdown/dropdown-15.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "dropdown",
        "title": "Dropdown · Select theme"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "dropdown"
      ]
    },
    {
      "name": "popover-01",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/checkbox.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/popover.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/popover/popover-01.tsx",
          "type": "registry:component",
          "target": "components/ui/popover-01.tsx",
          "content": "import { useId } from 'react'\nimport { Button, Checkbox, Label, Popover, PopoverContent, PopoverTrigger } from '@timui/react'\nimport { ListFilterIcon } from 'lucide-react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"flex flex-col gap-4\">\n      <Popover>\n        <PopoverTrigger asChild>\n          <Button variant=\"outline\" size=\"icon\" aria-label=\"Filters\">\n            <ListFilterIcon size={16} aria-hidden=\"true\" />\n          </Button>\n        </PopoverTrigger>\n        <PopoverContent className=\"w-36 p-3\">\n          <div className=\"space-y-3\">\n            <div className=\"text-muted-foreground text-xs font-medium\">Filters</div>\n            <form>\n              <div className=\"space-y-3\">\n                <div className=\"flex items-center gap-2\">\n                  <Checkbox id={`${id}-1`} />\n                  <Label htmlFor={`${id}-1`} className=\"font-normal\">\n                    Real Time\n                  </Label>\n                </div>\n                <div className=\"flex items-center gap-2\">\n                  <Checkbox id={`${id}-2`} />\n                  <Label htmlFor={`${id}-2`} className=\"font-normal\">\n                    Top Channels\n                  </Label>\n                </div>\n                <div className=\"flex items-center gap-2\">\n                  <Checkbox id={`${id}-3`} />\n                  <Label htmlFor={`${id}-3`} className=\"font-normal\">\n                    Last Orders\n                  </Label>\n                </div>\n                <div className=\"flex items-center gap-2\">\n                  <Checkbox id={`${id}-4`} />\n                  <Label htmlFor={`${id}-4`} className=\"font-normal\">\n                    Total Spent\n                  </Label>\n                </div>\n              </div>\n              <div\n                role=\"separator\"\n                aria-orientation=\"horizontal\"\n                className=\"bg-border -mx-3 my-3 h-px\"\n              ></div>\n              <div className=\"flex justify-between gap-2\">\n                <Button size=\"sm\" variant=\"outline\" className=\"h-7 px-2\">\n                  Clear\n                </Button>\n                <Button size=\"sm\" className=\"h-7 px-2\">\n                  Apply\n                </Button>\n              </div>\n            </form>\n          </div>\n        </PopoverContent>\n      </Popover>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/popover/popover-01.vue",
          "target": "components/ui/popover-01.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ListFilterIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { Checkbox } from '@timui/vue';\nimport { Label } from '@timui/vue';\nimport { Popover, PopoverContent, PopoverTrigger } from '@timui/vue';\n\n\n\n\n\nconst id = 'popover-01';\n\n</script>\n\n<template>\n  <div class=\"flex flex-col gap-4\"><Popover><PopoverTrigger as-child><Button variant=\"outline\" size=\"icon\" aria-label=\"Filters\"><ListFilterIcon :size=\"16\" aria-hidden=\"true\" /></Button></PopoverTrigger><PopoverContent class=\"w-36 p-3\"><div class=\"space-y-3\"><div class=\"text-muted-foreground text-xs font-medium\">Filters</div><form><div class=\"space-y-3\"><div class=\"flex items-center gap-2\"><Checkbox :id=\"`${id}-1`\" /><Label :htmlFor=\"`${id}-1`\" class=\"font-normal\">Real Time\n                  </Label></div><div class=\"flex items-center gap-2\"><Checkbox :id=\"`${id}-2`\" /><Label :htmlFor=\"`${id}-2`\" class=\"font-normal\">Top Channels\n                  </Label></div><div class=\"flex items-center gap-2\"><Checkbox :id=\"`${id}-3`\" /><Label :htmlFor=\"`${id}-3`\" class=\"font-normal\">Last Orders\n                  </Label></div><div class=\"flex items-center gap-2\"><Checkbox :id=\"`${id}-4`\" /><Label :htmlFor=\"`${id}-4`\" class=\"font-normal\">Total Spent\n                  </Label></div></div><div role=\"separator\" aria-orientation=\"horizontal\" class=\"bg-border -mx-3 my-3 h-px\"></div><div class=\"flex justify-between gap-2\"><Button size=\"sm\" variant=\"outline\" class=\"h-7 px-2\">Clear\n                </Button><Button size=\"sm\" class=\"h-7 px-2\">Apply\n                </Button></div></form></div></PopoverContent></Popover></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/popover/popover-01.html",
          "target": "components/ui/popover-01.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex flex-col gap-4\"><Popover><PopoverTrigger aschild><Button variant=\"outline\" size=\"icon\" aria-label=\"Filters\"><ListFilterIcon size=\"${16}\" aria-hidden=\"true\" /></Button></PopoverTrigger><PopoverContent class=\"w-36 p-3\"><div class=\"space-y-3\"><div class=\"text-muted-foreground text-xs font-medium\">Filters</div><form><div class=\"space-y-3\"><div class=\"flex items-center gap-2\"><Checkbox id=\"${`${id}-1`}\" /><Label htmlfor=\"${`${id}-1`}\" class=\"font-normal\">Real Time\n                  </Label></div><div class=\"flex items-center gap-2\"><Checkbox id=\"${`${id}-2`}\" /><Label htmlfor=\"${`${id}-2`}\" class=\"font-normal\">Top Channels\n                  </Label></div><div class=\"flex items-center gap-2\"><Checkbox id=\"${`${id}-3`}\" /><Label htmlfor=\"${`${id}-3`}\" class=\"font-normal\">Last Orders\n                  </Label></div><div class=\"flex items-center gap-2\"><Checkbox id=\"${`${id}-4`}\" /><Label htmlfor=\"${`${id}-4`}\" class=\"font-normal\">Total Spent\n                  </Label></div></div><div role=\"separator\" aria-orientation=\"horizontal\" class=\"bg-border -mx-3 my-3 h-px\"></div><div class=\"flex justify-between gap-2\"><Button size=\"sm\" variant=\"outline\" class=\"h-7 px-2\">Clear\n                </Button><Button size=\"sm\" class=\"h-7 px-2\">Apply\n                </Button></div></form></div></PopoverContent></Popover></div>\n</template>"
        },
        {
          "path": "registry/default/components/popover/popover-01.wxml",
          "target": "components/ui/popover-01/popover-01.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex flex-col gap-4\"><popover><popovertrigger aschild><button variant=\"outline\" size=\"icon\" aria-label=\"Filters\"><listfiltericon size=\"{{16}}\" aria-hidden=\"true\" /></button></popovertrigger><popovercontent class=\"w-36 p-3\"><view class=\"space-y-3\"><view class=\"text-muted-foreground text-xs font-medium\">Filters</view><form><view class=\"space-y-3\"><view class=\"flex items-center gap-2\"><checkbox id=\"{{`${id}-1`}}\" /><label htmlfor=\"{{`${id}-1`}}\" class=\"font-normal\">Real Time\n                  </label></view><view class=\"flex items-center gap-2\"><checkbox id=\"{{`${id}-2`}}\" /><label htmlfor=\"{{`${id}-2`}}\" class=\"font-normal\">Top Channels\n                  </label></view><view class=\"flex items-center gap-2\"><checkbox id=\"{{`${id}-3`}}\" /><label htmlfor=\"{{`${id}-3`}}\" class=\"font-normal\">Last Orders\n                  </label></view><view class=\"flex items-center gap-2\"><checkbox id=\"{{`${id}-4`}}\" /><label htmlfor=\"{{`${id}-4`}}\" class=\"font-normal\">Total Spent\n                  </label></view></view><view role=\"separator\" aria-orientation=\"horizontal\" class=\"bg-border -mx-3 my-3 h-px\"></view><view class=\"flex justify-between gap-2\"><button size=\"sm\" variant=\"outline\" class=\"h-7 px-2\">Clear\n                </button><button size=\"sm\" class=\"h-7 px-2\">Apply\n                </button></view></form></view></popovercontent></popover></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "popover",
          "filter",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "popover-01",
          "group": "popover",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "popover-01",
              "path": "registry/default/components/popover/popover-01.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "popover-01",
              "path": "registry/default/components/popover/popover-01.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "popover-01",
              "path": "registry/default/components/popover/popover-01.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "popover-01",
              "path": "registry/default/components/popover/popover-01.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "popover",
        "title": "Popover · Real Time"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "popover"
      ]
    },
    {
      "name": "popover-02",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/badge.json",
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/popover.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/popover/popover-02.tsx",
          "type": "registry:component",
          "target": "components/ui/popover-02.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Badge, Button, Popover, PopoverContent, PopoverTrigger } from '@timui/react'\nimport { BellIcon } from 'lucide-react'\n\nconst initialNotifications = [\n  {\n    id: 1,\n    user: 'Chris Tompson',\n    action: 'requested review on',\n    target: 'PR #42: Feature implementation',\n    timestamp: '15 minutes ago',\n    unread: true,\n  },\n  {\n    id: 2,\n    user: 'Emma Davis',\n    action: 'shared',\n    target: 'New component library',\n    timestamp: '45 minutes ago',\n    unread: true,\n  },\n  {\n    id: 3,\n    user: 'James Wilson',\n    action: 'assigned you to',\n    target: 'API integration task',\n    timestamp: '4 hours ago',\n    unread: false,\n  },\n  {\n    id: 4,\n    user: 'Alex Morgan',\n    action: 'replied to your comment in',\n    target: 'Authentication flow',\n    timestamp: '12 hours ago',\n    unread: false,\n  },\n  {\n    id: 5,\n    user: 'Sarah Chen',\n    action: 'commented on',\n    target: 'Dashboard redesign',\n    timestamp: '2 days ago',\n    unread: false,\n  },\n  {\n    id: 6,\n    user: 'Miky Derya',\n    action: 'mentioned you in',\n    target: 'Timkit UI open graph image',\n    timestamp: '2 weeks ago',\n    unread: false,\n  },\n]\n\nfunction Dot({ className }: { className?: string }) {\n  return (\n    <svg\n      width=\"6\"\n      height=\"6\"\n      fill=\"currentColor\"\n      viewBox=\"0 0 6 6\"\n      xmlns=\"http://www.w3.org/2000/svg\"\n      className={className}\n      aria-hidden=\"true\"\n    >\n      <circle cx=\"3\" cy=\"3\" r=\"3\" />\n    </svg>\n  )\n}\n\nexport default function Component() {\n  const [notifications, setNotifications] = useState(initialNotifications)\n  const unreadCount = notifications.filter((n) => n.unread).length\n\n  const handleMarkAllAsRead = () => {\n    setNotifications(\n      notifications.map((notification) => ({\n        ...notification,\n        unread: false,\n      }))\n    )\n  }\n\n  const handleNotificationClick = (id: number) => {\n    setNotifications(\n      notifications.map((notification) =>\n        notification.id === id ? { ...notification, unread: false } : notification\n      )\n    )\n  }\n\n  return (\n    <Popover>\n      <PopoverTrigger asChild>\n        <Button size=\"icon\" variant=\"outline\" className=\"relative\" aria-label=\"Open notifications\">\n          <BellIcon size={16} aria-hidden=\"true\" />\n          {unreadCount > 0 && (\n            <Badge className=\"absolute -top-2 left-full min-w-5 -translate-x-1/2 px-1\">\n              {unreadCount > 99 ? '99+' : unreadCount}\n            </Badge>\n          )}\n        </Button>\n      </PopoverTrigger>\n      <PopoverContent className=\"w-80 p-1\">\n        <div className=\"flex items-baseline justify-between gap-4 px-3 py-2\">\n          <div className=\"text-sm font-semibold\">Notifications</div>\n          {unreadCount > 0 && (\n            <button className=\"text-xs font-medium hover:underline\" onClick={handleMarkAllAsRead}>\n              Mark all as read\n            </button>\n          )}\n        </div>\n        <div\n          role=\"separator\"\n          aria-orientation=\"horizontal\"\n          className=\"bg-border -mx-1 my-1 h-px\"\n        ></div>\n        {notifications.map((notification) => (\n          <div\n            key={notification.id}\n            className=\"hover:bg-accent rounded-md px-3 py-2 text-sm transition-colors\"\n          >\n            <div className=\"relative flex items-start pe-3\">\n              <div className=\"flex-1 space-y-1\">\n                <button\n                  className=\"text-foreground/80 text-left after:absolute after:inset-0\"\n                  onClick={() => handleNotificationClick(notification.id)}\n                >\n                  <span className=\"text-foreground font-medium hover:underline\">\n                    {notification.user}\n                  </span>{' '}\n                  {notification.action}{' '}\n                  <span className=\"text-foreground font-medium hover:underline\">\n                    {notification.target}\n                  </span>\n                  .\n                </button>\n                <div className=\"text-muted-foreground text-xs\">{notification.timestamp}</div>\n              </div>\n              {notification.unread && (\n                <div className=\"absolute end-0 self-center\">\n                  <span className=\"sr-only\">Unread</span>\n                  <Dot />\n                </div>\n              )}\n            </div>\n          </div>\n        ))}\n      </PopoverContent>\n    </Popover>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/popover/popover-02.vue",
          "target": "components/ui/popover-02.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport { BellIcon } from 'lucide-vue-next'\nimport { Badge } from '@timui/vue'\nimport { Button } from '@timui/vue'\nimport { Popover, PopoverContent, PopoverTrigger } from '@timui/vue'\n\ntype NotificationItem = {\n  id: number\n  user: string\n  action: string\n  target: string\n  timestamp: string\n  unread: boolean\n}\n\nconst notifications = ref<NotificationItem[]>([\n  {\n    id: 1,\n    user: 'Chris Tompson',\n    action: 'requested review on',\n    target: 'PR #42: Feature implementation',\n    timestamp: '15 minutes ago',\n    unread: true,\n  },\n  {\n    id: 2,\n    user: 'Emma Davis',\n    action: 'shared',\n    target: 'New component library',\n    timestamp: '45 minutes ago',\n    unread: true,\n  },\n  {\n    id: 3,\n    user: 'James Wilson',\n    action: 'assigned you to',\n    target: 'API integration task',\n    timestamp: '4 hours ago',\n    unread: false,\n  },\n  {\n    id: 4,\n    user: 'Alex Morgan',\n    action: 'replied to your comment in',\n    target: 'Authentication flow',\n    timestamp: '12 hours ago',\n    unread: false,\n  },\n  {\n    id: 5,\n    user: 'Sarah Chen',\n    action: 'commented on',\n    target: 'Dashboard redesign',\n    timestamp: '2 days ago',\n    unread: false,\n  },\n  {\n    id: 6,\n    user: 'Miky Derya',\n    action: 'mentioned you in',\n    target: 'Timkit UI open graph image',\n    timestamp: '2 weeks ago',\n    unread: false,\n  },\n])\n\nconst unreadCount = computed(() => notifications.value.filter((n) => n.unread).length)\n\nconst handleMarkAllAsRead = () => {\n  notifications.value = notifications.value.map((n) => ({ ...n, unread: false }))\n}\n\nconst handleNotificationClick = (id: number) => {\n  notifications.value = notifications.value.map((n) =>\n    n.id === id ? { ...n, unread: false } : n\n  )\n}\n</script>\n\n<template>\n  <Popover>\n    <PopoverTrigger as-child>\n      <Button size=\"icon\" variant=\"outline\" class=\"relative\" aria-label=\"Open notifications\">\n        <BellIcon :size=\"16\" aria-hidden=\"true\" />\n        <Badge v-if=\"unreadCount > 0\" class=\"absolute -top-2 left-full min-w-5 -translate-x-1/2 px-1\">\n          {{ unreadCount > 99 ? '99+' : unreadCount }}\n        </Badge>\n      </Button>\n    </PopoverTrigger>\n    <PopoverContent class=\"w-80 p-1\">\n      <div class=\"flex items-baseline justify-between gap-4 px-3 py-2\">\n        <div class=\"text-sm font-semibold\">Notifications</div>\n        <button v-if=\"unreadCount > 0\" class=\"text-xs font-medium hover:underline\" @click=\"handleMarkAllAsRead\">\n          Mark all as read\n        </button>\n      </div>\n      <div role=\"separator\" aria-orientation=\"horizontal\" class=\"bg-border -mx-1 my-1 h-px\" />\n      <div\n        v-for=\"notification in notifications\"\n        :key=\"notification.id\"\n        class=\"hover:bg-accent rounded-md px-3 py-2 text-sm transition-colors\"\n      >\n        <div class=\"relative flex items-start pe-3\">\n          <div class=\"flex-1 space-y-1\">\n            <button\n              class=\"text-foreground/80 text-left after:absolute after:inset-0\"\n              @click=\"handleNotificationClick(notification.id)\"\n            >\n              <span class=\"text-foreground font-medium hover:underline\">{{ notification.user }}</span>\n              {{ ' ' }}{{ notification.action }}{{ ' ' }}\n              <span class=\"text-foreground font-medium hover:underline\">{{ notification.target }}</span>.\n            </button>\n            <div class=\"text-muted-foreground text-xs\">{{ notification.timestamp }}</div>\n          </div>\n          <div v-if=\"notification.unread\" class=\"absolute end-0 self-center\">\n            <span class=\"sr-only\">Unread</span>\n            <svg width=\"6\" height=\"6\" fill=\"currentColor\" viewBox=\"0 0 6 6\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n              <circle cx=\"3\" cy=\"3\" r=\"3\" />\n            </svg>\n          </div>\n        </div>\n      </div>\n    </PopoverContent>\n  </Popover>\n</template>\n"
        },
        {
          "path": "registry/default/components/popover/popover-02.html",
          "target": "components/ui/popover-02.html",
          "type": "registry:component",
          "content": "<template>\n  <Popover><PopoverTrigger aschild><Button size=\"icon\" variant=\"outline\" class=\"relative\" aria-label=\"Open notifications\"><BellIcon size=\"${16}\" aria-hidden=\"true\" /><!-- if unreadCount > 0 -->\n<Badge class=\"absolute -top-2 left-full min-w-5 -translate-x-1/2 px-1\"><!-- if unreadCount > 99 -->\n${'99+'}\n<!-- else -->\n${unreadCount}\n<!-- endif --></Badge>\n<!-- endif --></Button></PopoverTrigger><PopoverContent class=\"w-80 p-1\"><div class=\"flex items-baseline justify-between gap-4 px-3 py-2\"><div class=\"text-sm font-semibold\">Notifications</div><!-- if unreadCount > 0 -->\n<button class=\"text-xs font-medium hover:underline\" on-click=\"${handleMarkAllAsRead}\">Mark all as read\n            </button>\n<!-- endif --></div><div role=\"separator\" aria-orientation=\"horizontal\" class=\"bg-border -mx-1 my-1 h-px\"></div><!-- Loop notifications -->\n<div key=\"${notification.id}\" class=\"hover:bg-accent rounded-md px-3 py-2 text-sm transition-colors\"><div class=\"relative flex items-start pe-3\"><div class=\"flex-1 space-y-1\"><button class=\"text-foreground/80 text-left after:absolute after:inset-0\" on-click=\"${() => handleNotificationClick(notification.id)}\"><span class=\"text-foreground font-medium hover:underline\">${notification.user}</span>${' '}${notification.action}${' '}<span class=\"text-foreground font-medium hover:underline\">${notification.target}</span>.\n                </button><div class=\"text-muted-foreground text-xs\">${notification.timestamp}</div></div><!-- if notification.unread -->\n<div class=\"absolute end-0 self-center\"><span class=\"sr-only\">Unread</span><Dot /></div>\n<!-- endif --></div></div>\n<!-- End Loop --></PopoverContent></Popover>\n</template>"
        },
        {
          "path": "registry/default/components/popover/popover-02.wxml",
          "target": "components/ui/popover-02/popover-02.wxml",
          "type": "registry:component",
          "content": "<view>\n  <popover><popovertrigger aschild><button size=\"icon\" variant=\"outline\" class=\"relative\" aria-label=\"Open notifications\"><bellicon size=\"{{16}}\" aria-hidden=\"true\" /><badge wx:if=\"{{unreadCount > 0}}\" class=\"absolute -top-2 left-full min-w-5 -translate-x-1/2 px-1\"><block wx:if=\"{{unreadCount > 99}}\">\n{{ '99+' }}\n</block>\n<block wx:else>\n{{ unreadCount }}\n</block></badge></button></popovertrigger><popovercontent class=\"w-80 p-1\"><view class=\"flex items-baseline justify-between gap-4 px-3 py-2\"><view class=\"text-sm font-semibold\">Notifications</view><button wx:if=\"{{unreadCount > 0}}\" class=\"text-xs font-medium hover:underline\" bindtap=\"handleMarkAllAsRead\">Mark all as read\n            </button></view><view role=\"separator\" aria-orientation=\"horizontal\" class=\"bg-border -mx-1 my-1 h-px\"></view><view wx:for=\"{{notifications}}\" wx:for-item=\"notification\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{notification.id}}\" class=\"hover:bg-accent rounded-md px-3 py-2 text-sm transition-colors\"><view class=\"relative flex items-start pe-3\"><view class=\"flex-1 space-y-1\"><button class=\"text-foreground/80 text-left after:absolute after:inset-0\" bindtap=\"handleNotificationClick(notification.id)\"><text class=\"text-foreground font-medium hover:underline\">{{ notification.user }}</text>{{ ' ' }}{{ notification.action }}{{ ' ' }}<text class=\"text-foreground font-medium hover:underline\">{{ notification.target }}</text>.\n                </button><view class=\"text-muted-foreground text-xs\">{{ notification.timestamp }}</view></view><view wx:if=\"{{notification.unread}}\" class=\"absolute end-0 self-center\"><text class=\"sr-only\">Unread</text><dot /></view></view></view></popovercontent></popover>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "popover",
          "notification",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "popover-02",
          "group": "popover",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "popover-02",
              "path": "registry/default/components/popover/popover-02.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "popover-02",
              "path": "registry/default/components/popover/popover-02.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "popover-02",
              "path": "registry/default/components/popover/popover-02.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "popover-02",
              "path": "registry/default/components/popover/popover-02.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "popover",
        "title": "Popover · Open notifications"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "popover"
      ]
    },
    {
      "name": "popover-03",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/badge.json",
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/popover.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/popover/popover-03.tsx",
          "type": "registry:component",
          "target": "components/ui/popover-03.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Badge, Button, Popover, PopoverContent, PopoverTrigger } from '@timui/react'\nimport { BellIcon } from 'lucide-react'\n\nconst initialNotifications = [\n  {\n    id: 1,\n    image: '/avatar-80-01.jpg',\n    user: 'Chris Tompson',\n    action: 'requested review on',\n    target: 'PR #42: Feature implementation',\n    timestamp: '15 minutes ago',\n    unread: true,\n  },\n  {\n    id: 2,\n    image: '/avatar-80-02.jpg',\n    user: 'Emma Davis',\n    action: 'shared',\n    target: 'New component library',\n    timestamp: '45 minutes ago',\n    unread: true,\n  },\n  {\n    id: 3,\n    image: '/avatar-80-03.jpg',\n    user: 'James Wilson',\n    action: 'assigned you to',\n    target: 'API integration task',\n    timestamp: '4 hours ago',\n    unread: false,\n  },\n  {\n    id: 4,\n    image: '/avatar-80-04.jpg',\n    user: 'Alex Morgan',\n    action: 'replied to your comment in',\n    target: 'Authentication flow',\n    timestamp: '12 hours ago',\n    unread: false,\n  },\n  {\n    id: 5,\n    image: '/avatar-80-05.jpg',\n    user: 'Sarah Chen',\n    action: 'commented on',\n    target: 'Dashboard redesign',\n    timestamp: '2 days ago',\n    unread: false,\n  },\n  {\n    id: 6,\n    image: '/avatar-80-06.jpg',\n    user: 'Miky Derya',\n    action: 'mentioned you in',\n    target: 'Timkit UI open graph image',\n    timestamp: '2 weeks ago',\n    unread: false,\n  },\n]\n\nfunction Dot({ className }: { className?: string }) {\n  return (\n    <svg\n      width=\"6\"\n      height=\"6\"\n      fill=\"currentColor\"\n      viewBox=\"0 0 6 6\"\n      xmlns=\"http://www.w3.org/2000/svg\"\n      className={className}\n      aria-hidden=\"true\"\n    >\n      <circle cx=\"3\" cy=\"3\" r=\"3\" />\n    </svg>\n  )\n}\n\nexport default function Component() {\n  const [notifications, setNotifications] = useState(initialNotifications)\n  const unreadCount = notifications.filter((n) => n.unread).length\n\n  const handleMarkAllAsRead = () => {\n    setNotifications(\n      notifications.map((notification) => ({\n        ...notification,\n        unread: false,\n      }))\n    )\n  }\n\n  const handleNotificationClick = (id: number) => {\n    setNotifications(\n      notifications.map((notification) =>\n        notification.id === id ? { ...notification, unread: false } : notification\n      )\n    )\n  }\n\n  return (\n    <Popover>\n      <PopoverTrigger asChild>\n        <Button size=\"icon\" variant=\"outline\" className=\"relative\" aria-label=\"Open notifications\">\n          <BellIcon size={16} aria-hidden=\"true\" />\n          {unreadCount > 0 && (\n            <Badge className=\"absolute -top-2 left-full min-w-5 -translate-x-1/2 px-1\">\n              {unreadCount > 99 ? '99+' : unreadCount}\n            </Badge>\n          )}\n        </Button>\n      </PopoverTrigger>\n      <PopoverContent className=\"w-80 p-1\">\n        <div className=\"flex items-baseline justify-between gap-4 px-3 py-2\">\n          <div className=\"text-sm font-semibold\">Notifications</div>\n          {unreadCount > 0 && (\n            <button className=\"text-xs font-medium hover:underline\" onClick={handleMarkAllAsRead}>\n              Mark all as read\n            </button>\n          )}\n        </div>\n        <div\n          role=\"separator\"\n          aria-orientation=\"horizontal\"\n          className=\"bg-border -mx-1 my-1 h-px\"\n        ></div>\n        {notifications.map((notification) => (\n          <div\n            key={notification.id}\n            className=\"hover:bg-accent rounded-md px-3 py-2 text-sm transition-colors\"\n          >\n            <div className=\"relative flex items-start gap-3 pe-3\">\n              <img\n                className=\"size-9 rounded-md\"\n                src={notification.image}\n                width={32}\n                height={32}\n                alt={notification.user}\n              />\n              <div className=\"flex-1 space-y-1\">\n                <button\n                  className=\"text-foreground/80 text-left after:absolute after:inset-0\"\n                  onClick={() => handleNotificationClick(notification.id)}\n                >\n                  <span className=\"text-foreground font-medium hover:underline\">\n                    {notification.user}\n                  </span>{' '}\n                  {notification.action}{' '}\n                  <span className=\"text-foreground font-medium hover:underline\">\n                    {notification.target}\n                  </span>\n                  .\n                </button>\n                <div className=\"text-muted-foreground text-xs\">{notification.timestamp}</div>\n              </div>\n              {notification.unread && (\n                <div className=\"absolute end-0 self-center\">\n                  <Dot />\n                </div>\n              )}\n            </div>\n          </div>\n        ))}\n      </PopoverContent>\n    </Popover>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/popover/popover-03.vue",
          "target": "components/ui/popover-03.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport { BellIcon } from 'lucide-vue-next'\nimport { Badge } from '@timui/vue'\nimport { Button } from '@timui/vue'\nimport { Popover, PopoverContent, PopoverTrigger } from '@timui/vue'\n\ntype NotificationItem = {\n  id: number\n  image: string\n  user: string\n  action: string\n  target: string\n  timestamp: string\n  unread: boolean\n}\n\nconst notifications = ref<NotificationItem[]>([\n  {\n    id: 1,\n    image: '/avatar-80-01.jpg',\n    user: 'Chris Tompson',\n    action: 'requested review on',\n    target: 'PR #42: Feature implementation',\n    timestamp: '15 minutes ago',\n    unread: true,\n  },\n  {\n    id: 2,\n    image: '/avatar-80-02.jpg',\n    user: 'Emma Davis',\n    action: 'shared',\n    target: 'New component library',\n    timestamp: '45 minutes ago',\n    unread: true,\n  },\n  {\n    id: 3,\n    image: '/avatar-80-03.jpg',\n    user: 'James Wilson',\n    action: 'assigned you to',\n    target: 'API integration task',\n    timestamp: '4 hours ago',\n    unread: false,\n  },\n  {\n    id: 4,\n    image: '/avatar-80-04.jpg',\n    user: 'Alex Morgan',\n    action: 'replied to your comment in',\n    target: 'Authentication flow',\n    timestamp: '12 hours ago',\n    unread: false,\n  },\n  {\n    id: 5,\n    image: '/avatar-80-05.jpg',\n    user: 'Sarah Chen',\n    action: 'commented on',\n    target: 'Dashboard redesign',\n    timestamp: '2 days ago',\n    unread: false,\n  },\n  {\n    id: 6,\n    image: '/avatar-80-06.jpg',\n    user: 'Miky Derya',\n    action: 'mentioned you in',\n    target: 'Timkit UI open graph image',\n    timestamp: '2 weeks ago',\n    unread: false,\n  },\n])\n\nconst unreadCount = computed(() => notifications.value.filter((n) => n.unread).length)\n\nconst handleMarkAllAsRead = () => {\n  notifications.value = notifications.value.map((n) => ({ ...n, unread: false }))\n}\n\nconst handleNotificationClick = (id: number) => {\n  notifications.value = notifications.value.map((n) =>\n    n.id === id ? { ...n, unread: false } : n\n  )\n}\n</script>\n\n<template>\n  <Popover>\n    <PopoverTrigger as-child>\n      <Button size=\"icon\" variant=\"outline\" class=\"relative\" aria-label=\"Open notifications\">\n        <BellIcon :size=\"16\" aria-hidden=\"true\" />\n        <Badge v-if=\"unreadCount > 0\" class=\"absolute -top-2 left-full min-w-5 -translate-x-1/2 px-1\">\n          {{ unreadCount > 99 ? '99+' : unreadCount }}\n        </Badge>\n      </Button>\n    </PopoverTrigger>\n    <PopoverContent class=\"w-80 p-1\">\n      <div class=\"flex items-baseline justify-between gap-4 px-3 py-2\">\n        <div class=\"text-sm font-semibold\">Notifications</div>\n        <button v-if=\"unreadCount > 0\" class=\"text-xs font-medium hover:underline\" @click=\"handleMarkAllAsRead\">\n          Mark all as read\n        </button>\n      </div>\n      <div role=\"separator\" aria-orientation=\"horizontal\" class=\"bg-border -mx-1 my-1 h-px\" />\n      <div\n        v-for=\"notification in notifications\"\n        :key=\"notification.id\"\n        class=\"hover:bg-accent rounded-md px-3 py-2 text-sm transition-colors\"\n      >\n        <div class=\"relative flex items-start gap-3 pe-3\">\n          <img class=\"size-9 rounded-md\" :src=\"notification.image\" :width=\"32\" :height=\"32\" :alt=\"notification.user\" />\n          <div class=\"flex-1 space-y-1\">\n            <button\n              class=\"text-foreground/80 text-left after:absolute after:inset-0\"\n              @click=\"handleNotificationClick(notification.id)\"\n            >\n              <span class=\"text-foreground font-medium hover:underline\">{{ notification.user }}</span>\n              {{ ' ' }}{{ notification.action }}{{ ' ' }}\n              <span class=\"text-foreground font-medium hover:underline\">{{ notification.target }}</span>.\n            </button>\n            <div class=\"text-muted-foreground text-xs\">{{ notification.timestamp }}</div>\n          </div>\n          <div v-if=\"notification.unread\" class=\"absolute end-0 self-center\">\n            <svg width=\"6\" height=\"6\" fill=\"currentColor\" viewBox=\"0 0 6 6\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n              <circle cx=\"3\" cy=\"3\" r=\"3\" />\n            </svg>\n          </div>\n        </div>\n      </div>\n    </PopoverContent>\n  </Popover>\n</template>\n"
        },
        {
          "path": "registry/default/components/popover/popover-03.html",
          "target": "components/ui/popover-03.html",
          "type": "registry:component",
          "content": "<template>\n  <Popover><PopoverTrigger aschild><Button size=\"icon\" variant=\"outline\" class=\"relative\" aria-label=\"Open notifications\"><BellIcon size=\"${16}\" aria-hidden=\"true\" /><!-- if unreadCount > 0 -->\n<Badge class=\"absolute -top-2 left-full min-w-5 -translate-x-1/2 px-1\"><!-- if unreadCount > 99 -->\n${'99+'}\n<!-- else -->\n${unreadCount}\n<!-- endif --></Badge>\n<!-- endif --></Button></PopoverTrigger><PopoverContent class=\"w-80 p-1\"><div class=\"flex items-baseline justify-between gap-4 px-3 py-2\"><div class=\"text-sm font-semibold\">Notifications</div><!-- if unreadCount > 0 -->\n<button class=\"text-xs font-medium hover:underline\" on-click=\"${handleMarkAllAsRead}\">Mark all as read\n            </button>\n<!-- endif --></div><div role=\"separator\" aria-orientation=\"horizontal\" class=\"bg-border -mx-1 my-1 h-px\"></div><!-- Loop notifications -->\n<div key=\"${notification.id}\" class=\"hover:bg-accent rounded-md px-3 py-2 text-sm transition-colors\"><div class=\"relative flex items-start gap-3 pe-3\"><img class=\"size-9 rounded-md\" src=\"${notification.image}\" width=\"${32}\" height=\"${32}\" alt=\"${notification.user}\" /><div class=\"flex-1 space-y-1\"><button class=\"text-foreground/80 text-left after:absolute after:inset-0\" on-click=\"${() => handleNotificationClick(notification.id)}\"><span class=\"text-foreground font-medium hover:underline\">${notification.user}</span>${' '}${notification.action}${' '}<span class=\"text-foreground font-medium hover:underline\">${notification.target}</span>.\n                </button><div class=\"text-muted-foreground text-xs\">${notification.timestamp}</div></div><!-- if notification.unread -->\n<div class=\"absolute end-0 self-center\"><Dot /></div>\n<!-- endif --></div></div>\n<!-- End Loop --></PopoverContent></Popover>\n</template>"
        },
        {
          "path": "registry/default/components/popover/popover-03.wxml",
          "target": "components/ui/popover-03/popover-03.wxml",
          "type": "registry:component",
          "content": "<view>\n  <popover><popovertrigger aschild><button size=\"icon\" variant=\"outline\" class=\"relative\" aria-label=\"Open notifications\"><bellicon size=\"{{16}}\" aria-hidden=\"true\" /><badge wx:if=\"{{unreadCount > 0}}\" class=\"absolute -top-2 left-full min-w-5 -translate-x-1/2 px-1\"><block wx:if=\"{{unreadCount > 99}}\">\n{{ '99+' }}\n</block>\n<block wx:else>\n{{ unreadCount }}\n</block></badge></button></popovertrigger><popovercontent class=\"w-80 p-1\"><view class=\"flex items-baseline justify-between gap-4 px-3 py-2\"><view class=\"text-sm font-semibold\">Notifications</view><button wx:if=\"{{unreadCount > 0}}\" class=\"text-xs font-medium hover:underline\" bindtap=\"handleMarkAllAsRead\">Mark all as read\n            </button></view><view role=\"separator\" aria-orientation=\"horizontal\" class=\"bg-border -mx-1 my-1 h-px\"></view><view wx:for=\"{{notifications}}\" wx:for-item=\"notification\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{notification.id}}\" class=\"hover:bg-accent rounded-md px-3 py-2 text-sm transition-colors\"><view class=\"relative flex items-start gap-3 pe-3\"><image class=\"size-9 rounded-md\" src=\"{{notification.image}}\" width=\"{{32}}\" height=\"{{32}}\" alt=\"{{notification.user}}\" /><view class=\"flex-1 space-y-1\"><button class=\"text-foreground/80 text-left after:absolute after:inset-0\" bindtap=\"handleNotificationClick(notification.id)\"><text class=\"text-foreground font-medium hover:underline\">{{ notification.user }}</text>{{ ' ' }}{{ notification.action }}{{ ' ' }}<text class=\"text-foreground font-medium hover:underline\">{{ notification.target }}</text>.\n                </button><view class=\"text-muted-foreground text-xs\">{{ notification.timestamp }}</view></view><view wx:if=\"{{notification.unread}}\" class=\"absolute end-0 self-center\"><dot /></view></view></view></popovercontent></popover>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "popover",
          "notification",
          "user",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "popover-03",
          "group": "popover",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "popover-03",
              "path": "registry/default/components/popover/popover-03.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "popover-03",
              "path": "registry/default/components/popover/popover-03.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "popover-03",
              "path": "registry/default/components/popover/popover-03.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "popover-03",
              "path": "registry/default/components/popover/popover-03.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "popover",
        "title": "Popover · Open notifications"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "popover"
      ]
    },
    {
      "name": "popover-04",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/popover.json"
      ],
      "files": [
        {
          "path": "registry/default/components/popover/popover-04.tsx",
          "type": "registry:component",
          "target": "components/ui/popover-04.tsx",
          "content": "import { Button, Popover, PopoverContent, PopoverTrigger } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Popover>\n      <PopoverTrigger asChild>\n        <Button variant=\"outline\">Tooltip-like popover</Button>\n      </PopoverTrigger>\n      <PopoverContent className=\"max-w-[280px] py-3 shadow-none\" side=\"top\">\n        <div className=\"space-y-3\">\n          <div className=\"space-y-1\">\n            <p className=\"text-[13px] font-medium\">Popover with button</p>\n            <p className=\"text-muted-foreground text-xs\">\n              I am a popover that would like to look like a tooltip. I can&lsquo;t be a tooltip\n              because of the interactive element inside me.\n            </p>\n          </div>\n          <Button size=\"sm\" className=\"h-7 px-2\">\n            Know more\n          </Button>\n        </div>\n      </PopoverContent>\n    </Popover>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/popover/popover-04.vue",
          "target": "components/ui/popover-04.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\nimport { Popover, PopoverContent, PopoverTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Popover><PopoverTrigger as-child><Button variant=\"outline\">Tooltip-like popover</Button></PopoverTrigger><PopoverContent class=\"max-w-[280px] py-3 shadow-none\" side=\"top\"><div class=\"space-y-3\"><div class=\"space-y-1\"><p class=\"text-[13px] font-medium\">Popover with button</p><p class=\"text-muted-foreground text-xs\">I am a popover that would like to look like a tooltip. I can&lsquo;t be a tooltip\n              because of the interactive element inside me.\n            </p></div><Button size=\"sm\" class=\"h-7 px-2\">Know more\n          </Button></div></PopoverContent></Popover>\n</template>\n"
        },
        {
          "path": "registry/default/components/popover/popover-04.html",
          "target": "components/ui/popover-04.html",
          "type": "registry:component",
          "content": "<template>\n  <Popover><PopoverTrigger aschild><Button variant=\"outline\">Tooltip-like popover</Button></PopoverTrigger><PopoverContent class=\"max-w-[280px] py-3 shadow-none\" side=\"top\"><div class=\"space-y-3\"><div class=\"space-y-1\"><p class=\"text-[13px] font-medium\">Popover with button</p><p class=\"text-muted-foreground text-xs\">I am a popover that would like to look like a tooltip. I can&lsquo;t be a tooltip\n              because of the interactive element inside me.\n            </p></div><Button size=\"sm\" class=\"h-7 px-2\">Know more\n          </Button></div></PopoverContent></Popover>\n</template>"
        },
        {
          "path": "registry/default/components/popover/popover-04.wxml",
          "target": "components/ui/popover-04/popover-04.wxml",
          "type": "registry:component",
          "content": "<view>\n  <popover><popovertrigger aschild><button variant=\"outline\">Tooltip-like popover</button></popovertrigger><popovercontent class=\"max-w-[280px] py-3 shadow-none\" side=\"top\"><view class=\"space-y-3\"><view class=\"space-y-1\"><text class=\"text-[13px] font-medium\">Popover with button</text><text class=\"text-muted-foreground text-xs\">I am a popover that would like to look like a tooltip. I can&lsquo;t be a tooltip\n              because of the interactive element inside me.\n            </text></view><button size=\"sm\" class=\"h-7 px-2\">Know more\n          </button></view></popovercontent></popover>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "popover",
          "tooltip",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "popover-04",
          "group": "popover",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "popover-04",
              "path": "registry/default/components/popover/popover-04.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "popover-04",
              "path": "registry/default/components/popover/popover-04.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "popover-04",
              "path": "registry/default/components/popover/popover-04.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "popover-04",
              "path": "registry/default/components/popover/popover-04.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "popover",
        "title": "Popover · Interactive State"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "popover"
      ]
    },
    {
      "name": "popover-05",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/popover.json"
      ],
      "files": [
        {
          "path": "registry/default/components/popover/popover-05.tsx",
          "type": "registry:component",
          "target": "components/ui/popover-05.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Button, Popover, PopoverContent, PopoverTrigger } from '@timui/react'\n\nconst tips = [\n  {\n    title: 'Welcome to Dashboard',\n    description:\n      \"This is your new workspace. Here you'll find all your projects, recent activities, settings, and more.\",\n  },\n  {\n    title: 'Quick Actions',\n    description:\n      'Use the toolbar above to create new projects, invite team members, or access settings.',\n  },\n  {\n    title: 'Need Help?',\n    description:\n      'Click the support icon in the top right corner to access our help center and documentation.',\n  },\n]\n\nexport default function Component() {\n  const [currentTip, setCurrentTip] = useState(0)\n\n  const handleNavigation = () => {\n    if (currentTip === tips.length - 1) {\n      setCurrentTip(0)\n    } else {\n      setCurrentTip(currentTip + 1)\n    }\n  }\n\n  return (\n    <Popover>\n      <PopoverTrigger asChild>\n        <Button variant=\"outline\">Tooltip-like with steps</Button>\n      </PopoverTrigger>\n      <PopoverContent className=\"max-w-[280px] py-3 shadow-none\" side=\"top\">\n        <div className=\"space-y-3\">\n          <div className=\"space-y-1\">\n            <p className=\"text-[13px] font-medium\">{tips[currentTip].title}</p>\n            <p className=\"text-muted-foreground text-xs\">{tips[currentTip].description}</p>\n          </div>\n          <div className=\"flex items-center justify-between gap-2\">\n            <span className=\"text-muted-foreground text-xs\">\n              {currentTip + 1}/{tips.length}\n            </span>\n            <button className=\"text-xs font-medium hover:underline\" onClick={handleNavigation}>\n              {currentTip === tips.length - 1 ? 'Start over' : 'Next'}\n            </button>\n          </div>\n        </div>\n      </PopoverContent>\n    </Popover>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/popover/popover-05.vue",
          "target": "components/ui/popover-05.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Button } from '@timui/vue';\nimport { Popover, PopoverContent, PopoverTrigger } from '@timui/vue';\n\n\n\nconst currentTip = ref(0);\n\n</script>\n\n<template>\n  <Popover><PopoverTrigger as-child><Button variant=\"outline\">Tooltip-like with steps</Button></PopoverTrigger><PopoverContent class=\"max-w-[280px] py-3 shadow-none\" side=\"top\"><div class=\"space-y-3\"><div class=\"space-y-1\"><p class=\"text-[13px] font-medium\">{{ tips[currentTip].title }}</p><p class=\"text-muted-foreground text-xs\">{{ tips[currentTip].description }}</p></div><div class=\"flex items-center justify-between gap-2\"><span class=\"text-muted-foreground text-xs\">{{ currentTip + 1 }}/{{ tips.length }}</span><button class=\"text-xs font-medium hover:underline\" @click=\"handleNavigation\"><template v-if=\"currentTip === tips.length - 1\">\n{{ 'Start over' }}\n</template>\n<template v-else>\n{{ 'Next' }}\n</template></button></div></div></PopoverContent></Popover>\n</template>\n"
        },
        {
          "path": "registry/default/components/popover/popover-05.html",
          "target": "components/ui/popover-05.html",
          "type": "registry:component",
          "content": "<template>\n  <Popover><PopoverTrigger aschild><Button variant=\"outline\">Tooltip-like with steps</Button></PopoverTrigger><PopoverContent class=\"max-w-[280px] py-3 shadow-none\" side=\"top\"><div class=\"space-y-3\"><div class=\"space-y-1\"><p class=\"text-[13px] font-medium\">${tips[currentTip].title}</p><p class=\"text-muted-foreground text-xs\">${tips[currentTip].description}</p></div><div class=\"flex items-center justify-between gap-2\"><span class=\"text-muted-foreground text-xs\">${currentTip + 1}/${tips.length}</span><button class=\"text-xs font-medium hover:underline\" on-click=\"${handleNavigation}\"><!-- if currentTip === tips.length - 1 -->\n${'Start over'}\n<!-- else -->\n${'Next'}\n<!-- endif --></button></div></div></PopoverContent></Popover>\n</template>"
        },
        {
          "path": "registry/default/components/popover/popover-05.wxml",
          "target": "components/ui/popover-05/popover-05.wxml",
          "type": "registry:component",
          "content": "<view>\n  <popover><popovertrigger aschild><button variant=\"outline\">Tooltip-like with steps</button></popovertrigger><popovercontent class=\"max-w-[280px] py-3 shadow-none\" side=\"top\"><view class=\"space-y-3\"><view class=\"space-y-1\"><text class=\"text-[13px] font-medium\">{{ tips[currentTip].title }}</text><text class=\"text-muted-foreground text-xs\">{{ tips[currentTip].description }}</text></view><view class=\"flex items-center justify-between gap-2\"><text class=\"text-muted-foreground text-xs\">{{ currentTip + 1 }}/{{ tips.length }}</text><button class=\"text-xs font-medium hover:underline\" bindtap=\"handleNavigation\"><block wx:if=\"{{currentTip === tips.length - 1}}\">\n{{ 'Start over' }}\n</block>\n<block wx:else>\n{{ 'Next' }}\n</block></button></view></view></popovercontent></popover>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "popover",
          "tooltip",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "popover-05",
          "group": "popover",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "popover-05",
              "path": "registry/default/components/popover/popover-05.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "popover-05",
              "path": "registry/default/components/popover/popover-05.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "popover-05",
              "path": "registry/default/components/popover/popover-05.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "popover-05",
              "path": "registry/default/components/popover/popover-05.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "popover",
        "title": "Popover · Interactive State"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "popover"
      ]
    },
    {
      "name": "popover-06",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/popover.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/popover/popover-06.tsx",
          "type": "registry:component",
          "target": "components/ui/popover-06.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Button, Popover, PopoverContent, PopoverTrigger } from '@timui/react'\nimport { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react'\n\nconst tips = [\n  {\n    title: 'Welcome to Dashboard',\n    description:\n      \"This is your new workspace. Here you'll find all your projects, recent activities, settings, and more.\",\n  },\n  {\n    title: 'Quick Actions',\n    description:\n      'Use the toolbar above to create new projects, invite team members, or access settings.',\n  },\n  {\n    title: 'Need Help?',\n    description:\n      'Click the support icon in the top right corner to access our help center and documentation.',\n  },\n  {\n    title: 'Keyboard Shortcuts',\n    description:\n      'Press ⌘K to open the command palette. Use arrow keys to navigate and Enter to select an action.',\n  },\n  {\n    title: 'Stay Updated',\n    description:\n      'Enable notifications to receive updates about your projects, team activity, and important deadlines.',\n  },\n]\n\nexport default function Component() {\n  const [currentTip, setCurrentTip] = useState(0)\n\n  const handleNext = () => {\n    if (currentTip < tips.length - 1) {\n      setCurrentTip(currentTip + 1)\n    }\n  }\n\n  const handlePrev = () => {\n    if (currentTip > 0) {\n      setCurrentTip(currentTip - 1)\n    }\n  }\n\n  const isFirstTip = currentTip === 0\n  const isLastTip = currentTip === tips.length - 1\n\n  return (\n    <Popover>\n      <PopoverTrigger asChild>\n        <Button variant=\"outline\">Tooltip-like with nav</Button>\n      </PopoverTrigger>\n      <PopoverContent className=\"max-w-[280px] py-3 shadow-none\" side=\"top\">\n        <div className=\"space-y-3\">\n          <div className=\"space-y-1\">\n            <p className=\"text-[13px] font-medium\">{tips[currentTip].title}</p>\n            <p className=\"text-muted-foreground text-xs\">{tips[currentTip].description}</p>\n          </div>\n          <div className=\"flex items-center justify-between\">\n            <span className=\"text-muted-foreground text-xs\">\n              {currentTip + 1}/{tips.length}\n            </span>\n            <div className=\"flex gap-0.5\">\n              <Button\n                size=\"icon\"\n                variant=\"ghost\"\n                className=\"size-6\"\n                onClick={handlePrev}\n                disabled={isFirstTip}\n                aria-label=\"Previous tip\"\n              >\n                <ArrowLeftIcon size={14} aria-hidden=\"true\" />\n              </Button>\n              <Button\n                size=\"icon\"\n                variant=\"ghost\"\n                className=\"size-6\"\n                onClick={handleNext}\n                disabled={isLastTip}\n                aria-label=\"Next tip\"\n              >\n                <ArrowRightIcon size={14} aria-hidden=\"true\" />\n              </Button>\n            </div>\n          </div>\n        </div>\n      </PopoverContent>\n    </Popover>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/popover/popover-06.vue",
          "target": "components/ui/popover-06.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { ArrowLeftIcon, ArrowRightIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { Popover, PopoverContent, PopoverTrigger } from '@timui/vue';\n\n\n\nconst currentTip = ref(0);\n\n</script>\n\n<template>\n  <Popover><PopoverTrigger as-child><Button variant=\"outline\">Tooltip-like with nav</Button></PopoverTrigger><PopoverContent class=\"max-w-[280px] py-3 shadow-none\" side=\"top\"><div class=\"space-y-3\"><div class=\"space-y-1\"><p class=\"text-[13px] font-medium\">{{ tips[currentTip].title }}</p><p class=\"text-muted-foreground text-xs\">{{ tips[currentTip].description }}</p></div><div class=\"flex items-center justify-between\"><span class=\"text-muted-foreground text-xs\">{{ currentTip + 1 }}/{{ tips.length }}</span><div class=\"flex gap-0.5\"><Button size=\"icon\" variant=\"ghost\" class=\"size-6\" @click=\"handlePrev\" :disabled=\"isFirstTip\" aria-label=\"Previous tip\"><ArrowLeftIcon :size=\"14\" aria-hidden=\"true\" /></Button><Button size=\"icon\" variant=\"ghost\" class=\"size-6\" @click=\"handleNext\" :disabled=\"isLastTip\" aria-label=\"Next tip\"><ArrowRightIcon :size=\"14\" aria-hidden=\"true\" /></Button></div></div></div></PopoverContent></Popover>\n</template>\n"
        },
        {
          "path": "registry/default/components/popover/popover-06.html",
          "target": "components/ui/popover-06.html",
          "type": "registry:component",
          "content": "<template>\n  <Popover><PopoverTrigger aschild><Button variant=\"outline\">Tooltip-like with nav</Button></PopoverTrigger><PopoverContent class=\"max-w-[280px] py-3 shadow-none\" side=\"top\"><div class=\"space-y-3\"><div class=\"space-y-1\"><p class=\"text-[13px] font-medium\">${tips[currentTip].title}</p><p class=\"text-muted-foreground text-xs\">${tips[currentTip].description}</p></div><div class=\"flex items-center justify-between\"><span class=\"text-muted-foreground text-xs\">${currentTip + 1}/${tips.length}</span><div class=\"flex gap-0.5\"><Button size=\"icon\" variant=\"ghost\" class=\"size-6\" on-click=\"${handlePrev}\" disabled=\"${isFirstTip}\" aria-label=\"Previous tip\"><ArrowLeftIcon size=\"${14}\" aria-hidden=\"true\" /></Button><Button size=\"icon\" variant=\"ghost\" class=\"size-6\" on-click=\"${handleNext}\" disabled=\"${isLastTip}\" aria-label=\"Next tip\"><ArrowRightIcon size=\"${14}\" aria-hidden=\"true\" /></Button></div></div></div></PopoverContent></Popover>\n</template>"
        },
        {
          "path": "registry/default/components/popover/popover-06.wxml",
          "target": "components/ui/popover-06/popover-06.wxml",
          "type": "registry:component",
          "content": "<view>\n  <popover><popovertrigger aschild><button variant=\"outline\">Tooltip-like with nav</button></popovertrigger><popovercontent class=\"max-w-[280px] py-3 shadow-none\" side=\"top\"><view class=\"space-y-3\"><view class=\"space-y-1\"><text class=\"text-[13px] font-medium\">{{ tips[currentTip].title }}</text><text class=\"text-muted-foreground text-xs\">{{ tips[currentTip].description }}</text></view><view class=\"flex items-center justify-between\"><text class=\"text-muted-foreground text-xs\">{{ currentTip + 1 }}/{{ tips.length }}</text><view class=\"flex gap-0.5\"><button size=\"icon\" variant=\"ghost\" class=\"size-6\" bindtap=\"handlePrev\" disabled=\"{{isFirstTip}}\" aria-label=\"Previous tip\"><arrowlefticon size=\"{{14}}\" aria-hidden=\"true\" /></button><button size=\"icon\" variant=\"ghost\" class=\"size-6\" bindtap=\"handleNext\" disabled=\"{{isLastTip}}\" aria-label=\"Next tip\"><arrowrighticon size=\"{{14}}\" aria-hidden=\"true\" /></button></view></view></view></popovercontent></popover>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "popover",
          "tooltip",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "popover-06",
          "group": "popover",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "popover-06",
              "path": "registry/default/components/popover/popover-06.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "popover-06",
              "path": "registry/default/components/popover/popover-06.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "popover-06",
              "path": "registry/default/components/popover/popover-06.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "popover-06",
              "path": "registry/default/components/popover/popover-06.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "popover",
        "title": "Popover · Previous tip"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "popover"
      ]
    },
    {
      "name": "popover-07",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/popover.json",
        "https://ui.timkit.cn/r/tooltip.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/popover/popover-07.tsx",
          "type": "registry:component",
          "target": "components/ui/popover-07.tsx",
          "content": "'use client'\n\nimport { useId, useRef, useState } from 'react'\nimport { RiCodeFill, RiFacebookFill, RiMailLine, RiTwitterXFill } from '@remixicon/react'\nimport { cn } from '@timui/core'\nimport {\n  Button,\n  Input,\n  Popover,\n  PopoverContent,\n  PopoverTrigger,\n  Tooltip,\n  TooltipContent,\n  TooltipProvider,\n  TooltipTrigger,\n} from '@timui/react'\nimport { CheckIcon, CopyIcon } from 'lucide-react'\n\nexport default function Component() {\n  const id = useId()\n  const [copied, setCopied] = useState<boolean>(false)\n  const inputRef = useRef<HTMLInputElement>(null)\n\n  const handleCopy = () => {\n    if (inputRef.current) {\n      navigator.clipboard.writeText(inputRef.current.value)\n      setCopied(true)\n      setTimeout(() => setCopied(false), 1500)\n    }\n  }\n\n  return (\n    <div className=\"flex flex-col gap-4\">\n      <Popover>\n        <PopoverTrigger asChild>\n          <Button variant=\"outline\">Share</Button>\n        </PopoverTrigger>\n        <PopoverContent className=\"w-72\">\n          <div className=\"flex flex-col gap-3 text-center\">\n            <div className=\"text-sm font-medium\">Share code</div>\n            <div className=\"flex flex-wrap justify-center gap-2\">\n              <Button size=\"icon\" variant=\"outline\" aria-label=\"Embed\">\n                <RiCodeFill size={16} aria-hidden=\"true\" />\n              </Button>\n              <Button size=\"icon\" variant=\"outline\" aria-label=\"Share on Twitter\">\n                <RiTwitterXFill size={16} aria-hidden=\"true\" />\n              </Button>\n              <Button size=\"icon\" variant=\"outline\" aria-label=\"Share on Facebook\">\n                <RiFacebookFill size={16} aria-hidden=\"true\" />\n              </Button>\n              <Button size=\"icon\" variant=\"outline\" aria-label=\"Share via email\">\n                <RiMailLine size={16} aria-hidden=\"true\" />\n              </Button>\n            </div>\n            <div className=\"space-y-2\">\n              <div className=\"relative\">\n                <Input\n                  ref={inputRef}\n                  id={id}\n                  className=\"pe-9\"\n                  type=\"text\"\n                  defaultValue=\"https://ui.timkit.cn/Avx8HD\"\n                  aria-label=\"Share link\"\n                  readOnly\n                />\n                <TooltipProvider delayDuration={0}>\n                  <Tooltip>\n                    <TooltipTrigger asChild>\n                      <button\n                        onClick={handleCopy}\n                        className=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed\"\n                        aria-label={copied ? 'Copied' : 'Copy to clipboard'}\n                        disabled={copied}\n                      >\n                        <div\n                          className={cn(\n                            'transition-all',\n                            copied ? 'scale-100 opacity-100' : 'scale-0 opacity-0'\n                          )}\n                        >\n                          <CheckIcon className=\"stroke-emerald-500\" size={16} aria-hidden=\"true\" />\n                        </div>\n                        <div\n                          className={cn(\n                            'absolute transition-all',\n                            copied ? 'scale-0 opacity-0' : 'scale-100 opacity-100'\n                          )}\n                        >\n                          <CopyIcon size={16} aria-hidden=\"true\" />\n                        </div>\n                      </button>\n                    </TooltipTrigger>\n                    <TooltipContent className=\"px-2 py-1 text-xs\">Copy to clipboard</TooltipContent>\n                  </Tooltip>\n                </TooltipProvider>\n              </div>\n            </div>\n          </div>\n        </PopoverContent>\n      </Popover>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/popover/popover-07.vue",
          "target": "components/ui/popover-07.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { cn } from '@timui/core'\nimport {\n  CheckIcon,\n  CodeIcon,\n  CopyIcon,\n  FacebookIcon,\n  MailIcon,\n  TwitterIcon,\n} from 'lucide-vue-next'\nimport { Button } from '@timui/vue'\nimport { Input } from '@timui/vue'\nimport { Popover, PopoverContent, PopoverTrigger } from '@timui/vue'\nimport { Tooltip } from '@timui/vue'\nimport { TooltipContent } from '@timui/vue'\nimport { TooltipProvider } from '@timui/vue'\nimport { TooltipTrigger } from '@timui/vue'\n\nconst id = 'popover-07'\nconst shareLink = 'https://ui.timkit.cn/Avx8HD'\nconst copied = ref(false)\n\nconst handleCopy = async () => {\n  if (copied.value) return\n  try {\n    await navigator.clipboard.writeText(shareLink)\n    copied.value = true\n    setTimeout(() => {\n      copied.value = false\n    }, 1500)\n  } catch {\n    copied.value = false\n  }\n}\n</script>\n\n<template>\n  <div class=\"flex flex-col gap-4\">\n    <Popover>\n      <PopoverTrigger as-child>\n        <Button variant=\"outline\">Share</Button>\n      </PopoverTrigger>\n      <PopoverContent class=\"w-72\">\n        <div class=\"flex flex-col gap-3 text-center\">\n          <div class=\"text-sm font-medium\">Share code</div>\n          <div class=\"flex flex-wrap justify-center gap-2\">\n            <Button size=\"icon\" variant=\"outline\" aria-label=\"Embed\"><CodeIcon :size=\"16\" aria-hidden=\"true\" /></Button>\n            <Button size=\"icon\" variant=\"outline\" aria-label=\"Share on Twitter\"><TwitterIcon :size=\"16\" aria-hidden=\"true\" /></Button>\n            <Button size=\"icon\" variant=\"outline\" aria-label=\"Share on Facebook\"><FacebookIcon :size=\"16\" aria-hidden=\"true\" /></Button>\n            <Button size=\"icon\" variant=\"outline\" aria-label=\"Share via email\"><MailIcon :size=\"16\" aria-hidden=\"true\" /></Button>\n          </div>\n          <div class=\"space-y-2\">\n            <div class=\"relative\">\n              <Input :id=\"id\" class=\"pe-9\" type=\"text\" :default-value=\"shareLink\" aria-label=\"Share link\" readOnly />\n              <TooltipProvider :delayDuration=\"0\">\n                <Tooltip>\n                  <TooltipTrigger as-child>\n                    <button\n                      class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed\"\n                      :aria-label=\"copied ? 'Copied' : 'Copy to clipboard'\"\n                      :disabled=\"copied\"\n                      @click=\"handleCopy\"\n                    >\n                      <div :class=\"cn('transition-all', copied ? 'scale-100 opacity-100' : 'scale-0 opacity-0')\">\n                        <CheckIcon class=\"stroke-emerald-500\" :size=\"16\" aria-hidden=\"true\" />\n                      </div>\n                      <div :class=\"cn('absolute transition-all', copied ? 'scale-0 opacity-0' : 'scale-100 opacity-100')\">\n                        <CopyIcon :size=\"16\" aria-hidden=\"true\" />\n                      </div>\n                    </button>\n                  </TooltipTrigger>\n                  <TooltipContent class=\"px-2 py-1 text-xs\">Copy to clipboard</TooltipContent>\n                </Tooltip>\n              </TooltipProvider>\n            </div>\n          </div>\n        </div>\n      </PopoverContent>\n    </Popover>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/popover/popover-07.html",
          "target": "components/ui/popover-07.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex flex-col gap-4\"><Popover><PopoverTrigger aschild><Button variant=\"outline\">Share</Button></PopoverTrigger><PopoverContent class=\"w-72\"><div class=\"flex flex-col gap-3 text-center\"><div class=\"text-sm font-medium\">Share code</div><div class=\"flex flex-wrap justify-center gap-2\"><Button size=\"icon\" variant=\"outline\" aria-label=\"Embed\"><RiCodeFill size=\"${16}\" aria-hidden=\"true\" /></Button><Button size=\"icon\" variant=\"outline\" aria-label=\"Share on Twitter\"><RiTwitterXFill size=\"${16}\" aria-hidden=\"true\" /></Button><Button size=\"icon\" variant=\"outline\" aria-label=\"Share on Facebook\"><RiFacebookFill size=\"${16}\" aria-hidden=\"true\" /></Button><Button size=\"icon\" variant=\"outline\" aria-label=\"Share via email\"><RiMailLine size=\"${16}\" aria-hidden=\"true\" /></Button></div><div class=\"space-y-2\"><div class=\"relative\"><Input ref=\"${inputRef}\" id=\"${id}\" class=\"pe-9\" type=\"text\" default-value=\"https://ui.timkit.cn/Avx8HD\" aria-label=\"Share link\" readonly /><TooltipProvider delayduration=\"${0}\"><Tooltip><TooltipTrigger aschild><button on-click=\"${handleCopy}\" class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed\" aria-label=\"${copied ? 'Copied' : 'Copy to clipboard'}\" disabled=\"${copied}\"><div class=\"${cn(\n                            'transition-all',\n                            copied ? 'scale-100 opacity-100' : 'scale-0 opacity-0'\n                          )}\"><CheckIcon class=\"stroke-emerald-500\" size=\"${16}\" aria-hidden=\"true\" /></div><div class=\"${cn(\n                            'absolute transition-all',\n                            copied ? 'scale-0 opacity-0' : 'scale-100 opacity-100'\n                          )}\"><CopyIcon size=\"${16}\" aria-hidden=\"true\" /></div></button></TooltipTrigger><TooltipContent class=\"px-2 py-1 text-xs\">Copy to clipboard</TooltipContent></Tooltip></TooltipProvider></div></div></div></PopoverContent></Popover></div>\n</template>"
        },
        {
          "path": "registry/default/components/popover/popover-07.wxml",
          "target": "components/ui/popover-07/popover-07.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex flex-col gap-4\"><popover><popovertrigger aschild><button variant=\"outline\">Share</button></popovertrigger><popovercontent class=\"w-72\"><view class=\"flex flex-col gap-3 text-center\"><view class=\"text-sm font-medium\">Share code</view><view class=\"flex flex-wrap justify-center gap-2\"><button size=\"icon\" variant=\"outline\" aria-label=\"Embed\"><ricodefill size=\"{{16}}\" aria-hidden=\"true\" /></button><button size=\"icon\" variant=\"outline\" aria-label=\"Share on Twitter\"><ritwitterxfill size=\"{{16}}\" aria-hidden=\"true\" /></button><button size=\"icon\" variant=\"outline\" aria-label=\"Share on Facebook\"><rifacebookfill size=\"{{16}}\" aria-hidden=\"true\" /></button><button size=\"icon\" variant=\"outline\" aria-label=\"Share via email\"><rimailline size=\"{{16}}\" aria-hidden=\"true\" /></button></view><view class=\"space-y-2\"><view class=\"relative\"><input ref=\"{{inputRef}}\" id=\"{{id}}\" class=\"pe-9\" type=\"text\" default-value=\"https://ui.timkit.cn/Avx8HD\" aria-label=\"Share link\" readonly /><tooltipprovider delayduration=\"{{0}}\"><tooltip><tooltiptrigger aschild><button bindtap=\"handleCopy\" class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed\" aria-label=\"{{copied ? 'Copied' : 'Copy to clipboard'}}\" disabled=\"{{copied}}\"><view class=\"{{cn(\n                            'transition-all',\n                            copied ? 'scale-100 opacity-100' : 'scale-0 opacity-0'\n                          )}}\"><checkicon class=\"stroke-emerald-500\" size=\"{{16}}\" aria-hidden=\"true\" /></view><view class=\"{{cn(\n                            'absolute transition-all',\n                            copied ? 'scale-0 opacity-0' : 'scale-100 opacity-100'\n                          )}}\"><copyicon size=\"{{16}}\" aria-hidden=\"true\" /></view></button></tooltiptrigger><tooltipcontent class=\"px-2 py-1 text-xs\">Copy to clipboard</tooltipcontent></tooltip></tooltipprovider></view></view></view></popovercontent></popover></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "popover",
          "share",
          "social",
          "copy",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "popover-07",
          "group": "popover",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "popover-07",
              "path": "registry/default/components/popover/popover-07.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "popover-07",
              "path": "registry/default/components/popover/popover-07.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "popover-07",
              "path": "registry/default/components/popover/popover-07.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "popover-07",
              "path": "registry/default/components/popover/popover-07.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@remixicon/react",
              "@timui/core",
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "popover",
        "title": "Popover · Embed"
      },
      "dependencies": [
        "@remixicon/react",
        "@timui/core",
        "@timui/react"
      ],
      "categories": [
        "popover"
      ]
    },
    {
      "name": "popover-08",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/popover.json",
        "https://ui.timkit.cn/r/textarea.json"
      ],
      "files": [
        {
          "path": "registry/default/components/popover/popover-08.tsx",
          "type": "registry:component",
          "target": "components/ui/popover-08.tsx",
          "content": "import { Button, Popover, PopoverContent, PopoverTrigger, Textarea } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"flex flex-col gap-4\">\n      <Popover>\n        <PopoverTrigger asChild>\n          <Button variant=\"outline\">Feedback</Button>\n        </PopoverTrigger>\n        <PopoverContent className=\"w-72\">\n          <h2 className=\"mb-2 text-sm font-semibold\">Send us feedback</h2>\n          <form className=\"space-y-3\">\n            <Textarea\n              id=\"feedback\"\n              placeholder=\"How can we improve Timkit UI?\"\n              aria-label=\"Send feedback\"\n            />\n            <div className=\"flex flex-col sm:flex-row sm:justify-end\">\n              <Button size=\"sm\">Send feedback</Button>\n            </div>\n          </form>\n        </PopoverContent>\n      </Popover>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/popover/popover-08.vue",
          "target": "components/ui/popover-08.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\nimport { Popover, PopoverContent, PopoverTrigger } from '@timui/vue';\nimport { Textarea } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"flex flex-col gap-4\"><Popover><PopoverTrigger as-child><Button variant=\"outline\">Feedback</Button></PopoverTrigger><PopoverContent class=\"w-72\"><h2 class=\"mb-2 text-sm font-semibold\">Send us feedback</h2><form class=\"space-y-3\"><Textarea id=\"feedback\" placeholder=\"How can we improve Timkit UI?\" aria-label=\"Send feedback\" /><div class=\"flex flex-col sm:flex-row sm:justify-end\"><Button size=\"sm\">Send feedback</Button></div></form></PopoverContent></Popover></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/popover/popover-08.html",
          "target": "components/ui/popover-08.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex flex-col gap-4\"><Popover><PopoverTrigger aschild><Button variant=\"outline\">Feedback</Button></PopoverTrigger><PopoverContent class=\"w-72\"><h2 class=\"mb-2 text-sm font-semibold\">Send us feedback</h2><form class=\"space-y-3\"><Textarea id=\"feedback\" placeholder=\"How can we improve Timkit UI?\" aria-label=\"Send feedback\" /><div class=\"flex flex-col sm:flex-row sm:justify-end\"><Button size=\"sm\">Send feedback</Button></div></form></PopoverContent></Popover></div>\n</template>"
        },
        {
          "path": "registry/default/components/popover/popover-08.wxml",
          "target": "components/ui/popover-08/popover-08.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex flex-col gap-4\"><popover><popovertrigger aschild><button variant=\"outline\">Feedback</button></popovertrigger><popovercontent class=\"w-72\"><h2 class=\"mb-2 text-sm font-semibold\">Send us feedback</h2><form class=\"space-y-3\"><textarea id=\"feedback\" placeholder=\"How can we improve Timkit UI?\" aria-label=\"Send feedback\" /><view class=\"flex flex-col sm:flex-row sm:justify-end\"><button size=\"sm\">Send feedback</button></view></form></popovercontent></popover></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "popover",
          "feedback",
          "form",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "popover-08",
          "group": "popover",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "popover-08",
              "path": "registry/default/components/popover/popover-08.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "popover-08",
              "path": "registry/default/components/popover/popover-08.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "popover-08",
              "path": "registry/default/components/popover/popover-08.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "popover-08",
              "path": "registry/default/components/popover/popover-08.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "popover",
        "title": "Popover · Send us feedback"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "popover"
      ]
    },
    {
      "name": "popover-09",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/popover.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/popover/popover-09.tsx",
          "type": "registry:component",
          "target": "components/ui/popover-09.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Button, Popover, PopoverAnchor, PopoverContent, PopoverTrigger } from '@timui/react'\nimport { ClubIcon, DiamondIcon, HeartIcon, LucideIcon, SpadeIcon } from 'lucide-react'\n\ninterface TourStep {\n  icon: LucideIcon\n  title: string\n  description: string\n}\n\nconst tourSteps: TourStep[] = [\n  {\n    icon: HeartIcon,\n    title: 'Heart',\n    description:\n      \"This is your new workspace. Here you'll find all your projects, recent activities, settings, and more.\",\n  },\n  {\n    icon: DiamondIcon,\n    title: 'Diamond',\n    description:\n      'Use the toolbar above to create new projects, invite team members, or access settings.',\n  },\n  {\n    icon: ClubIcon,\n    title: 'Club',\n    description:\n      'Click the support icon in the top right corner to access our help center and documentation.',\n  },\n  {\n    icon: SpadeIcon,\n    title: 'Spade',\n    description:\n      'Press ⌘K to open the command palette. Use arrow keys to navigate and Enter to select an action.',\n  },\n]\n\ninterface CardProps {\n  number: number\n  isActive: boolean\n}\n\nfunction Card({ number, isActive }: CardProps) {\n  const content = (\n    <div className=\"bg-secondary text-muted-foreground flex size-10 items-center justify-center rounded-md text-sm font-medium\">\n      {number + 1}\n    </div>\n  )\n\n  return isActive ? <PopoverAnchor>{content}</PopoverAnchor> : content\n}\n\nexport default function Component() {\n  const [currentTip, setCurrentTip] = useState(0)\n\n  const handleNavigation = () => {\n    if (currentTip === tourSteps.length - 1) {\n      setCurrentTip(0)\n    } else {\n      setCurrentTip(currentTip + 1)\n    }\n  }\n\n  return (\n    <div className=\"flex flex-col gap-4\">\n      <Popover\n        onOpenChange={(open) => {\n          if (open) setCurrentTip(0)\n        }}\n      >\n        <div className=\"grid grid-cols-2 place-items-center gap-4\">\n          {tourSteps.map((step, index) => (\n            <Card key={step.title} number={index} isActive={currentTip === index} />\n          ))}\n        </div>\n\n        <PopoverTrigger asChild>\n          <Button variant=\"outline\">Start tour</Button>\n        </PopoverTrigger>\n\n        <PopoverContent\n          className=\"max-w-[280px] py-3 shadow-none\"\n          side={currentTip % 2 === 0 ? 'left' : 'right'}\n          showArrow={true}\n        >\n          <div className=\"space-y-3\">\n            <div className=\"space-y-1\">\n              <p className=\"text-[13px] font-medium\">{tourSteps[currentTip].title}</p>\n              <p className=\"text-muted-foreground text-xs\">{tourSteps[currentTip].description}</p>\n            </div>\n            <div className=\"flex items-center justify-between gap-2\">\n              <span className=\"text-muted-foreground text-xs\">\n                {currentTip + 1}/{tourSteps.length}\n              </span>\n              <button className=\"text-xs font-medium hover:underline\" onClick={handleNavigation}>\n                {currentTip === tourSteps.length - 1 ? 'Start over' : 'Next'}\n              </button>\n            </div>\n          </div>\n        </PopoverContent>\n      </Popover>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/popover/popover-09.vue",
          "target": "components/ui/popover-09.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref, type FunctionalComponent } from 'vue'\nimport { ClubIcon, DiamondIcon, HeartIcon, SpadeIcon } from 'lucide-vue-next'\nimport { Button } from '@timui/vue'\nimport { Popover, PopoverAnchor, PopoverContent, PopoverTrigger } from '@timui/vue'\n\ntype TourStep = {\n  icon: FunctionalComponent\n  title: string\n  description: string\n}\n\nconst currentTip = ref(0)\n\nconst tourSteps: TourStep[] = [\n  {\n    icon: HeartIcon,\n    title: 'Heart',\n    description:\n      \"This is your new workspace. Here you'll find all your projects, recent activities, settings, and more.\",\n  },\n  {\n    icon: DiamondIcon,\n    title: 'Diamond',\n    description:\n      'Use the toolbar above to create new projects, invite team members, or access settings.',\n  },\n  {\n    icon: ClubIcon,\n    title: 'Club',\n    description:\n      'Click the support icon in the top right corner to access our help center and documentation.',\n  },\n  {\n    icon: SpadeIcon,\n    title: 'Spade',\n    description:\n      'Press ⌘K to open the command palette. Use arrow keys to navigate and Enter to select an action.',\n  },\n]\n\nconst handleOpenChange = (open: boolean) => {\n  if (open) currentTip.value = 0\n}\n\nconst handleNavigation = () => {\n  currentTip.value = currentTip.value === tourSteps.length - 1 ? 0 : currentTip.value + 1\n}\n</script>\n\n<template>\n  <div class=\"flex flex-col gap-4\">\n    <Popover @update:open=\"handleOpenChange\">\n      <div class=\"grid grid-cols-2 place-items-center gap-4\">\n        <template v-for=\"(step, index) in tourSteps\" :key=\"step.title\">\n          <PopoverAnchor v-if=\"currentTip === index\">\n            <div class=\"bg-secondary text-muted-foreground flex size-10 items-center justify-center rounded-md text-sm font-medium\">\n              {{ index + 1 }}\n            </div>\n          </PopoverAnchor>\n          <div\n            v-else\n            class=\"bg-secondary text-muted-foreground flex size-10 items-center justify-center rounded-md text-sm font-medium\"\n          >\n            {{ index + 1 }}\n          </div>\n        </template>\n      </div>\n\n      <PopoverTrigger as-child>\n        <Button variant=\"outline\">Start tour</Button>\n      </PopoverTrigger>\n\n      <PopoverContent class=\"max-w-[280px] py-3 shadow-none\" :side=\"currentTip % 2 === 0 ? 'left' : 'right'\" :showArrow=\"true\">\n        <div class=\"space-y-3\">\n          <div class=\"space-y-1\">\n            <p class=\"text-[13px] font-medium\">{{ tourSteps[currentTip].title }}</p>\n            <p class=\"text-muted-foreground text-xs\">{{ tourSteps[currentTip].description }}</p>\n          </div>\n          <div class=\"flex items-center justify-between gap-2\">\n            <span class=\"text-muted-foreground text-xs\">{{ currentTip + 1 }}/{{ tourSteps.length }}</span>\n            <button class=\"text-xs font-medium hover:underline\" @click=\"handleNavigation\">\n              {{ currentTip === tourSteps.length - 1 ? 'Start over' : 'Next' }}\n            </button>\n          </div>\n        </div>\n      </PopoverContent>\n    </Popover>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/popover/popover-09.html",
          "target": "components/ui/popover-09.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex flex-col gap-4\"><Popover on-open-change=\"${(open) => {\n          if (open) setCurrentTip(0)\n        }}\"><div class=\"grid grid-cols-2 place-items-center gap-4\"><!-- Loop tourSteps -->\n<Card key=\"${step.title}\" number=\"${index}\" isactive=\"${currentTip === index}\" />\n<!-- End Loop --></div><PopoverTrigger aschild><Button variant=\"outline\">Start tour</Button></PopoverTrigger><PopoverContent class=\"max-w-[280px] py-3 shadow-none\" side=\"${currentTip % 2 === 0 ? 'left' : 'right'}\" showarrow=\"${true}\"><div class=\"space-y-3\"><div class=\"space-y-1\"><p class=\"text-[13px] font-medium\">${tourSteps[currentTip].title}</p><p class=\"text-muted-foreground text-xs\">${tourSteps[currentTip].description}</p></div><div class=\"flex items-center justify-between gap-2\"><span class=\"text-muted-foreground text-xs\">${currentTip + 1}/${tourSteps.length}</span><button class=\"text-xs font-medium hover:underline\" on-click=\"${handleNavigation}\"><!-- if currentTip === tourSteps.length - 1 -->\n${'Start over'}\n<!-- else -->\n${'Next'}\n<!-- endif --></button></div></div></PopoverContent></Popover></div>\n</template>"
        },
        {
          "path": "registry/default/components/popover/popover-09.wxml",
          "target": "components/ui/popover-09/popover-09.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex flex-col gap-4\"><popover bindchange=\"{\n          if (open) setCurrentTip(0)\n        }\"><view class=\"grid grid-cols-2 place-items-center gap-4\"><card wx:for=\"{{tourSteps}}\" wx:for-item=\"step\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{step.title}}\" number=\"{{index}}\" isactive=\"{{currentTip === index}}\" /></view><popovertrigger aschild><button variant=\"outline\">Start tour</button></popovertrigger><popovercontent class=\"max-w-[280px] py-3 shadow-none\" side=\"{{currentTip % 2 === 0 ? 'left' : 'right'}}\" showarrow=\"{{true}}\"><view class=\"space-y-3\"><view class=\"space-y-1\"><text class=\"text-[13px] font-medium\">{{ tourSteps[currentTip].title }}</text><text class=\"text-muted-foreground text-xs\">{{ tourSteps[currentTip].description }}</text></view><view class=\"flex items-center justify-between gap-2\"><text class=\"text-muted-foreground text-xs\">{{ currentTip + 1 }}/{{ tourSteps.length }}</text><button class=\"text-xs font-medium hover:underline\" bindtap=\"handleNavigation\"><block wx:if=\"{{currentTip === tourSteps.length - 1}}\">\n{{ 'Start over' }}\n</block>\n<block wx:else>\n{{ 'Next' }}\n</block></button></view></view></popovercontent></popover></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "popover",
          "tour",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "popover-09",
          "group": "popover",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "popover-09",
              "path": "registry/default/components/popover/popover-09.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "popover-09",
              "path": "registry/default/components/popover/popover-09.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "popover-09",
              "path": "registry/default/components/popover/popover-09.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "popover-09",
              "path": "registry/default/components/popover/popover-09.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "popover",
        "title": "Popover · Interactive State"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "popover"
      ]
    },
    {
      "name": "avatar-01",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/avatar.json"
      ],
      "files": [
        {
          "path": "registry/default/components/avatar/avatar-01.tsx",
          "type": "registry:component",
          "target": "components/ui/avatar-01.tsx",
          "content": "import { Avatar, AvatarFallback, AvatarImage } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Avatar>\n      <AvatarImage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" />\n      <AvatarFallback>KK</AvatarFallback>\n    </Avatar>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-01.vue",
          "target": "components/ui/avatar-01.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Avatar, AvatarFallback, AvatarImage } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Avatar><AvatarImage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" /><AvatarFallback>KK</AvatarFallback></Avatar>\n</template>\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-01.html",
          "target": "components/ui/avatar-01.html",
          "type": "registry:component",
          "content": "<template>\n  <Avatar><AvatarImage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" /><AvatarFallback>KK</AvatarFallback></Avatar>\n</template>"
        },
        {
          "path": "registry/default/components/avatar/avatar-01.wxml",
          "target": "components/ui/avatar-01/avatar-01.wxml",
          "type": "registry:component",
          "content": "<view>\n  <avatar><avatarimage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" /><avatarfallback>KK</avatarfallback></avatar>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "avatar",
          "user",
          "profile"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "avatar-01",
          "group": "avatar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "avatar-01",
              "path": "registry/default/components/avatar/avatar-01.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "avatar-01",
              "path": "registry/default/components/avatar/avatar-01.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "avatar-01",
              "path": "registry/default/components/avatar/avatar-01.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "avatar-01",
              "path": "registry/default/components/avatar/avatar-01.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "avatars",
        "title": "Avatar · Image + fallback"
      },
      "categories": [
        "avatars",
        "avatar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "avatar-02",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/avatar.json"
      ],
      "files": [
        {
          "path": "registry/default/components/avatar/avatar-02.tsx",
          "type": "registry:component",
          "target": "components/ui/avatar-02.tsx",
          "content": "import { Avatar, AvatarFallback } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Avatar>\n      <AvatarFallback>KK</AvatarFallback>\n    </Avatar>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-02.vue",
          "target": "components/ui/avatar-02.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Avatar, AvatarFallback } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Avatar><AvatarFallback>KK</AvatarFallback></Avatar>\n</template>\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-02.html",
          "target": "components/ui/avatar-02.html",
          "type": "registry:component",
          "content": "<template>\n  <Avatar><AvatarFallback>KK</AvatarFallback></Avatar>\n</template>"
        },
        {
          "path": "registry/default/components/avatar/avatar-02.wxml",
          "target": "components/ui/avatar-02/avatar-02.wxml",
          "type": "registry:component",
          "content": "<view>\n  <avatar><avatarfallback>KK</avatarfallback></avatar>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "avatar",
          "user",
          "profile"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "avatar-02",
          "group": "avatar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "avatar-02",
              "path": "registry/default/components/avatar/avatar-02.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "avatar-02",
              "path": "registry/default/components/avatar/avatar-02.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "avatar-02",
              "path": "registry/default/components/avatar/avatar-02.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "avatar-02",
              "path": "registry/default/components/avatar/avatar-02.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "avatars",
        "title": "Avatar · Fallback only"
      },
      "categories": [
        "avatars",
        "avatar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "avatar-03",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/avatar.json"
      ],
      "files": [
        {
          "path": "registry/default/components/avatar/avatar-03.tsx",
          "type": "registry:component",
          "target": "components/ui/avatar-03.tsx",
          "content": "import { Avatar, AvatarFallback } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Avatar>\n      <AvatarFallback>\n        <svg\n          className=\"size-4 opacity-60\"\n          viewBox=\"0 0 24 24\"\n          fill=\"none\"\n          stroke=\"currentColor\"\n          strokeWidth=\"2\"\n          strokeLinecap=\"round\"\n          strokeLinejoin=\"round\"\n          aria-hidden=\"true\"\n        >\n          <circle cx=\"12\" cy=\"8\" r=\"4\" />\n          <path d=\"M20 21a8 8 0 0 0-16 0\" />\n        </svg>\n      </AvatarFallback>\n    </Avatar>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-03.vue",
          "target": "components/ui/avatar-03.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Avatar, AvatarFallback } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Avatar><AvatarFallback><svg class=\"size-4 opacity-60\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"8\" r=\"4\" /><path d=\"M20 21a8 8 0 0 0-16 0\" /></svg></AvatarFallback></Avatar>\n</template>\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-03.html",
          "target": "components/ui/avatar-03.html",
          "type": "registry:component",
          "content": "<template>\n  <Avatar><AvatarFallback><svg class=\"size-4 opacity-60\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"8\" r=\"4\" /><path d=\"M20 21a8 8 0 0 0-16 0\" /></svg></AvatarFallback></Avatar>\n</template>"
        },
        {
          "path": "registry/default/components/avatar/avatar-03.wxml",
          "target": "components/ui/avatar-03/avatar-03.wxml",
          "type": "registry:component",
          "content": "<view>\n  <avatar><avatarfallback><svg class=\"size-4 opacity-60\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"8\" r=\"4\" /><path d=\"M20 21a8 8 0 0 0-16 0\" /></svg></avatarfallback></avatar>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "avatar",
          "user",
          "profile"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "avatar-03",
          "group": "avatar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "avatar-03",
              "path": "registry/default/components/avatar/avatar-03.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "avatar-03",
              "path": "registry/default/components/avatar/avatar-03.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "avatar-03",
              "path": "registry/default/components/avatar/avatar-03.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "avatar-03",
              "path": "registry/default/components/avatar/avatar-03.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "avatars",
        "title": "Avatar · Fallback only"
      },
      "categories": [
        "avatars",
        "avatar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "avatar-04",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/avatar.json"
      ],
      "files": [
        {
          "path": "registry/default/components/avatar/avatar-04.tsx",
          "type": "registry:component",
          "target": "components/ui/avatar-04.tsx",
          "content": "import { Avatar, AvatarFallback, AvatarImage } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Avatar className=\"rounded-md\">\n      <AvatarImage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" />\n      <AvatarFallback>KK</AvatarFallback>\n    </Avatar>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-04.vue",
          "target": "components/ui/avatar-04.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Avatar, AvatarFallback, AvatarImage } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Avatar class=\"rounded-md\"><AvatarImage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" /><AvatarFallback>KK</AvatarFallback></Avatar>\n</template>\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-04.html",
          "target": "components/ui/avatar-04.html",
          "type": "registry:component",
          "content": "<template>\n  <Avatar class=\"rounded-md\"><AvatarImage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" /><AvatarFallback>KK</AvatarFallback></Avatar>\n</template>"
        },
        {
          "path": "registry/default/components/avatar/avatar-04.wxml",
          "target": "components/ui/avatar-04/avatar-04.wxml",
          "type": "registry:component",
          "content": "<view>\n  <avatar class=\"rounded-md\"><avatarimage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" /><avatarfallback>KK</avatarfallback></avatar>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "avatar",
          "user",
          "profile"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "avatar-04",
          "group": "avatar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "avatar-04",
              "path": "registry/default/components/avatar/avatar-04.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "avatar-04",
              "path": "registry/default/components/avatar/avatar-04.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "avatar-04",
              "path": "registry/default/components/avatar/avatar-04.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "avatar-04",
              "path": "registry/default/components/avatar/avatar-04.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "avatars",
        "title": "Avatar · Image + fallback"
      },
      "categories": [
        "avatars",
        "avatar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "avatar-05",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/avatar.json"
      ],
      "files": [
        {
          "path": "registry/default/components/avatar/avatar-05.tsx",
          "type": "registry:component",
          "target": "components/ui/avatar-05.tsx",
          "content": "import { Avatar, AvatarFallback, AvatarImage } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"relative\">\n      <Avatar>\n        <AvatarImage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" />\n        <AvatarFallback>KK</AvatarFallback>\n      </Avatar>\n      <span className=\"border-background absolute -end-0.5 -bottom-0.5 size-3 rounded-full border-2 bg-emerald-500\">\n        <span className=\"sr-only\">Online</span>\n      </span>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-05.vue",
          "target": "components/ui/avatar-05.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Avatar, AvatarFallback, AvatarImage } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"relative\"><Avatar><AvatarImage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" /><AvatarFallback>KK</AvatarFallback></Avatar><span class=\"border-background absolute -end-0.5 -bottom-0.5 size-3 rounded-full border-2 bg-emerald-500\"><span class=\"sr-only\">Online</span></span></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-05.html",
          "target": "components/ui/avatar-05.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"relative\"><Avatar><AvatarImage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" /><AvatarFallback>KK</AvatarFallback></Avatar><span class=\"border-background absolute -end-0.5 -bottom-0.5 size-3 rounded-full border-2 bg-emerald-500\"><span class=\"sr-only\">Online</span></span></div>\n</template>"
        },
        {
          "path": "registry/default/components/avatar/avatar-05.wxml",
          "target": "components/ui/avatar-05/avatar-05.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"relative\"><avatar><avatarimage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" /><avatarfallback>KK</avatarfallback></avatar><text class=\"border-background absolute -end-0.5 -bottom-0.5 size-3 rounded-full border-2 bg-emerald-500\"><text class=\"sr-only\">Online</text></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "avatar",
          "user",
          "profile",
          "status"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "avatar-05",
          "group": "avatar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "avatar-05",
              "path": "registry/default/components/avatar/avatar-05.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "avatar-05",
              "path": "registry/default/components/avatar/avatar-05.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "avatar-05",
              "path": "registry/default/components/avatar/avatar-05.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "avatar-05",
              "path": "registry/default/components/avatar/avatar-05.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "avatars",
        "title": "Avatar · Image + fallback"
      },
      "categories": [
        "avatars",
        "avatar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "avatar-06",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/avatar.json"
      ],
      "files": [
        {
          "path": "registry/default/components/avatar/avatar-06.tsx",
          "type": "registry:component",
          "target": "components/ui/avatar-06.tsx",
          "content": "import { Avatar, AvatarFallback, AvatarImage } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"relative\">\n      <Avatar>\n        <AvatarImage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" />\n        <AvatarFallback>KK</AvatarFallback>\n      </Avatar>\n      <span className=\"border-background bg-muted-foreground absolute -end-0.5 -bottom-0.5 size-3 rounded-full border-2\">\n        <span className=\"sr-only\">Offline</span>\n      </span>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-06.vue",
          "target": "components/ui/avatar-06.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Avatar, AvatarFallback, AvatarImage } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"relative\"><Avatar><AvatarImage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" /><AvatarFallback>KK</AvatarFallback></Avatar><span class=\"border-background bg-muted-foreground absolute -end-0.5 -bottom-0.5 size-3 rounded-full border-2\"><span class=\"sr-only\">Offline</span></span></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-06.html",
          "target": "components/ui/avatar-06.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"relative\"><Avatar><AvatarImage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" /><AvatarFallback>KK</AvatarFallback></Avatar><span class=\"border-background bg-muted-foreground absolute -end-0.5 -bottom-0.5 size-3 rounded-full border-2\"><span class=\"sr-only\">Offline</span></span></div>\n</template>"
        },
        {
          "path": "registry/default/components/avatar/avatar-06.wxml",
          "target": "components/ui/avatar-06/avatar-06.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"relative\"><avatar><avatarimage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" /><avatarfallback>KK</avatarfallback></avatar><text class=\"border-background bg-muted-foreground absolute -end-0.5 -bottom-0.5 size-3 rounded-full border-2\"><text class=\"sr-only\">Offline</text></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "avatar",
          "user",
          "profile",
          "status"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "avatar-06",
          "group": "avatar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "avatar-06",
              "path": "registry/default/components/avatar/avatar-06.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "avatar-06",
              "path": "registry/default/components/avatar/avatar-06.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "avatar-06",
              "path": "registry/default/components/avatar/avatar-06.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "avatar-06",
              "path": "registry/default/components/avatar/avatar-06.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "avatars",
        "title": "Avatar · Image + fallback"
      },
      "categories": [
        "avatars",
        "avatar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "avatar-07",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/avatar.json"
      ],
      "files": [
        {
          "path": "registry/default/components/avatar/avatar-07.tsx",
          "type": "registry:component",
          "target": "components/ui/avatar-07.tsx",
          "content": "import { Avatar, AvatarFallback, AvatarImage } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"relative\">\n      <Avatar className=\"rounded-md\">\n        <AvatarImage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" />\n        <AvatarFallback>KK</AvatarFallback>\n      </Avatar>\n      <span className=\"border-background absolute -end-1 -top-1 size-3 rounded-full border-2 bg-emerald-500\">\n        <span className=\"sr-only\">Online</span>\n      </span>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-07.vue",
          "target": "components/ui/avatar-07.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Avatar, AvatarFallback, AvatarImage } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"relative\"><Avatar class=\"rounded-md\"><AvatarImage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" /><AvatarFallback>KK</AvatarFallback></Avatar><span class=\"border-background absolute -end-1 -top-1 size-3 rounded-full border-2 bg-emerald-500\"><span class=\"sr-only\">Online</span></span></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-07.html",
          "target": "components/ui/avatar-07.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"relative\"><Avatar class=\"rounded-md\"><AvatarImage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" /><AvatarFallback>KK</AvatarFallback></Avatar><span class=\"border-background absolute -end-1 -top-1 size-3 rounded-full border-2 bg-emerald-500\"><span class=\"sr-only\">Online</span></span></div>\n</template>"
        },
        {
          "path": "registry/default/components/avatar/avatar-07.wxml",
          "target": "components/ui/avatar-07/avatar-07.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"relative\"><avatar class=\"rounded-md\"><avatarimage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" /><avatarfallback>KK</avatarfallback></avatar><text class=\"border-background absolute -end-1 -top-1 size-3 rounded-full border-2 bg-emerald-500\"><text class=\"sr-only\">Online</text></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "avatar",
          "user",
          "profile",
          "status"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "avatar-07",
          "group": "avatar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "avatar-07",
              "path": "registry/default/components/avatar/avatar-07.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "avatar-07",
              "path": "registry/default/components/avatar/avatar-07.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "avatar-07",
              "path": "registry/default/components/avatar/avatar-07.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "avatar-07",
              "path": "registry/default/components/avatar/avatar-07.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "avatars",
        "title": "Avatar · Image + fallback"
      },
      "categories": [
        "avatars",
        "avatar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "avatar-08",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/avatar.json"
      ],
      "files": [
        {
          "path": "registry/default/components/avatar/avatar-08.tsx",
          "type": "registry:component",
          "target": "components/ui/avatar-08.tsx",
          "content": "import { Avatar, AvatarFallback, AvatarImage } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"relative\">\n      <Avatar>\n        <AvatarImage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" />\n        <AvatarFallback>KK</AvatarFallback>\n      </Avatar>\n      <span className=\"absolute -end-1.5 -top-1.5\">\n        <span className=\"sr-only\">Verified</span>\n        <svg\n          xmlns=\"http://www.w3.org/2000/svg\"\n          width=\"20\"\n          height=\"20\"\n          viewBox=\"0 0 24 24\"\n          aria-hidden=\"true\"\n        >\n          <path\n            className=\"fill-background\"\n            d=\"M3.046 8.277A4.402 4.402 0 0 1 8.303 3.03a4.4 4.4 0 0 1 7.411 0 4.397 4.397 0 0 1 5.19 3.068c.207.713.23 1.466.067 2.19a4.4 4.4 0 0 1 0 7.415 4.403 4.403 0 0 1-3.06 5.187 4.398 4.398 0 0 1-2.186.072 4.398 4.398 0 0 1-7.422 0 4.398 4.398 0 0 1-5.257-5.248 4.4 4.4 0 0 1 0-7.437Z\"\n          />\n          <path\n            className=\"fill-primary\"\n            d=\"M4.674 8.954a3.602 3.602 0 0 1 4.301-4.293 3.6 3.6 0 0 1 6.064 0 3.598 3.598 0 0 1 4.3 4.302 3.6 3.6 0 0 1 0 6.067 3.6 3.6 0 0 1-4.29 4.302 3.6 3.6 0 0 1-6.074 0 3.598 3.598 0 0 1-4.3-4.293 3.6 3.6 0 0 1 0-6.085Z\"\n          />\n          <path\n            className=\"fill-background\"\n            d=\"M15.707 9.293a1 1 0 0 1 0 1.414l-4 4a1 1 0 0 1-1.414 0l-2-2a1 1 0 1 1 1.414-1.414L11 12.586l3.293-3.293a1 1 0 0 1 1.414 0Z\"\n          />\n        </svg>\n      </span>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-08.vue",
          "target": "components/ui/avatar-08.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Avatar, AvatarFallback, AvatarImage } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"relative\"><Avatar><AvatarImage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" /><AvatarFallback>KK</AvatarFallback></Avatar><span class=\"absolute -end-1.5 -top-1.5\"><span class=\"sr-only\">Verified</span><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path class=\"fill-background\" d=\"M3.046 8.277A4.402 4.402 0 0 1 8.303 3.03a4.4 4.4 0 0 1 7.411 0 4.397 4.397 0 0 1 5.19 3.068c.207.713.23 1.466.067 2.19a4.4 4.4 0 0 1 0 7.415 4.403 4.403 0 0 1-3.06 5.187 4.398 4.398 0 0 1-2.186.072 4.398 4.398 0 0 1-7.422 0 4.398 4.398 0 0 1-5.257-5.248 4.4 4.4 0 0 1 0-7.437Z\" /><path class=\"fill-primary\" d=\"M4.674 8.954a3.602 3.602 0 0 1 4.301-4.293 3.6 3.6 0 0 1 6.064 0 3.598 3.598 0 0 1 4.3 4.302 3.6 3.6 0 0 1 0 6.067 3.6 3.6 0 0 1-4.29 4.302 3.6 3.6 0 0 1-6.074 0 3.598 3.598 0 0 1-4.3-4.293 3.6 3.6 0 0 1 0-6.085Z\" /><path class=\"fill-background\" d=\"M15.707 9.293a1 1 0 0 1 0 1.414l-4 4a1 1 0 0 1-1.414 0l-2-2a1 1 0 1 1 1.414-1.414L11 12.586l3.293-3.293a1 1 0 0 1 1.414 0Z\" /></svg></span></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-08.html",
          "target": "components/ui/avatar-08.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"relative\"><Avatar><AvatarImage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" /><AvatarFallback>KK</AvatarFallback></Avatar><span class=\"absolute -end-1.5 -top-1.5\"><span class=\"sr-only\">Verified</span><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewbox=\"0 0 24 24\" aria-hidden=\"true\"><path class=\"fill-background\" d=\"M3.046 8.277A4.402 4.402 0 0 1 8.303 3.03a4.4 4.4 0 0 1 7.411 0 4.397 4.397 0 0 1 5.19 3.068c.207.713.23 1.466.067 2.19a4.4 4.4 0 0 1 0 7.415 4.403 4.403 0 0 1-3.06 5.187 4.398 4.398 0 0 1-2.186.072 4.398 4.398 0 0 1-7.422 0 4.398 4.398 0 0 1-5.257-5.248 4.4 4.4 0 0 1 0-7.437Z\" /><path class=\"fill-primary\" d=\"M4.674 8.954a3.602 3.602 0 0 1 4.301-4.293 3.6 3.6 0 0 1 6.064 0 3.598 3.598 0 0 1 4.3 4.302 3.6 3.6 0 0 1 0 6.067 3.6 3.6 0 0 1-4.29 4.302 3.6 3.6 0 0 1-6.074 0 3.598 3.598 0 0 1-4.3-4.293 3.6 3.6 0 0 1 0-6.085Z\" /><path class=\"fill-background\" d=\"M15.707 9.293a1 1 0 0 1 0 1.414l-4 4a1 1 0 0 1-1.414 0l-2-2a1 1 0 1 1 1.414-1.414L11 12.586l3.293-3.293a1 1 0 0 1 1.414 0Z\" /></svg></span></div>\n</template>"
        },
        {
          "path": "registry/default/components/avatar/avatar-08.wxml",
          "target": "components/ui/avatar-08/avatar-08.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"relative\"><avatar><avatarimage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" /><avatarfallback>KK</avatarfallback></avatar><text class=\"absolute -end-1.5 -top-1.5\"><text class=\"sr-only\">Verified</text><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewbox=\"0 0 24 24\" aria-hidden=\"true\"><path class=\"fill-background\" d=\"M3.046 8.277A4.402 4.402 0 0 1 8.303 3.03a4.4 4.4 0 0 1 7.411 0 4.397 4.397 0 0 1 5.19 3.068c.207.713.23 1.466.067 2.19a4.4 4.4 0 0 1 0 7.415 4.403 4.403 0 0 1-3.06 5.187 4.398 4.398 0 0 1-2.186.072 4.398 4.398 0 0 1-7.422 0 4.398 4.398 0 0 1-5.257-5.248 4.4 4.4 0 0 1 0-7.437Z\" /><path class=\"fill-primary\" d=\"M4.674 8.954a3.602 3.602 0 0 1 4.301-4.293 3.6 3.6 0 0 1 6.064 0 3.598 3.598 0 0 1 4.3 4.302 3.6 3.6 0 0 1 0 6.067 3.6 3.6 0 0 1-4.29 4.302 3.6 3.6 0 0 1-6.074 0 3.598 3.598 0 0 1-4.3-4.293 3.6 3.6 0 0 1 0-6.085Z\" /><path class=\"fill-background\" d=\"M15.707 9.293a1 1 0 0 1 0 1.414l-4 4a1 1 0 0 1-1.414 0l-2-2a1 1 0 1 1 1.414-1.414L11 12.586l3.293-3.293a1 1 0 0 1 1.414 0Z\" /></svg></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "avatar",
          "user",
          "profile",
          "badge",
          "chip"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "avatar-08",
          "group": "avatar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "avatar-08",
              "path": "registry/default/components/avatar/avatar-08.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "avatar-08",
              "path": "registry/default/components/avatar/avatar-08.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "avatar-08",
              "path": "registry/default/components/avatar/avatar-08.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "avatar-08",
              "path": "registry/default/components/avatar/avatar-08.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "avatars",
        "title": "Avatar · Image + fallback"
      },
      "categories": [
        "avatars",
        "avatar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "avatar-09",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/avatar.json",
        "https://ui.timkit.cn/r/badge.json"
      ],
      "files": [
        {
          "path": "registry/default/components/avatar/avatar-09.tsx",
          "type": "registry:component",
          "target": "components/ui/avatar-09.tsx",
          "content": "import { Avatar, AvatarFallback, AvatarImage, Badge } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"relative\">\n      <Avatar>\n        <AvatarImage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" />\n        <AvatarFallback>KK</AvatarFallback>\n      </Avatar>\n      <Badge className=\"border-background absolute -top-1.5 left-full min-w-5 -translate-x-3.5 px-1\">\n        6\n      </Badge>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-09.vue",
          "target": "components/ui/avatar-09.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Avatar, AvatarFallback, AvatarImage } from '@timui/vue';\nimport { Badge } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"relative\"><Avatar><AvatarImage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" /><AvatarFallback>KK</AvatarFallback></Avatar><Badge class=\"border-background absolute -top-1.5 left-full min-w-5 -translate-x-3.5 px-1\">6\n      </Badge></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-09.html",
          "target": "components/ui/avatar-09.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"relative\"><Avatar><AvatarImage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" /><AvatarFallback>KK</AvatarFallback></Avatar><Badge class=\"border-background absolute -top-1.5 left-full min-w-5 -translate-x-3.5 px-1\">6\n      </Badge></div>\n</template>"
        },
        {
          "path": "registry/default/components/avatar/avatar-09.wxml",
          "target": "components/ui/avatar-09/avatar-09.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"relative\"><avatar><avatarimage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" /><avatarfallback>KK</avatarfallback></avatar><badge class=\"border-background absolute -top-1.5 left-full min-w-5 -translate-x-3.5 px-1\">6\n      </badge></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "avatar",
          "user",
          "profile",
          "badge",
          "chip"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "avatar-09",
          "group": "avatar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "avatar-09",
              "path": "registry/default/components/avatar/avatar-09.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "avatar-09",
              "path": "registry/default/components/avatar/avatar-09.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "avatar-09",
              "path": "registry/default/components/avatar/avatar-09.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "avatar-09",
              "path": "registry/default/components/avatar/avatar-09.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "avatars",
        "title": "Avatar · Image + fallback"
      },
      "categories": [
        "avatars",
        "avatar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "avatar-10",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/avatar.json",
        "https://ui.timkit.cn/r/badge.json"
      ],
      "files": [
        {
          "path": "registry/default/components/avatar/avatar-10.tsx",
          "type": "registry:component",
          "target": "components/ui/avatar-10.tsx",
          "content": "import { Avatar, AvatarFallback, AvatarImage, Badge } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"relative\">\n      <Avatar className=\"rounded-md\">\n        <AvatarImage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" />\n        <AvatarFallback>KK</AvatarFallback>\n      </Avatar>\n      <Badge className=\"border-background absolute -top-2 left-full min-w-5 -translate-x-3 px-1\">\n        6\n      </Badge>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-10.vue",
          "target": "components/ui/avatar-10.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Avatar, AvatarFallback, AvatarImage } from '@timui/vue';\nimport { Badge } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"relative\"><Avatar class=\"rounded-md\"><AvatarImage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" /><AvatarFallback>KK</AvatarFallback></Avatar><Badge class=\"border-background absolute -top-2 left-full min-w-5 -translate-x-3 px-1\">6\n      </Badge></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-10.html",
          "target": "components/ui/avatar-10.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"relative\"><Avatar class=\"rounded-md\"><AvatarImage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" /><AvatarFallback>KK</AvatarFallback></Avatar><Badge class=\"border-background absolute -top-2 left-full min-w-5 -translate-x-3 px-1\">6\n      </Badge></div>\n</template>"
        },
        {
          "path": "registry/default/components/avatar/avatar-10.wxml",
          "target": "components/ui/avatar-10/avatar-10.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"relative\"><avatar class=\"rounded-md\"><avatarimage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" /><avatarfallback>KK</avatarfallback></avatar><badge class=\"border-background absolute -top-2 left-full min-w-5 -translate-x-3 px-1\">6\n      </badge></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "avatar",
          "user",
          "profile",
          "badge",
          "chip"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "avatar-10",
          "group": "avatar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "avatar-10",
              "path": "registry/default/components/avatar/avatar-10.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "avatar-10",
              "path": "registry/default/components/avatar/avatar-10.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "avatar-10",
              "path": "registry/default/components/avatar/avatar-10.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "avatar-10",
              "path": "registry/default/components/avatar/avatar-10.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "avatars",
        "title": "Avatar · Image + fallback"
      },
      "categories": [
        "avatars",
        "avatar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "avatar-11",
      "type": "registry:component",
      "files": [
        {
          "path": "registry/default/components/avatar/avatar-11.tsx",
          "type": "registry:component",
          "target": "components/ui/avatar-11.tsx",
          "content": "import { Avatar, AvatarImage } from '@timui/react'\n\nconst avatars = [\n  { src: '/avatar-80-03.jpg', alt: 'Avatar 01' },\n  { src: '/avatar-80-04.jpg', alt: 'Avatar 02' },\n  { src: '/avatar-80-05.jpg', alt: 'Avatar 03' },\n  { src: '/avatar-80-06.jpg', alt: 'Avatar 04' },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"flex -space-x-1.5\">\n      {avatars.map((avatar) => (\n        <Avatar key={avatar.src} className=\"size-5 ring-1 ring-background\">\n          <AvatarImage src={avatar.src} alt={avatar.alt} />\n        </Avatar>\n      ))}\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-11.vue",
          "target": "components/ui/avatar-11.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Avatar, AvatarImage } from '@timui/vue'\n\nconst avatars = [\n  { src: '/avatar-80-03.jpg', alt: 'Avatar 01' },\n  { src: '/avatar-80-04.jpg', alt: 'Avatar 02' },\n  { src: '/avatar-80-05.jpg', alt: 'Avatar 03' },\n  { src: '/avatar-80-06.jpg', alt: 'Avatar 04' },\n]\n</script>\n\n<template>\n  <div class=\"flex -space-x-1.5\">\n    <Avatar v-for=\"avatar in avatars\" :key=\"avatar.src\" :class=\"'size-5 ring-1 ring-background'\">\n      <AvatarImage :src=\"avatar.src\" :alt=\"avatar.alt\" />\n    </Avatar>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-11.html",
          "target": "components/ui/avatar-11.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex -space-x-1.5\"><img class=\"ring-background rounded-full ring-1\" src=\"/avatar-80-03.jpg\" width=\"${20}\" height=\"${20}\" alt=\"Avatar 01\" /><img class=\"ring-background rounded-full ring-1\" src=\"/avatar-80-04.jpg\" width=\"${20}\" height=\"${20}\" alt=\"Avatar 02\" /><img class=\"ring-background rounded-full ring-1\" src=\"/avatar-80-05.jpg\" width=\"${20}\" height=\"${20}\" alt=\"Avatar 03\" /><img class=\"ring-background rounded-full ring-1\" src=\"/avatar-80-06.jpg\" width=\"${20}\" height=\"${20}\" alt=\"Avatar 04\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/avatar/avatar-11.wxml",
          "target": "components/ui/avatar-11/avatar-11.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex -space-x-1.5\"><image class=\"ring-background rounded-full ring-1\" src=\"/avatar-80-03.jpg\" width=\"{{20}}\" height=\"{{20}}\" alt=\"Avatar 01\" /><image class=\"ring-background rounded-full ring-1\" src=\"/avatar-80-04.jpg\" width=\"{{20}}\" height=\"{{20}}\" alt=\"Avatar 02\" /><image class=\"ring-background rounded-full ring-1\" src=\"/avatar-80-05.jpg\" width=\"{{20}}\" height=\"{{20}}\" alt=\"Avatar 03\" /><image class=\"ring-background rounded-full ring-1\" src=\"/avatar-80-06.jpg\" width=\"{{20}}\" height=\"{{20}}\" alt=\"Avatar 04\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "avatar",
          "user",
          "profile"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "avatar-11",
          "group": "avatar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "avatar-11",
              "path": "registry/default/components/avatar/avatar-11.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "avatar-11",
              "path": "registry/default/components/avatar/avatar-11.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "avatar-11",
              "path": "registry/default/components/avatar/avatar-11.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "avatar-11",
              "path": "registry/default/components/avatar/avatar-11.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "avatars",
        "title": "Avatar · Profile Pattern"
      },
      "categories": [
        "avatars",
        "avatar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "avatar-12",
      "type": "registry:component",
      "files": [
        {
          "path": "registry/default/components/avatar/avatar-12.tsx",
          "type": "registry:component",
          "target": "components/ui/avatar-12.tsx",
          "content": "import { Avatar, AvatarImage } from '@timui/react'\n\nconst avatars = [\n  { src: '/avatar-80-03.jpg', alt: 'Avatar 01' },\n  { src: '/avatar-80-04.jpg', alt: 'Avatar 02' },\n  { src: '/avatar-80-05.jpg', alt: 'Avatar 03' },\n  { src: '/avatar-80-06.jpg', alt: 'Avatar 04' },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"flex -space-x-[0.45rem]\">\n      {avatars.map((avatar) => (\n        <Avatar key={avatar.src} className=\"size-6 ring-1 ring-background\">\n          <AvatarImage src={avatar.src} alt={avatar.alt} />\n        </Avatar>\n      ))}\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-12.vue",
          "target": "components/ui/avatar-12.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Avatar, AvatarImage } from '@timui/vue'\n\nconst avatars = [\n  { src: '/avatar-80-03.jpg', alt: 'Avatar 01' },\n  { src: '/avatar-80-04.jpg', alt: 'Avatar 02' },\n  { src: '/avatar-80-05.jpg', alt: 'Avatar 03' },\n  { src: '/avatar-80-06.jpg', alt: 'Avatar 04' },\n]\n</script>\n\n<template>\n  <div class=\"flex -space-x-[0.45rem]\">\n    <Avatar v-for=\"avatar in avatars\" :key=\"avatar.src\" :class=\"'size-6 ring-1 ring-background'\">\n      <AvatarImage :src=\"avatar.src\" :alt=\"avatar.alt\" />\n    </Avatar>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-12.html",
          "target": "components/ui/avatar-12.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex -space-x-[0.45rem]\"><img class=\"ring-background rounded-full ring-1\" src=\"/avatar-80-03.jpg\" width=\"${24}\" height=\"${24}\" alt=\"Avatar 01\" /><img class=\"ring-background rounded-full ring-1\" src=\"/avatar-80-04.jpg\" width=\"${24}\" height=\"${24}\" alt=\"Avatar 02\" /><img class=\"ring-background rounded-full ring-1\" src=\"/avatar-80-05.jpg\" width=\"${24}\" height=\"${24}\" alt=\"Avatar 03\" /><img class=\"ring-background rounded-full ring-1\" src=\"/avatar-80-06.jpg\" width=\"${24}\" height=\"${24}\" alt=\"Avatar 04\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/avatar/avatar-12.wxml",
          "target": "components/ui/avatar-12/avatar-12.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex -space-x-[0.45rem]\"><image class=\"ring-background rounded-full ring-1\" src=\"/avatar-80-03.jpg\" width=\"{{24}}\" height=\"{{24}}\" alt=\"Avatar 01\" /><image class=\"ring-background rounded-full ring-1\" src=\"/avatar-80-04.jpg\" width=\"{{24}}\" height=\"{{24}}\" alt=\"Avatar 02\" /><image class=\"ring-background rounded-full ring-1\" src=\"/avatar-80-05.jpg\" width=\"{{24}}\" height=\"{{24}}\" alt=\"Avatar 03\" /><image class=\"ring-background rounded-full ring-1\" src=\"/avatar-80-06.jpg\" width=\"{{24}}\" height=\"{{24}}\" alt=\"Avatar 04\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "avatar",
          "avatar group"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "avatar-12",
          "group": "avatar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "avatar-12",
              "path": "registry/default/components/avatar/avatar-12.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "avatar-12",
              "path": "registry/default/components/avatar/avatar-12.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "avatar-12",
              "path": "registry/default/components/avatar/avatar-12.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "avatar-12",
              "path": "registry/default/components/avatar/avatar-12.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "avatars",
        "title": "Avatar · Profile Pattern"
      },
      "categories": [
        "avatars",
        "avatar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "avatar-13",
      "type": "registry:component",
      "files": [
        {
          "path": "registry/default/components/avatar/avatar-13.tsx",
          "type": "registry:component",
          "target": "components/ui/avatar-13.tsx",
          "content": "import { Avatar, AvatarImage } from '@timui/react'\n\nconst avatars = [\n  { src: '/avatar-80-03.jpg', alt: 'Avatar 01' },\n  { src: '/avatar-80-04.jpg', alt: 'Avatar 02' },\n  { src: '/avatar-80-05.jpg', alt: 'Avatar 03' },\n  { src: '/avatar-80-06.jpg', alt: 'Avatar 04' },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"flex -space-x-[0.525rem]\">\n      {avatars.map((avatar) => (\n        <Avatar key={avatar.src} className=\"size-7 ring-2 ring-background\">\n          <AvatarImage src={avatar.src} alt={avatar.alt} />\n        </Avatar>\n      ))}\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-13.vue",
          "target": "components/ui/avatar-13.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Avatar, AvatarImage } from '@timui/vue'\n\nconst avatars = [\n  { src: '/avatar-80-03.jpg', alt: 'Avatar 01' },\n  { src: '/avatar-80-04.jpg', alt: 'Avatar 02' },\n  { src: '/avatar-80-05.jpg', alt: 'Avatar 03' },\n  { src: '/avatar-80-06.jpg', alt: 'Avatar 04' },\n]\n</script>\n\n<template>\n  <div class=\"flex -space-x-[0.525rem]\">\n    <Avatar v-for=\"avatar in avatars\" :key=\"avatar.src\" :class=\"'size-7 ring-2 ring-background'\">\n      <AvatarImage :src=\"avatar.src\" :alt=\"avatar.alt\" />\n    </Avatar>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-13.html",
          "target": "components/ui/avatar-13.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex -space-x-[0.525rem]\"><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-03.jpg\" width=\"${28}\" height=\"${28}\" alt=\"Avatar 01\" /><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-04.jpg\" width=\"${28}\" height=\"${28}\" alt=\"Avatar 02\" /><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-05.jpg\" width=\"${28}\" height=\"${28}\" alt=\"Avatar 03\" /><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-06.jpg\" width=\"${28}\" height=\"${28}\" alt=\"Avatar 04\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/avatar/avatar-13.wxml",
          "target": "components/ui/avatar-13/avatar-13.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex -space-x-[0.525rem]\"><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-03.jpg\" width=\"{{28}}\" height=\"{{28}}\" alt=\"Avatar 01\" /><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-04.jpg\" width=\"{{28}}\" height=\"{{28}}\" alt=\"Avatar 02\" /><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-05.jpg\" width=\"{{28}}\" height=\"{{28}}\" alt=\"Avatar 03\" /><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-06.jpg\" width=\"{{28}}\" height=\"{{28}}\" alt=\"Avatar 04\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "avatar",
          "avatar group"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "avatar-13",
          "group": "avatar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "avatar-13",
              "path": "registry/default/components/avatar/avatar-13.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "avatar-13",
              "path": "registry/default/components/avatar/avatar-13.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "avatar-13",
              "path": "registry/default/components/avatar/avatar-13.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "avatar-13",
              "path": "registry/default/components/avatar/avatar-13.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "avatars",
        "title": "Avatar · Profile Pattern"
      },
      "categories": [
        "avatars",
        "avatar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "avatar-14",
      "type": "registry:component",
      "files": [
        {
          "path": "registry/default/components/avatar/avatar-14.tsx",
          "type": "registry:component",
          "target": "components/ui/avatar-14.tsx",
          "content": "import { Avatar, AvatarImage } from '@timui/react'\n\nconst avatars = [\n  { src: '/avatar-80-03.jpg', alt: 'Avatar 01' },\n  { src: '/avatar-80-04.jpg', alt: 'Avatar 02' },\n  { src: '/avatar-80-05.jpg', alt: 'Avatar 03' },\n  { src: '/avatar-80-06.jpg', alt: 'Avatar 04' },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"flex -space-x-[0.6rem]\">\n      {avatars.map((avatar) => (\n        <Avatar key={avatar.src} className=\"size-8 ring-2 ring-background\">\n          <AvatarImage src={avatar.src} alt={avatar.alt} />\n        </Avatar>\n      ))}\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-14.vue",
          "target": "components/ui/avatar-14.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Avatar, AvatarImage } from '@timui/vue'\n\nconst avatars = [\n  { src: '/avatar-80-03.jpg', alt: 'Avatar 01' },\n  { src: '/avatar-80-04.jpg', alt: 'Avatar 02' },\n  { src: '/avatar-80-05.jpg', alt: 'Avatar 03' },\n  { src: '/avatar-80-06.jpg', alt: 'Avatar 04' },\n]\n</script>\n\n<template>\n  <div class=\"flex -space-x-[0.6rem]\">\n    <Avatar v-for=\"avatar in avatars\" :key=\"avatar.src\" :class=\"'size-8 ring-2 ring-background'\">\n      <AvatarImage :src=\"avatar.src\" :alt=\"avatar.alt\" />\n    </Avatar>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-14.html",
          "target": "components/ui/avatar-14.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex -space-x-[0.6rem]\"><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-03.jpg\" width=\"${32}\" height=\"${32}\" alt=\"Avatar 01\" /><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-04.jpg\" width=\"${32}\" height=\"${32}\" alt=\"Avatar 02\" /><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-05.jpg\" width=\"${32}\" height=\"${32}\" alt=\"Avatar 03\" /><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-06.jpg\" width=\"${32}\" height=\"${32}\" alt=\"Avatar 04\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/avatar/avatar-14.wxml",
          "target": "components/ui/avatar-14/avatar-14.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex -space-x-[0.6rem]\"><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-03.jpg\" width=\"{{32}}\" height=\"{{32}}\" alt=\"Avatar 01\" /><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-04.jpg\" width=\"{{32}}\" height=\"{{32}}\" alt=\"Avatar 02\" /><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-05.jpg\" width=\"{{32}}\" height=\"{{32}}\" alt=\"Avatar 03\" /><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-06.jpg\" width=\"{{32}}\" height=\"{{32}}\" alt=\"Avatar 04\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "avatar",
          "avatar group"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "avatar-14",
          "group": "avatar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "avatar-14",
              "path": "registry/default/components/avatar/avatar-14.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "avatar-14",
              "path": "registry/default/components/avatar/avatar-14.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "avatar-14",
              "path": "registry/default/components/avatar/avatar-14.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "avatar-14",
              "path": "registry/default/components/avatar/avatar-14.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "avatars",
        "title": "Avatar · Profile Pattern"
      },
      "categories": [
        "avatars",
        "avatar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "avatar-15",
      "type": "registry:component",
      "files": [
        {
          "path": "registry/default/components/avatar/avatar-15.tsx",
          "type": "registry:component",
          "target": "components/ui/avatar-15.tsx",
          "content": "import { Avatar, AvatarImage } from '@timui/react'\n\nconst avatars = [\n  { src: '/avatar-80-03.jpg', alt: 'Avatar 01' },\n  { src: '/avatar-80-04.jpg', alt: 'Avatar 02' },\n  { src: '/avatar-80-05.jpg', alt: 'Avatar 03' },\n  { src: '/avatar-80-06.jpg', alt: 'Avatar 04' },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"flex -space-x-[0.675rem]\">\n      {avatars.map((avatar) => (\n        <Avatar key={avatar.src} className=\"size-9 ring-2 ring-background\">\n          <AvatarImage src={avatar.src} alt={avatar.alt} />\n        </Avatar>\n      ))}\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-15.vue",
          "target": "components/ui/avatar-15.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Avatar, AvatarImage } from '@timui/vue'\n\nconst avatars = [\n  { src: '/avatar-80-03.jpg', alt: 'Avatar 01' },\n  { src: '/avatar-80-04.jpg', alt: 'Avatar 02' },\n  { src: '/avatar-80-05.jpg', alt: 'Avatar 03' },\n  { src: '/avatar-80-06.jpg', alt: 'Avatar 04' },\n]\n</script>\n\n<template>\n  <div class=\"flex -space-x-[0.675rem]\">\n    <Avatar v-for=\"avatar in avatars\" :key=\"avatar.src\" :class=\"'size-9 ring-2 ring-background'\">\n      <AvatarImage :src=\"avatar.src\" :alt=\"avatar.alt\" />\n    </Avatar>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-15.html",
          "target": "components/ui/avatar-15.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex -space-x-[0.675rem]\"><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-03.jpg\" width=\"${36}\" height=\"${36}\" alt=\"Avatar 01\" /><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-04.jpg\" width=\"${36}\" height=\"${36}\" alt=\"Avatar 02\" /><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-05.jpg\" width=\"${36}\" height=\"${36}\" alt=\"Avatar 03\" /><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-06.jpg\" width=\"${36}\" height=\"${36}\" alt=\"Avatar 04\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/avatar/avatar-15.wxml",
          "target": "components/ui/avatar-15/avatar-15.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex -space-x-[0.675rem]\"><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-03.jpg\" width=\"{{36}}\" height=\"{{36}}\" alt=\"Avatar 01\" /><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-04.jpg\" width=\"{{36}}\" height=\"{{36}}\" alt=\"Avatar 02\" /><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-05.jpg\" width=\"{{36}}\" height=\"{{36}}\" alt=\"Avatar 03\" /><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-06.jpg\" width=\"{{36}}\" height=\"{{36}}\" alt=\"Avatar 04\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "avatar",
          "avatar group"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "avatar-15",
          "group": "avatar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "avatar-15",
              "path": "registry/default/components/avatar/avatar-15.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "avatar-15",
              "path": "registry/default/components/avatar/avatar-15.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "avatar-15",
              "path": "registry/default/components/avatar/avatar-15.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "avatar-15",
              "path": "registry/default/components/avatar/avatar-15.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "avatars",
        "title": "Avatar · Profile Pattern"
      },
      "categories": [
        "avatars",
        "avatar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "avatar-16",
      "type": "registry:component",
      "files": [
        {
          "path": "registry/default/components/avatar/avatar-16.tsx",
          "type": "registry:component",
          "target": "components/ui/avatar-16.tsx",
          "content": "import { Avatar, AvatarImage } from '@timui/react'\n\nconst avatars = [\n  { src: '/avatar-80-03.jpg', alt: 'Avatar 01' },\n  { src: '/avatar-80-04.jpg', alt: 'Avatar 02' },\n  { src: '/avatar-80-05.jpg', alt: 'Avatar 03' },\n  { src: '/avatar-80-06.jpg', alt: 'Avatar 04' },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"flex -space-x-3\">\n      {avatars.map((avatar) => (\n        <Avatar key={avatar.src} className=\"size-10 ring-2 ring-background\">\n          <AvatarImage src={avatar.src} alt={avatar.alt} />\n        </Avatar>\n      ))}\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-16.vue",
          "target": "components/ui/avatar-16.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Avatar, AvatarImage } from '@timui/vue'\n\nconst avatars = [\n  { src: '/avatar-80-03.jpg', alt: 'Avatar 01' },\n  { src: '/avatar-80-04.jpg', alt: 'Avatar 02' },\n  { src: '/avatar-80-05.jpg', alt: 'Avatar 03' },\n  { src: '/avatar-80-06.jpg', alt: 'Avatar 04' },\n]\n</script>\n\n<template>\n  <div class=\"flex -space-x-3\">\n    <Avatar v-for=\"avatar in avatars\" :key=\"avatar.src\" :class=\"'size-10 ring-2 ring-background'\">\n      <AvatarImage :src=\"avatar.src\" :alt=\"avatar.alt\" />\n    </Avatar>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-16.html",
          "target": "components/ui/avatar-16.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex -space-x-3\"><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-03.jpg\" width=\"${40}\" height=\"${40}\" alt=\"Avatar 01\" /><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-04.jpg\" width=\"${40}\" height=\"${40}\" alt=\"Avatar 02\" /><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-05.jpg\" width=\"${40}\" height=\"${40}\" alt=\"Avatar 03\" /><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-06.jpg\" width=\"${40}\" height=\"${40}\" alt=\"Avatar 04\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/avatar/avatar-16.wxml",
          "target": "components/ui/avatar-16/avatar-16.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex -space-x-3\"><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-03.jpg\" width=\"{{40}}\" height=\"{{40}}\" alt=\"Avatar 01\" /><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-04.jpg\" width=\"{{40}}\" height=\"{{40}}\" alt=\"Avatar 02\" /><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-05.jpg\" width=\"{{40}}\" height=\"{{40}}\" alt=\"Avatar 03\" /><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-06.jpg\" width=\"{{40}}\" height=\"{{40}}\" alt=\"Avatar 04\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "avatar",
          "avatar group"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "avatar-16",
          "group": "avatar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "avatar-16",
              "path": "registry/default/components/avatar/avatar-16.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "avatar-16",
              "path": "registry/default/components/avatar/avatar-16.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "avatar-16",
              "path": "registry/default/components/avatar/avatar-16.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "avatar-16",
              "path": "registry/default/components/avatar/avatar-16.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "avatars",
        "title": "Avatar · Profile Pattern"
      },
      "categories": [
        "avatars",
        "avatar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "avatar-17",
      "type": "registry:component",
      "files": [
        {
          "path": "registry/default/components/avatar/avatar-17.tsx",
          "type": "registry:component",
          "target": "components/ui/avatar-17.tsx",
          "content": "import { Avatar, AvatarImage } from '@timui/react'\n\nconst avatars = [\n  { src: '/avatar-80-03.jpg', alt: 'Avatar 01' },\n  { src: '/avatar-80-04.jpg', alt: 'Avatar 02' },\n  { src: '/avatar-80-05.jpg', alt: 'Avatar 03' },\n  { src: '/avatar-80-06.jpg', alt: 'Avatar 04' },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"flex -space-x-[0.9rem]\">\n      {avatars.map((avatar) => (\n        <Avatar key={avatar.src} className=\"size-12 ring-2 ring-background\">\n          <AvatarImage src={avatar.src} alt={avatar.alt} />\n        </Avatar>\n      ))}\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-17.vue",
          "target": "components/ui/avatar-17.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Avatar, AvatarImage } from '@timui/vue'\n\nconst avatars = [\n  { src: '/avatar-80-03.jpg', alt: 'Avatar 01' },\n  { src: '/avatar-80-04.jpg', alt: 'Avatar 02' },\n  { src: '/avatar-80-05.jpg', alt: 'Avatar 03' },\n  { src: '/avatar-80-06.jpg', alt: 'Avatar 04' },\n]\n</script>\n\n<template>\n  <div class=\"flex -space-x-[0.9rem]\">\n    <Avatar v-for=\"avatar in avatars\" :key=\"avatar.src\" :class=\"'size-12 ring-2 ring-background'\">\n      <AvatarImage :src=\"avatar.src\" :alt=\"avatar.alt\" />\n    </Avatar>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-17.html",
          "target": "components/ui/avatar-17.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex -space-x-[0.9rem]\"><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-03.jpg\" width=\"${48}\" height=\"${48}\" alt=\"Avatar 01\" /><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-04.jpg\" width=\"${48}\" height=\"${48}\" alt=\"Avatar 02\" /><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-05.jpg\" width=\"${48}\" height=\"${48}\" alt=\"Avatar 03\" /><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-06.jpg\" width=\"${48}\" height=\"${48}\" alt=\"Avatar 04\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/avatar/avatar-17.wxml",
          "target": "components/ui/avatar-17/avatar-17.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex -space-x-[0.9rem]\"><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-03.jpg\" width=\"{{48}}\" height=\"{{48}}\" alt=\"Avatar 01\" /><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-04.jpg\" width=\"{{48}}\" height=\"{{48}}\" alt=\"Avatar 02\" /><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-05.jpg\" width=\"{{48}}\" height=\"{{48}}\" alt=\"Avatar 03\" /><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-06.jpg\" width=\"{{48}}\" height=\"{{48}}\" alt=\"Avatar 04\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "avatar",
          "avatar group"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "avatar-17",
          "group": "avatar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "avatar-17",
              "path": "registry/default/components/avatar/avatar-17.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "avatar-17",
              "path": "registry/default/components/avatar/avatar-17.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "avatar-17",
              "path": "registry/default/components/avatar/avatar-17.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "avatar-17",
              "path": "registry/default/components/avatar/avatar-17.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "avatars",
        "title": "Avatar · Profile Pattern"
      },
      "categories": [
        "avatars",
        "avatar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "avatar-18",
      "type": "registry:component",
      "files": [
        {
          "path": "registry/default/components/avatar/avatar-18.tsx",
          "type": "registry:component",
          "target": "components/ui/avatar-18.tsx",
          "content": "import { Avatar, AvatarImage } from '@timui/react'\n\nconst avatars = [\n  { src: '/avatar-80-03.jpg', alt: 'Avatar 01' },\n  { src: '/avatar-80-04.jpg', alt: 'Avatar 02' },\n  { src: '/avatar-80-05.jpg', alt: 'Avatar 03' },\n  { src: '/avatar-80-06.jpg', alt: 'Avatar 04' },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"flex -space-x-[1.2rem]\">\n      {avatars.map((avatar) => (\n        <Avatar key={avatar.src} className=\"size-16 ring-2 ring-background\">\n          <AvatarImage src={avatar.src} alt={avatar.alt} />\n        </Avatar>\n      ))}\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-18.vue",
          "target": "components/ui/avatar-18.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Avatar, AvatarImage } from '@timui/vue'\n\nconst avatars = [\n  { src: '/avatar-80-03.jpg', alt: 'Avatar 01' },\n  { src: '/avatar-80-04.jpg', alt: 'Avatar 02' },\n  { src: '/avatar-80-05.jpg', alt: 'Avatar 03' },\n  { src: '/avatar-80-06.jpg', alt: 'Avatar 04' },\n]\n</script>\n\n<template>\n  <div class=\"flex -space-x-[1.2rem]\">\n    <Avatar v-for=\"avatar in avatars\" :key=\"avatar.src\" :class=\"'size-16 ring-2 ring-background'\">\n      <AvatarImage :src=\"avatar.src\" :alt=\"avatar.alt\" />\n    </Avatar>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-18.html",
          "target": "components/ui/avatar-18.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex -space-x-[1.2rem]\"><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-03.jpg\" width=\"${64}\" height=\"${64}\" alt=\"Avatar 01\" /><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-04.jpg\" width=\"${64}\" height=\"${64}\" alt=\"Avatar 02\" /><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-05.jpg\" width=\"${64}\" height=\"${64}\" alt=\"Avatar 03\" /><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-06.jpg\" width=\"${64}\" height=\"${64}\" alt=\"Avatar 04\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/avatar/avatar-18.wxml",
          "target": "components/ui/avatar-18/avatar-18.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex -space-x-[1.2rem]\"><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-03.jpg\" width=\"{{64}}\" height=\"{{64}}\" alt=\"Avatar 01\" /><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-04.jpg\" width=\"{{64}}\" height=\"{{64}}\" alt=\"Avatar 02\" /><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-05.jpg\" width=\"{{64}}\" height=\"{{64}}\" alt=\"Avatar 03\" /><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-06.jpg\" width=\"{{64}}\" height=\"{{64}}\" alt=\"Avatar 04\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "avatar",
          "avatar group"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "avatar-18",
          "group": "avatar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "avatar-18",
              "path": "registry/default/components/avatar/avatar-18.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "avatar-18",
              "path": "registry/default/components/avatar/avatar-18.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "avatar-18",
              "path": "registry/default/components/avatar/avatar-18.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "avatar-18",
              "path": "registry/default/components/avatar/avatar-18.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "avatars",
        "title": "Avatar · Profile Pattern"
      },
      "categories": [
        "avatars",
        "avatar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "avatar-19",
      "type": "registry:component",
      "files": [
        {
          "path": "registry/default/components/avatar/avatar-19.tsx",
          "type": "registry:component",
          "target": "components/ui/avatar-19.tsx",
          "content": "import { Avatar, AvatarImage } from '@timui/react'\n\nconst avatars = [\n  { src: '/avatar-80-03.jpg', alt: 'Avatar 01' },\n  { src: '/avatar-80-04.jpg', alt: 'Avatar 02' },\n  { src: '/avatar-80-05.jpg', alt: 'Avatar 03' },\n  { src: '/avatar-80-06.jpg', alt: 'Avatar 04' },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"flex -space-x-6\">\n      {avatars.map((avatar) => (\n        <Avatar key={avatar.src} className=\"size-20 ring-2 ring-background\">\n          <AvatarImage src={avatar.src} alt={avatar.alt} />\n        </Avatar>\n      ))}\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-19.vue",
          "target": "components/ui/avatar-19.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Avatar, AvatarImage } from '@timui/vue'\n\nconst avatars = [\n  { src: '/avatar-80-03.jpg', alt: 'Avatar 01' },\n  { src: '/avatar-80-04.jpg', alt: 'Avatar 02' },\n  { src: '/avatar-80-05.jpg', alt: 'Avatar 03' },\n  { src: '/avatar-80-06.jpg', alt: 'Avatar 04' },\n]\n</script>\n\n<template>\n  <div class=\"flex -space-x-6\">\n    <Avatar v-for=\"avatar in avatars\" :key=\"avatar.src\" :class=\"'size-20 ring-2 ring-background'\">\n      <AvatarImage :src=\"avatar.src\" :alt=\"avatar.alt\" />\n    </Avatar>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-19.html",
          "target": "components/ui/avatar-19.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex -space-x-6\"><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-03.jpg\" width=\"${80}\" height=\"${80}\" alt=\"Avatar 01\" /><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-04.jpg\" width=\"${80}\" height=\"${80}\" alt=\"Avatar 02\" /><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-05.jpg\" width=\"${80}\" height=\"${80}\" alt=\"Avatar 03\" /><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-06.jpg\" width=\"${80}\" height=\"${80}\" alt=\"Avatar 04\" /></div>\n</template>"
        },
        {
          "path": "registry/default/components/avatar/avatar-19.wxml",
          "target": "components/ui/avatar-19/avatar-19.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex -space-x-6\"><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-03.jpg\" width=\"{{80}}\" height=\"{{80}}\" alt=\"Avatar 01\" /><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-04.jpg\" width=\"{{80}}\" height=\"{{80}}\" alt=\"Avatar 02\" /><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-05.jpg\" width=\"{{80}}\" height=\"{{80}}\" alt=\"Avatar 03\" /><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-06.jpg\" width=\"{{80}}\" height=\"{{80}}\" alt=\"Avatar 04\" /></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "avatar",
          "avatar group"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "avatar-19",
          "group": "avatar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "avatar-19",
              "path": "registry/default/components/avatar/avatar-19.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "avatar-19",
              "path": "registry/default/components/avatar/avatar-19.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "avatar-19",
              "path": "registry/default/components/avatar/avatar-19.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "avatar-19",
              "path": "registry/default/components/avatar/avatar-19.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "avatars",
        "title": "Avatar · Profile Pattern"
      },
      "categories": [
        "avatars",
        "avatar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "avatar-20",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "files": [
        {
          "path": "registry/default/components/avatar/avatar-20.tsx",
          "type": "registry:component",
          "target": "components/ui/avatar-20.tsx",
          "content": "import { Button } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"flex -space-x-3\">\n      <img\n        className=\"ring-background rounded-full ring-2\"\n        src=\"/avatar-80-03.jpg\"\n        width={40}\n        height={40}\n        alt=\"Avatar 01\"\n      />\n      <img\n        className=\"ring-background rounded-full ring-2\"\n        src=\"/avatar-80-04.jpg\"\n        width={40}\n        height={40}\n        alt=\"Avatar 02\"\n      />\n      <img\n        className=\"ring-background rounded-full ring-2\"\n        src=\"/avatar-80-05.jpg\"\n        width={40}\n        height={40}\n        alt=\"Avatar 03\"\n      />\n      <img\n        className=\"ring-background rounded-full ring-2\"\n        src=\"/avatar-80-06.jpg\"\n        width={40}\n        height={40}\n        alt=\"Avatar 04\"\n      />\n      <Button\n        variant=\"secondary\"\n        className=\"bg-secondary text-muted-foreground ring-background hover:bg-secondary hover:text-foreground flex size-10 items-center justify-center rounded-full text-xs ring-2\"\n        size=\"icon\"\n      >\n        +3\n      </Button>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-20.vue",
          "target": "components/ui/avatar-20.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"flex -space-x-3\"><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-03.jpg\" :width=\"40\" :height=\"40\" alt=\"Avatar 01\" /><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-04.jpg\" :width=\"40\" :height=\"40\" alt=\"Avatar 02\" /><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-05.jpg\" :width=\"40\" :height=\"40\" alt=\"Avatar 03\" /><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-06.jpg\" :width=\"40\" :height=\"40\" alt=\"Avatar 04\" /><Button variant=\"secondary\" class=\"bg-secondary text-muted-foreground ring-background hover:bg-secondary hover:text-foreground flex size-10 items-center justify-center rounded-full text-xs ring-2\" size=\"icon\">+3\n      </Button></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-20.html",
          "target": "components/ui/avatar-20.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex -space-x-3\"><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-03.jpg\" width=\"${40}\" height=\"${40}\" alt=\"Avatar 01\" /><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-04.jpg\" width=\"${40}\" height=\"${40}\" alt=\"Avatar 02\" /><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-05.jpg\" width=\"${40}\" height=\"${40}\" alt=\"Avatar 03\" /><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-06.jpg\" width=\"${40}\" height=\"${40}\" alt=\"Avatar 04\" /><Button variant=\"secondary\" class=\"bg-secondary text-muted-foreground ring-background hover:bg-secondary hover:text-foreground flex size-10 items-center justify-center rounded-full text-xs ring-2\" size=\"icon\">+3\n      </Button></div>\n</template>"
        },
        {
          "path": "registry/default/components/avatar/avatar-20.wxml",
          "target": "components/ui/avatar-20/avatar-20.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex -space-x-3\"><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-03.jpg\" width=\"{{40}}\" height=\"{{40}}\" alt=\"Avatar 01\" /><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-04.jpg\" width=\"{{40}}\" height=\"{{40}}\" alt=\"Avatar 02\" /><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-05.jpg\" width=\"{{40}}\" height=\"{{40}}\" alt=\"Avatar 03\" /><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-06.jpg\" width=\"{{40}}\" height=\"{{40}}\" alt=\"Avatar 04\" /><button variant=\"secondary\" class=\"bg-secondary text-muted-foreground ring-background hover:bg-secondary hover:text-foreground flex size-10 items-center justify-center rounded-full text-xs ring-2\" size=\"icon\">+3\n      </button></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "avatar",
          "avatar group"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "avatar-20",
          "group": "avatar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "avatar-20",
              "path": "registry/default/components/avatar/avatar-20.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "avatar-20",
              "path": "registry/default/components/avatar/avatar-20.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "avatar-20",
              "path": "registry/default/components/avatar/avatar-20.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "avatar-20",
              "path": "registry/default/components/avatar/avatar-20.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "avatars",
        "title": "Avatar · Interactive State"
      },
      "categories": [
        "avatars",
        "avatar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "avatar-21",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "files": [
        {
          "path": "registry/default/components/avatar/avatar-21.tsx",
          "type": "registry:component",
          "target": "components/ui/avatar-21.tsx",
          "content": "import { Button } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"bg-muted flex items-center rounded-full p-0.5\">\n      <div className=\"flex -space-x-3\">\n        <img\n          className=\"ring-muted rounded-full ring-2\"\n          src=\"/avatar-80-03.jpg\"\n          width={40}\n          height={40}\n          alt=\"Avatar 01\"\n        />\n        <img\n          className=\"ring-muted rounded-full ring-2\"\n          src=\"/avatar-80-04.jpg\"\n          width={40}\n          height={40}\n          alt=\"Avatar 02\"\n        />\n        <img\n          className=\"ring-muted rounded-full ring-2\"\n          src=\"/avatar-80-05.jpg\"\n          width={40}\n          height={40}\n          alt=\"Avatar 03\"\n        />\n        <img\n          className=\"ring-muted rounded-full ring-2\"\n          src=\"/avatar-80-06.jpg\"\n          width={40}\n          height={40}\n          alt=\"Avatar 04\"\n        />\n      </div>\n      <Button\n        variant=\"secondary\"\n        className=\"text-muted-foreground hover:text-foreground flex items-center justify-center rounded-full bg-transparent px-3 text-xs shadow-none hover:bg-transparent\"\n      >\n        +3\n      </Button>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-21.vue",
          "target": "components/ui/avatar-21.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"bg-muted flex items-center rounded-full p-0.5\"><div class=\"flex -space-x-3\"><img class=\"ring-muted rounded-full ring-2\" src=\"/avatar-80-03.jpg\" :width=\"40\" :height=\"40\" alt=\"Avatar 01\" /><img class=\"ring-muted rounded-full ring-2\" src=\"/avatar-80-04.jpg\" :width=\"40\" :height=\"40\" alt=\"Avatar 02\" /><img class=\"ring-muted rounded-full ring-2\" src=\"/avatar-80-05.jpg\" :width=\"40\" :height=\"40\" alt=\"Avatar 03\" /><img class=\"ring-muted rounded-full ring-2\" src=\"/avatar-80-06.jpg\" :width=\"40\" :height=\"40\" alt=\"Avatar 04\" /></div><Button variant=\"secondary\" class=\"text-muted-foreground hover:text-foreground flex items-center justify-center rounded-full bg-transparent px-3 text-xs shadow-none hover:bg-transparent\">+3\n      </Button></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-21.html",
          "target": "components/ui/avatar-21.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"bg-muted flex items-center rounded-full p-0.5\"><div class=\"flex -space-x-3\"><img class=\"ring-muted rounded-full ring-2\" src=\"/avatar-80-03.jpg\" width=\"${40}\" height=\"${40}\" alt=\"Avatar 01\" /><img class=\"ring-muted rounded-full ring-2\" src=\"/avatar-80-04.jpg\" width=\"${40}\" height=\"${40}\" alt=\"Avatar 02\" /><img class=\"ring-muted rounded-full ring-2\" src=\"/avatar-80-05.jpg\" width=\"${40}\" height=\"${40}\" alt=\"Avatar 03\" /><img class=\"ring-muted rounded-full ring-2\" src=\"/avatar-80-06.jpg\" width=\"${40}\" height=\"${40}\" alt=\"Avatar 04\" /></div><Button variant=\"secondary\" class=\"text-muted-foreground hover:text-foreground flex items-center justify-center rounded-full bg-transparent px-3 text-xs shadow-none hover:bg-transparent\">+3\n      </Button></div>\n</template>"
        },
        {
          "path": "registry/default/components/avatar/avatar-21.wxml",
          "target": "components/ui/avatar-21/avatar-21.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"bg-muted flex items-center rounded-full p-0.5\"><view class=\"flex -space-x-3\"><image class=\"ring-muted rounded-full ring-2\" src=\"/avatar-80-03.jpg\" width=\"{{40}}\" height=\"{{40}}\" alt=\"Avatar 01\" /><image class=\"ring-muted rounded-full ring-2\" src=\"/avatar-80-04.jpg\" width=\"{{40}}\" height=\"{{40}}\" alt=\"Avatar 02\" /><image class=\"ring-muted rounded-full ring-2\" src=\"/avatar-80-05.jpg\" width=\"{{40}}\" height=\"{{40}}\" alt=\"Avatar 03\" /><image class=\"ring-muted rounded-full ring-2\" src=\"/avatar-80-06.jpg\" width=\"{{40}}\" height=\"{{40}}\" alt=\"Avatar 04\" /></view><button variant=\"secondary\" class=\"text-muted-foreground hover:text-foreground flex items-center justify-center rounded-full bg-transparent px-3 text-xs shadow-none hover:bg-transparent\">+3\n      </button></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "avatar",
          "avatar group"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "avatar-21",
          "group": "avatar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "avatar-21",
              "path": "registry/default/components/avatar/avatar-21.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "avatar-21",
              "path": "registry/default/components/avatar/avatar-21.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "avatar-21",
              "path": "registry/default/components/avatar/avatar-21.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "avatar-21",
              "path": "registry/default/components/avatar/avatar-21.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "avatars",
        "title": "Avatar · Interactive State"
      },
      "categories": [
        "avatars",
        "avatar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "avatar-22",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "files": [
        {
          "path": "registry/default/components/avatar/avatar-22.tsx",
          "type": "registry:component",
          "target": "components/ui/avatar-22.tsx",
          "content": "import { Button } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"bg-background flex items-center rounded-full border p-1 shadow-sm\">\n      <div className=\"flex -space-x-3\">\n        <img\n          className=\"ring-background rounded-full ring-2\"\n          src=\"/avatar-80-03.jpg\"\n          width={40}\n          height={40}\n          alt=\"Avatar 01\"\n        />\n        <img\n          className=\"ring-background rounded-full ring-2\"\n          src=\"/avatar-80-04.jpg\"\n          width={40}\n          height={40}\n          alt=\"Avatar 02\"\n        />\n        <img\n          className=\"ring-background rounded-full ring-2\"\n          src=\"/avatar-80-05.jpg\"\n          width={40}\n          height={40}\n          alt=\"Avatar 03\"\n        />\n        <img\n          className=\"ring-background rounded-full ring-2\"\n          src=\"/avatar-80-06.jpg\"\n          width={40}\n          height={40}\n          alt=\"Avatar 04\"\n        />\n      </div>\n      <Button\n        variant=\"secondary\"\n        className=\"text-muted-foreground hover:text-foreground flex items-center justify-center rounded-full bg-transparent px-3 text-xs shadow-none hover:bg-transparent\"\n      >\n        +3\n      </Button>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-22.vue",
          "target": "components/ui/avatar-22.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"bg-background flex items-center rounded-full border p-1 shadow-sm\"><div class=\"flex -space-x-3\"><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-03.jpg\" :width=\"40\" :height=\"40\" alt=\"Avatar 01\" /><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-04.jpg\" :width=\"40\" :height=\"40\" alt=\"Avatar 02\" /><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-05.jpg\" :width=\"40\" :height=\"40\" alt=\"Avatar 03\" /><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-06.jpg\" :width=\"40\" :height=\"40\" alt=\"Avatar 04\" /></div><Button variant=\"secondary\" class=\"text-muted-foreground hover:text-foreground flex items-center justify-center rounded-full bg-transparent px-3 text-xs shadow-none hover:bg-transparent\">+3\n      </Button></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-22.html",
          "target": "components/ui/avatar-22.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"bg-background flex items-center rounded-full border p-1 shadow-sm\"><div class=\"flex -space-x-3\"><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-03.jpg\" width=\"${40}\" height=\"${40}\" alt=\"Avatar 01\" /><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-04.jpg\" width=\"${40}\" height=\"${40}\" alt=\"Avatar 02\" /><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-05.jpg\" width=\"${40}\" height=\"${40}\" alt=\"Avatar 03\" /><img class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-06.jpg\" width=\"${40}\" height=\"${40}\" alt=\"Avatar 04\" /></div><Button variant=\"secondary\" class=\"text-muted-foreground hover:text-foreground flex items-center justify-center rounded-full bg-transparent px-3 text-xs shadow-none hover:bg-transparent\">+3\n      </Button></div>\n</template>"
        },
        {
          "path": "registry/default/components/avatar/avatar-22.wxml",
          "target": "components/ui/avatar-22/avatar-22.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"bg-background flex items-center rounded-full border p-1 shadow-sm\"><view class=\"flex -space-x-3\"><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-03.jpg\" width=\"{{40}}\" height=\"{{40}}\" alt=\"Avatar 01\" /><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-04.jpg\" width=\"{{40}}\" height=\"{{40}}\" alt=\"Avatar 02\" /><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-05.jpg\" width=\"{{40}}\" height=\"{{40}}\" alt=\"Avatar 03\" /><image class=\"ring-background rounded-full ring-2\" src=\"/avatar-80-06.jpg\" width=\"{{40}}\" height=\"{{40}}\" alt=\"Avatar 04\" /></view><button variant=\"secondary\" class=\"text-muted-foreground hover:text-foreground flex items-center justify-center rounded-full bg-transparent px-3 text-xs shadow-none hover:bg-transparent\">+3\n      </button></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "avatar",
          "avatar group"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "avatar-22",
          "group": "avatar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "avatar-22",
              "path": "registry/default/components/avatar/avatar-22.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "avatar-22",
              "path": "registry/default/components/avatar/avatar-22.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "avatar-22",
              "path": "registry/default/components/avatar/avatar-22.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "avatar-22",
              "path": "registry/default/components/avatar/avatar-22.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "avatars",
        "title": "Avatar · Interactive State"
      },
      "categories": [
        "avatars",
        "avatar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "avatar-23",
      "type": "registry:component",
      "files": [
        {
          "path": "registry/default/components/avatar/avatar-23.tsx",
          "type": "registry:component",
          "target": "components/ui/avatar-23.tsx",
          "content": "import { Avatar, AvatarImage } from '@timui/react'\n\nconst avatars = [\n  { src: '/avatar-80-03.jpg', alt: 'Avatar 01' },\n  { src: '/avatar-80-04.jpg', alt: 'Avatar 02' },\n  { src: '/avatar-80-05.jpg', alt: 'Avatar 03' },\n  { src: '/avatar-80-06.jpg', alt: 'Avatar 04' },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"bg-background flex items-center rounded-full border p-1 shadow-sm\">\n      <div className=\"flex -space-x-1.5\">\n        {avatars.map((avatar) => (\n          <Avatar key={avatar.src} className=\"size-5 ring-1 ring-background\">\n            <AvatarImage src={avatar.src} alt={avatar.alt} />\n          </Avatar>\n        ))}\n      </div>\n      <p className=\"text-muted-foreground px-2 text-xs\">\n        Trusted by <strong className=\"text-foreground font-medium\">60K+</strong> developers.\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-23.vue",
          "target": "components/ui/avatar-23.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Avatar, AvatarImage } from '@timui/vue'\n\nconst avatars = [\n  { src: '/avatar-80-03.jpg', alt: 'Avatar 01' },\n  { src: '/avatar-80-04.jpg', alt: 'Avatar 02' },\n  { src: '/avatar-80-05.jpg', alt: 'Avatar 03' },\n  { src: '/avatar-80-06.jpg', alt: 'Avatar 04' },\n]\n</script>\n\n<template>\n  <div class=\"bg-background flex items-center rounded-full border p-1 shadow-sm\">\n    <div class=\"flex -space-x-1.5\">\n      <Avatar v-for=\"avatar in avatars\" :key=\"avatar.src\" class=\"size-5 ring-1 ring-background\">\n        <AvatarImage :src=\"avatar.src\" :alt=\"avatar.alt\" />\n      </Avatar>\n    </div>\n    <p class=\"text-muted-foreground px-2 text-xs\">\n      Trusted by <strong class=\"text-foreground font-medium\">60K+</strong> developers.\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/avatar/avatar-23.html",
          "target": "components/ui/avatar-23.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"bg-background flex items-center rounded-full border p-1 shadow-sm\"><div class=\"flex -space-x-1.5\"><img class=\"ring-background rounded-full ring-1\" src=\"/avatar-80-03.jpg\" width=\"${20}\" height=\"${20}\" alt=\"Avatar 01\" /><img class=\"ring-background rounded-full ring-1\" src=\"/avatar-80-04.jpg\" width=\"${20}\" height=\"${20}\" alt=\"Avatar 02\" /><img class=\"ring-background rounded-full ring-1\" src=\"/avatar-80-05.jpg\" width=\"${20}\" height=\"${20}\" alt=\"Avatar 03\" /><img class=\"ring-background rounded-full ring-1\" src=\"/avatar-80-06.jpg\" width=\"${20}\" height=\"${20}\" alt=\"Avatar 04\" /></div><p class=\"text-muted-foreground px-2 text-xs\">Trusted by <strong class=\"text-foreground font-medium\">60K+</strong>developers.\n      </p></div>\n</template>"
        },
        {
          "path": "registry/default/components/avatar/avatar-23.wxml",
          "target": "components/ui/avatar-23/avatar-23.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"bg-background flex items-center rounded-full border p-1 shadow-sm\"><view class=\"flex -space-x-1.5\"><image class=\"ring-background rounded-full ring-1\" src=\"/avatar-80-03.jpg\" width=\"{{20}}\" height=\"{{20}}\" alt=\"Avatar 01\" /><image class=\"ring-background rounded-full ring-1\" src=\"/avatar-80-04.jpg\" width=\"{{20}}\" height=\"{{20}}\" alt=\"Avatar 02\" /><image class=\"ring-background rounded-full ring-1\" src=\"/avatar-80-05.jpg\" width=\"{{20}}\" height=\"{{20}}\" alt=\"Avatar 03\" /><image class=\"ring-background rounded-full ring-1\" src=\"/avatar-80-06.jpg\" width=\"{{20}}\" height=\"{{20}}\" alt=\"Avatar 04\" /></view><text class=\"text-muted-foreground px-2 text-xs\">Trusted by <strong class=\"text-foreground font-medium\">60K+</strong>developers.\n      </text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "avatar",
          "avatar group"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "avatar-23",
          "group": "avatar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "avatar-23",
              "path": "registry/default/components/avatar/avatar-23.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "avatar-23",
              "path": "registry/default/components/avatar/avatar-23.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "avatar-23",
              "path": "registry/default/components/avatar/avatar-23.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "avatar-23",
              "path": "registry/default/components/avatar/avatar-23.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "avatars",
        "title": "Avatar · Profile Pattern"
      },
      "categories": [
        "avatars",
        "avatar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "badge-01",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/badge.json"
      ],
      "files": [
        {
          "path": "registry/default/components/badge/badge-01.tsx",
          "type": "registry:component",
          "target": "components/ui/badge-01.tsx",
          "content": "import { Badge } from '@timui/react'\n\nexport default function Component() {\n  return <Badge>Badge</Badge>\n}\n"
        },
        {
          "path": "registry/default/components/badge/badge-01.vue",
          "target": "components/ui/badge-01.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Badge } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Badge>Badge</Badge>\n</template>\n"
        },
        {
          "path": "registry/default/components/badge/badge-01.html",
          "target": "components/ui/badge-01.html",
          "type": "registry:component",
          "content": "<template>\n  <Badge>Badge</Badge>\n</template>"
        },
        {
          "path": "registry/default/components/badge/badge-01.wxml",
          "target": "components/ui/badge-01/badge-01.wxml",
          "type": "registry:component",
          "content": "<view>\n  <badge>Badge</badge>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "badge",
          "chip"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "badge-01",
          "group": "badge",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "badge-01",
              "path": "registry/default/components/badge/badge-01.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "badge-01",
              "path": "registry/default/components/badge/badge-01.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "badge-01",
              "path": "registry/default/components/badge/badge-01.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "badge-01",
              "path": "registry/default/components/badge/badge-01.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "badge",
        "title": "Badge · Basic badge"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "badge"
      ]
    },
    {
      "name": "badge-02",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/badge.json"
      ],
      "files": [
        {
          "path": "registry/default/components/badge/badge-02.tsx",
          "type": "registry:component",
          "target": "components/ui/badge-02.tsx",
          "content": "import { Badge } from '@timui/react'\n\nexport default function Component() {\n  return <Badge className=\"rounded\">Badge</Badge>\n}\n"
        },
        {
          "path": "registry/default/components/badge/badge-02.vue",
          "target": "components/ui/badge-02.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Badge } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Badge class=\"rounded\">Badge</Badge>\n</template>\n"
        },
        {
          "path": "registry/default/components/badge/badge-02.html",
          "target": "components/ui/badge-02.html",
          "type": "registry:component",
          "content": "<template>\n  <Badge class=\"rounded\">Badge</Badge>\n</template>"
        },
        {
          "path": "registry/default/components/badge/badge-02.wxml",
          "target": "components/ui/badge-02/badge-02.wxml",
          "type": "registry:component",
          "content": "<view>\n  <badge class=\"rounded\">Badge</badge>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "badge",
          "chip"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "badge-02",
          "group": "badge",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "badge-02",
              "path": "registry/default/components/badge/badge-02.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "badge-02",
              "path": "registry/default/components/badge/badge-02.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "badge-02",
              "path": "registry/default/components/badge/badge-02.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "badge-02",
              "path": "registry/default/components/badge/badge-02.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "badge",
        "title": "Badge · Rounded badge"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "badge"
      ]
    },
    {
      "name": "badge-03",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/badge.json"
      ],
      "files": [
        {
          "path": "registry/default/components/badge/badge-03.tsx",
          "type": "registry:component",
          "target": "components/ui/badge-03.tsx",
          "content": "import { Badge } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Badge>\n      <svg\n        className=\"-ms-0.5 opacity-60\"\n        width={12}\n        height={12}\n        viewBox=\"0 0 24 24\"\n        fill=\"none\"\n        stroke=\"currentColor\"\n        strokeWidth=\"2\"\n        strokeLinecap=\"round\"\n        strokeLinejoin=\"round\"\n        aria-hidden=\"true\"\n      >\n        <path d=\"M13 2 3 14h9l-1 8 10-12h-9l1-8z\" />\n      </svg>\n      Badge\n    </Badge>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/badge/badge-03.vue",
          "target": "components/ui/badge-03.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Badge } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Badge><svg class=\"-ms-0.5 opacity-60\" :width=\"12\" :height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M13 2 3 14h9l-1 8 10-12h-9l1-8z\" /></svg>Badge\n    </Badge>\n</template>\n"
        },
        {
          "path": "registry/default/components/badge/badge-03.html",
          "target": "components/ui/badge-03.html",
          "type": "registry:component",
          "content": "<template>\n  <Badge><svg class=\"-ms-0.5 opacity-60\" width=\"${12}\" height=\"${12}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M13 2 3 14h9l-1 8 10-12h-9l1-8z\" /></svg>Badge\n    </Badge>\n</template>"
        },
        {
          "path": "registry/default/components/badge/badge-03.wxml",
          "target": "components/ui/badge-03/badge-03.wxml",
          "type": "registry:component",
          "content": "<view>\n  <badge><svg class=\"-ms-0.5 opacity-60\" width=\"{{12}}\" height=\"{{12}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M13 2 3 14h9l-1 8 10-12h-9l1-8z\" /></svg>Badge\n    </badge>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "badge",
          "chip"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "badge-03",
          "group": "badge",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "badge-03",
              "path": "registry/default/components/badge/badge-03.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "badge-03",
              "path": "registry/default/components/badge/badge-03.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "badge-03",
              "path": "registry/default/components/badge/badge-03.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "badge-03",
              "path": "registry/default/components/badge/badge-03.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "badge",
        "title": "Badge · With icon"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "badge"
      ]
    },
    {
      "name": "badge-04",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/badge.json"
      ],
      "files": [
        {
          "path": "registry/default/components/badge/badge-04.tsx",
          "type": "registry:component",
          "target": "components/ui/badge-04.tsx",
          "content": "import { Badge } from '@timui/react'\n\nexport default function Component() {\n  return <Badge className=\"min-w-5 px-1\">6</Badge>\n}\n"
        },
        {
          "path": "registry/default/components/badge/badge-04.vue",
          "target": "components/ui/badge-04.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Badge } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Badge class=\"min-w-5 px-1\">6</Badge>\n</template>\n"
        },
        {
          "path": "registry/default/components/badge/badge-04.html",
          "target": "components/ui/badge-04.html",
          "type": "registry:component",
          "content": "<template>\n  <Badge class=\"min-w-5 px-1\">6</Badge>\n</template>"
        },
        {
          "path": "registry/default/components/badge/badge-04.wxml",
          "target": "components/ui/badge-04/badge-04.wxml",
          "type": "registry:component",
          "content": "<view>\n  <badge class=\"min-w-5 px-1\">6</badge>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "badge",
          "chip",
          "counter"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "badge-04",
          "group": "badge",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "badge-04",
              "path": "registry/default/components/badge/badge-04.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "badge-04",
              "path": "registry/default/components/badge/badge-04.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "badge-04",
              "path": "registry/default/components/badge/badge-04.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "badge-04",
              "path": "registry/default/components/badge/badge-04.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "badge",
        "title": "Badge · Counter badge"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "badge"
      ]
    },
    {
      "name": "badge-05",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/badge.json"
      ],
      "files": [
        {
          "path": "registry/default/components/badge/badge-05.tsx",
          "type": "registry:component",
          "target": "components/ui/badge-05.tsx",
          "content": "import { Badge } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Badge asChild>\n      <a href=\"#\">Link</a>\n    </Badge>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/badge/badge-05.vue",
          "target": "components/ui/badge-05.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Badge } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Badge as-child><a href=\"#\">Link</a></Badge>\n</template>\n"
        },
        {
          "path": "registry/default/components/badge/badge-05.html",
          "target": "components/ui/badge-05.html",
          "type": "registry:component",
          "content": "<template>\n  <Badge aschild><a href=\"#\">Link</a></Badge>\n</template>"
        },
        {
          "path": "registry/default/components/badge/badge-05.wxml",
          "target": "components/ui/badge-05/badge-05.wxml",
          "type": "registry:component",
          "content": "<view>\n  <badge aschild><a href=\"#\">Link</a></badge>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "badge",
          "chip"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "badge-05",
          "group": "badge",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "badge-05",
              "path": "registry/default/components/badge/badge-05.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "badge-05",
              "path": "registry/default/components/badge/badge-05.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "badge-05",
              "path": "registry/default/components/badge/badge-05.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "badge-05",
              "path": "registry/default/components/badge/badge-05.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "badge",
        "title": "Badge · Link badge"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "badge"
      ]
    },
    {
      "name": "badge-06",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/badge.json"
      ],
      "files": [
        {
          "path": "registry/default/components/badge/badge-06.tsx",
          "type": "registry:component",
          "target": "components/ui/badge-06.tsx",
          "content": "import { Badge } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Badge className=\"items-baseline gap-1.5\">\n      Badge\n      <span className=\"text-primary-foreground/60 text-[0.625rem] font-medium\">73</span>\n    </Badge>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/badge/badge-06.vue",
          "target": "components/ui/badge-06.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Badge } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Badge class=\"items-baseline gap-1.5\">Badge\n      <span class=\"text-primary-foreground/60 text-[0.625rem] font-medium\">73</span></Badge>\n</template>\n"
        },
        {
          "path": "registry/default/components/badge/badge-06.html",
          "target": "components/ui/badge-06.html",
          "type": "registry:component",
          "content": "<template>\n  <Badge class=\"items-baseline gap-1.5\">Badge\n      <span class=\"text-primary-foreground/60 text-[0.625rem] font-medium\">73</span></Badge>\n</template>"
        },
        {
          "path": "registry/default/components/badge/badge-06.wxml",
          "target": "components/ui/badge-06/badge-06.wxml",
          "type": "registry:component",
          "content": "<view>\n  <badge class=\"items-baseline gap-1.5\">Badge\n      <text class=\"text-primary-foreground/60 text-[0.625rem] font-medium\">73</text></badge>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "badge",
          "chip",
          "counter"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "badge-06",
          "group": "badge",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "badge-06",
              "path": "registry/default/components/badge/badge-06.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "badge-06",
              "path": "registry/default/components/badge/badge-06.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "badge-06",
              "path": "registry/default/components/badge/badge-06.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "badge-06",
              "path": "registry/default/components/badge/badge-06.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "badge",
        "title": "Badge · With secondary value"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "badge"
      ]
    },
    {
      "name": "badge-07",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/badge.json"
      ],
      "files": [
        {
          "path": "registry/default/components/badge/badge-07.tsx",
          "type": "registry:component",
          "target": "components/ui/badge-07.tsx",
          "content": "import { Badge } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Badge variant=\"outline\" className=\"gap-1\">\n      <svg\n        className=\"text-emerald-500\"\n        width={12}\n        height={12}\n        viewBox=\"0 0 24 24\"\n        fill=\"none\"\n        stroke=\"currentColor\"\n        strokeWidth=\"2\"\n        strokeLinecap=\"round\"\n        strokeLinejoin=\"round\"\n        aria-hidden=\"true\"\n      >\n        <path d=\"M20 6 9 17l-5-5\" />\n      </svg>\n      Badge\n    </Badge>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/badge/badge-07.vue",
          "target": "components/ui/badge-07.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Badge } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Badge variant=\"outline\" class=\"gap-1\"><svg class=\"text-emerald-500\" :width=\"12\" :height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M20 6 9 17l-5-5\" /></svg>Badge\n    </Badge>\n</template>\n"
        },
        {
          "path": "registry/default/components/badge/badge-07.html",
          "target": "components/ui/badge-07.html",
          "type": "registry:component",
          "content": "<template>\n  <Badge variant=\"outline\" class=\"gap-1\"><svg class=\"text-emerald-500\" width=\"${12}\" height=\"${12}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M20 6 9 17l-5-5\" /></svg>Badge\n    </Badge>\n</template>"
        },
        {
          "path": "registry/default/components/badge/badge-07.wxml",
          "target": "components/ui/badge-07/badge-07.wxml",
          "type": "registry:component",
          "content": "<view>\n  <badge variant=\"outline\" class=\"gap-1\"><svg class=\"text-emerald-500\" width=\"{{12}}\" height=\"{{12}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M20 6 9 17l-5-5\" /></svg>Badge\n    </badge>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "badge",
          "chip",
          "status"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "badge-07",
          "group": "badge",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "badge-07",
              "path": "registry/default/components/badge/badge-07.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "badge-07",
              "path": "registry/default/components/badge/badge-07.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "badge-07",
              "path": "registry/default/components/badge/badge-07.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "badge-07",
              "path": "registry/default/components/badge/badge-07.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "badge",
        "title": "Badge · With icon"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "badge"
      ]
    },
    {
      "name": "badge-08",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/badge.json"
      ],
      "files": [
        {
          "path": "registry/default/components/badge/badge-08.tsx",
          "type": "registry:component",
          "target": "components/ui/badge-08.tsx",
          "content": "import { Badge } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Badge variant=\"outline\" className=\"gap-1.5\">\n      <span className=\"size-1.5 rounded-full bg-emerald-500\" aria-hidden=\"true\"></span>\n      Badge\n    </Badge>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/badge/badge-08.vue",
          "target": "components/ui/badge-08.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Badge } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Badge variant=\"outline\" class=\"gap-1.5\"><span class=\"size-1.5 rounded-full bg-emerald-500\" aria-hidden=\"true\"></span>Badge\n    </Badge>\n</template>\n"
        },
        {
          "path": "registry/default/components/badge/badge-08.html",
          "target": "components/ui/badge-08.html",
          "type": "registry:component",
          "content": "<template>\n  <Badge variant=\"outline\" class=\"gap-1.5\"><span class=\"size-1.5 rounded-full bg-emerald-500\" aria-hidden=\"true\"></span>Badge\n    </Badge>\n</template>"
        },
        {
          "path": "registry/default/components/badge/badge-08.wxml",
          "target": "components/ui/badge-08/badge-08.wxml",
          "type": "registry:component",
          "content": "<view>\n  <badge variant=\"outline\" class=\"gap-1.5\"><text class=\"size-1.5 rounded-full bg-emerald-500\" aria-hidden=\"true\"></text>Badge\n    </badge>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "badge",
          "chip",
          "status"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "badge-08",
          "group": "badge",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "badge-08",
              "path": "registry/default/components/badge/badge-08.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "badge-08",
              "path": "registry/default/components/badge/badge-08.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "badge-08",
              "path": "registry/default/components/badge/badge-08.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "badge-08",
              "path": "registry/default/components/badge/badge-08.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "badge",
        "title": "Badge · Rounded badge"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "badge"
      ]
    },
    {
      "name": "badge-09",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/badge.json"
      ],
      "files": [
        {
          "path": "registry/default/components/badge/badge-09.tsx",
          "type": "registry:component",
          "target": "components/ui/badge-09.tsx",
          "content": "import { Badge } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Badge variant=\"outline\" className=\"gap-1.5\">\n      <span className=\"size-1.5 rounded-full bg-amber-500\" aria-hidden=\"true\"></span>\n      Badge\n    </Badge>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/badge/badge-09.vue",
          "target": "components/ui/badge-09.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Badge } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Badge variant=\"outline\" class=\"gap-1.5\"><span class=\"size-1.5 rounded-full bg-amber-500\" aria-hidden=\"true\"></span>Badge\n    </Badge>\n</template>\n"
        },
        {
          "path": "registry/default/components/badge/badge-09.html",
          "target": "components/ui/badge-09.html",
          "type": "registry:component",
          "content": "<template>\n  <Badge variant=\"outline\" class=\"gap-1.5\"><span class=\"size-1.5 rounded-full bg-amber-500\" aria-hidden=\"true\"></span>Badge\n    </Badge>\n</template>"
        },
        {
          "path": "registry/default/components/badge/badge-09.wxml",
          "target": "components/ui/badge-09/badge-09.wxml",
          "type": "registry:component",
          "content": "<view>\n  <badge variant=\"outline\" class=\"gap-1.5\"><text class=\"size-1.5 rounded-full bg-amber-500\" aria-hidden=\"true\"></text>Badge\n    </badge>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "badge",
          "chip",
          "status"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "badge-09",
          "group": "badge",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "badge-09",
              "path": "registry/default/components/badge/badge-09.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "badge-09",
              "path": "registry/default/components/badge/badge-09.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "badge-09",
              "path": "registry/default/components/badge/badge-09.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "badge-09",
              "path": "registry/default/components/badge/badge-09.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "badge",
        "title": "Badge · Rounded badge"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "badge"
      ]
    },
    {
      "name": "badge-10",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/badge.json"
      ],
      "files": [
        {
          "path": "registry/default/components/badge/badge-10.tsx",
          "type": "registry:component",
          "target": "components/ui/badge-10.tsx",
          "content": "import { Badge } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Badge variant=\"outline\" className=\"gap-1.5\">\n      <span className=\"size-1.5 rounded-full bg-red-500\" aria-hidden=\"true\"></span>\n      Badge\n    </Badge>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/badge/badge-10.vue",
          "target": "components/ui/badge-10.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Badge } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Badge variant=\"outline\" class=\"gap-1.5\"><span class=\"size-1.5 rounded-full bg-red-500\" aria-hidden=\"true\"></span>Badge\n    </Badge>\n</template>\n"
        },
        {
          "path": "registry/default/components/badge/badge-10.html",
          "target": "components/ui/badge-10.html",
          "type": "registry:component",
          "content": "<template>\n  <Badge variant=\"outline\" class=\"gap-1.5\"><span class=\"size-1.5 rounded-full bg-red-500\" aria-hidden=\"true\"></span>Badge\n    </Badge>\n</template>"
        },
        {
          "path": "registry/default/components/badge/badge-10.wxml",
          "target": "components/ui/badge-10/badge-10.wxml",
          "type": "registry:component",
          "content": "<view>\n  <badge variant=\"outline\" class=\"gap-1.5\"><text class=\"size-1.5 rounded-full bg-red-500\" aria-hidden=\"true\"></text>Badge\n    </badge>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "badge",
          "chip",
          "status"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "badge-10",
          "group": "badge",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "badge-10",
              "path": "registry/default/components/badge/badge-10.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "badge-10",
              "path": "registry/default/components/badge/badge-10.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "badge-10",
              "path": "registry/default/components/badge/badge-10.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "badge-10",
              "path": "registry/default/components/badge/badge-10.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "badge",
        "title": "Badge · Rounded badge"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "badge"
      ]
    },
    {
      "name": "badge-11",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/badge.json"
      ],
      "files": [
        {
          "path": "registry/default/components/badge/badge-11.tsx",
          "type": "registry:component",
          "target": "components/ui/badge-11.tsx",
          "content": "import { useId } from 'react'\nimport { Badge, Checkbox } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <Badge className=\"has-data-[state=unchecked]:bg-muted has-data-[state=unchecked]:text-muted-foreground has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative outline-none has-focus-visible:ring-[3px]\">\n      <Checkbox id={id} className=\"peer sr-only after:absolute after:inset-0\" defaultChecked />\n      <svg\n        className=\"hidden peer-data-[state=checked]:block\"\n        width={12}\n        height={12}\n        viewBox=\"0 0 24 24\"\n        fill=\"none\"\n        stroke=\"currentColor\"\n        strokeWidth=\"2\"\n        strokeLinecap=\"round\"\n        strokeLinejoin=\"round\"\n        aria-hidden=\"true\"\n      >\n        <path d=\"M20 6 9 17l-5-5\" />\n      </svg>\n      <label htmlFor={id} className=\"cursor-pointer select-none after:absolute after:inset-0\">\n        Selectable\n      </label>\n    </Badge>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/badge/badge-11.vue",
          "target": "components/ui/badge-11.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Badge } from '@timui/vue';\nimport { Checkbox } from '@timui/vue';\n\n\n\n\n\nconst id = 'badge-11';\n\n</script>\n\n<template>\n  <Badge class=\"has-data-[state=unchecked]:bg-muted has-data-[state=unchecked]:text-muted-foreground has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative outline-none has-focus-visible:ring-[3px]\"><Checkbox :id=\"id\" class=\"peer sr-only after:absolute after:inset-0\" defaultChecked /><svg class=\"hidden peer-data-[state=checked]:block\" :width=\"12\" :height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M20 6 9 17l-5-5\" /></svg><label :for=\"id\" class=\"cursor-pointer select-none after:absolute after:inset-0\">Selectable\n      </label></Badge>\n</template>\n"
        },
        {
          "path": "registry/default/components/badge/badge-11.html",
          "target": "components/ui/badge-11.html",
          "type": "registry:component",
          "content": "<template>\n  <Badge class=\"has-data-[state=unchecked]:bg-muted has-data-[state=unchecked]:text-muted-foreground has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative outline-none has-focus-visible:ring-[3px]\"><Checkbox id=\"${id}\" class=\"peer sr-only after:absolute after:inset-0\" defaultchecked /><svg class=\"hidden peer-data-[state=checked]:block\" width=\"${12}\" height=\"${12}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M20 6 9 17l-5-5\" /></svg><label htmlfor=\"${id}\" class=\"cursor-pointer select-none after:absolute after:inset-0\">Selectable\n      </label></Badge>\n</template>"
        },
        {
          "path": "registry/default/components/badge/badge-11.wxml",
          "target": "components/ui/badge-11/badge-11.wxml",
          "type": "registry:component",
          "content": "<view>\n  <badge class=\"has-data-[state=unchecked]:bg-muted has-data-[state=unchecked]:text-muted-foreground has-focus-visible:border-ring has-focus-visible:ring-ring/50 relative outline-none has-focus-visible:ring-[3px]\"><checkbox id=\"{{id}}\" class=\"peer sr-only after:absolute after:inset-0\" defaultchecked /><svg class=\"hidden peer-data-[state=checked]:block\" width=\"{{12}}\" height=\"{{12}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M20 6 9 17l-5-5\" /></svg><label htmlfor=\"{{id}}\" class=\"cursor-pointer select-none after:absolute after:inset-0\">Selectable\n      </label></badge>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "badge",
          "chip",
          "checkbox"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "badge-11",
          "group": "badge",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "badge-11",
              "path": "registry/default/components/badge/badge-11.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "badge-11",
              "path": "registry/default/components/badge/badge-11.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "badge-11",
              "path": "registry/default/components/badge/badge-11.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "badge-11",
              "path": "registry/default/components/badge/badge-11.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "badge",
        "title": "Badge · With icon"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "badge"
      ]
    },
    {
      "name": "badge-12",
      "type": "registry:component",
      "files": [
        {
          "path": "registry/default/components/badge/badge-12.tsx",
          "type": "registry:component",
          "target": "components/ui/badge-12.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Badge } from '@timui/react'\n\nexport default function Component() {\n  const [isActive, setIsActive] = useState(true)\n\n  if (!isActive) return null\n\n  return (\n    <Badge className=\"gap-0\">\n      Removable\n      <button\n        className=\"focus-visible:border-ring focus-visible:ring-ring/50 text-primary-foreground/60 hover:text-primary-foreground -my-px -ms-px -me-1.5 inline-flex size-5 shrink-0 cursor-pointer items-center justify-center rounded-[inherit] p-0 transition-[color,box-shadow] outline-none focus-visible:ring-[3px]\"\n        onClick={() => setIsActive(false)}\n      >\n        <svg\n          width={12}\n          height={12}\n          viewBox=\"0 0 24 24\"\n          fill=\"none\"\n          stroke=\"currentColor\"\n          strokeWidth=\"2\"\n          strokeLinecap=\"round\"\n          strokeLinejoin=\"round\"\n          aria-hidden=\"true\"\n        >\n          <path d=\"M18 6 6 18\" />\n          <path d=\"M6 6 18 18\" />\n        </svg>\n      </button>\n    </Badge>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/badge/badge-12.vue",
          "target": "components/ui/badge-12.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Badge } from '@timui/vue';\n\n\n\nconst isActive = ref(true);\n\n\nfunction setIsActive(next: typeof isActive.value | ((prev: typeof isActive.value) => typeof isActive.value)) {\n  isActive.value = typeof next === 'function'\n    ? (next as (prev: typeof isActive.value) => typeof isActive.value)(isActive.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <Badge class=\"gap-0\">Removable\n      <button class=\"focus-visible:border-ring focus-visible:ring-ring/50 text-primary-foreground/60 hover:text-primary-foreground -my-px -ms-px -me-1.5 inline-flex size-5 shrink-0 cursor-pointer items-center justify-center rounded-[inherit] p-0 transition-[color,box-shadow] outline-none focus-visible:ring-[3px]\" @click=\"setIsActive(false)\"><svg :width=\"12\" :height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M18 6 6 18\" /><path d=\"M6 6 18 18\" /></svg></button></Badge>\n</template>\n"
        },
        {
          "path": "registry/default/components/badge/badge-12.html",
          "target": "components/ui/badge-12.html",
          "type": "registry:component",
          "content": "<template>\n  <Badge class=\"gap-0\">Removable\n      <button class=\"focus-visible:border-ring focus-visible:ring-ring/50 text-primary-foreground/60 hover:text-primary-foreground -my-px -ms-px -me-1.5 inline-flex size-5 shrink-0 cursor-pointer items-center justify-center rounded-[inherit] p-0 transition-[color,box-shadow] outline-none focus-visible:ring-[3px]\" on-click=\"${() => setIsActive(false)}\"><svg width=\"${12}\" height=\"${12}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M18 6 6 18\" /><path d=\"M6 6 18 18\" /></svg></button></Badge>\n</template>"
        },
        {
          "path": "registry/default/components/badge/badge-12.wxml",
          "target": "components/ui/badge-12/badge-12.wxml",
          "type": "registry:component",
          "content": "<view>\n  <badge class=\"gap-0\">Removable\n      <button class=\"focus-visible:border-ring focus-visible:ring-ring/50 text-primary-foreground/60 hover:text-primary-foreground -my-px -ms-px -me-1.5 inline-flex size-5 shrink-0 cursor-pointer items-center justify-center rounded-[inherit] p-0 transition-[color,box-shadow] outline-none focus-visible:ring-[3px]\" bindtap=\"setIsActive(false)\"><svg width=\"{{12}}\" height=\"{{12}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M18 6 6 18\" /><path d=\"M6 6 18 18\" /></svg></button></badge>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "badge",
          "chip"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "badge-12",
          "group": "badge",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "badge-12",
              "path": "registry/default/components/badge/badge-12.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "badge-12",
              "path": "registry/default/components/badge/badge-12.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "badge-12",
              "path": "registry/default/components/badge/badge-12.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "badge-12",
              "path": "registry/default/components/badge/badge-12.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "badge",
        "title": "Badge · Rounded badge"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "badge"
      ]
    },
    {
      "name": "badge-13",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/badge.json"
      ],
      "files": [
        {
          "path": "registry/default/components/badge/badge-13.tsx",
          "type": "registry:component",
          "target": "components/ui/badge-13.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Badge } from '@timui/react'\n\nexport default function Component() {\n  const [isActive, setIsActive] = useState(true)\n\n  if (!isActive) return null\n\n  return (\n    <Badge variant=\"outline\" className=\"gap-0 rounded-md px-2 py-1\">\n      Tag\n      <button\n        className=\"focus-visible:border-ring focus-visible:ring-ring/50 text-foreground/60 hover:text-foreground -my-[5px] -ms-0.5 -me-2 inline-flex size-7 shrink-0 cursor-pointer items-center justify-center rounded-[inherit] p-0 transition-[color,box-shadow] outline-none focus-visible:ring-[3px]\"\n        onClick={() => setIsActive(false)}\n        aria-label=\"Delete\"\n      >\n        <svg\n          width={14}\n          height={14}\n          viewBox=\"0 0 24 24\"\n          fill=\"none\"\n          stroke=\"currentColor\"\n          strokeWidth=\"2\"\n          strokeLinecap=\"round\"\n          strokeLinejoin=\"round\"\n          aria-hidden=\"true\"\n        >\n          <path d=\"M18 6 6 18\" />\n          <path d=\"M6 6 18 18\" />\n        </svg>\n      </button>\n    </Badge>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/badge/badge-13.vue",
          "target": "components/ui/badge-13.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Badge } from '@timui/vue';\n\n\n\nconst isActive = ref(true);\n\n\nfunction setIsActive(next: typeof isActive.value | ((prev: typeof isActive.value) => typeof isActive.value)) {\n  isActive.value = typeof next === 'function'\n    ? (next as (prev: typeof isActive.value) => typeof isActive.value)(isActive.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <Badge variant=\"outline\" class=\"gap-0 rounded-md px-2 py-1\">Tag\n      <button class=\"focus-visible:border-ring focus-visible:ring-ring/50 text-foreground/60 hover:text-foreground -my-[5px] -ms-0.5 -me-2 inline-flex size-7 shrink-0 cursor-pointer items-center justify-center rounded-[inherit] p-0 transition-[color,box-shadow] outline-none focus-visible:ring-[3px]\" @click=\"setIsActive(false)\" aria-label=\"Delete\"><svg :width=\"14\" :height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M18 6 6 18\" /><path d=\"M6 6 18 18\" /></svg></button></Badge>\n</template>\n"
        },
        {
          "path": "registry/default/components/badge/badge-13.html",
          "target": "components/ui/badge-13.html",
          "type": "registry:component",
          "content": "<template>\n  <Badge variant=\"outline\" class=\"gap-0 rounded-md px-2 py-1\">Tag\n      <button class=\"focus-visible:border-ring focus-visible:ring-ring/50 text-foreground/60 hover:text-foreground -my-[5px] -ms-0.5 -me-2 inline-flex size-7 shrink-0 cursor-pointer items-center justify-center rounded-[inherit] p-0 transition-[color,box-shadow] outline-none focus-visible:ring-[3px]\" on-click=\"${() => setIsActive(false)}\" aria-label=\"Delete\"><svg width=\"${14}\" height=\"${14}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M18 6 6 18\" /><path d=\"M6 6 18 18\" /></svg></button></Badge>\n</template>"
        },
        {
          "path": "registry/default/components/badge/badge-13.wxml",
          "target": "components/ui/badge-13/badge-13.wxml",
          "type": "registry:component",
          "content": "<view>\n  <badge variant=\"outline\" class=\"gap-0 rounded-md px-2 py-1\">Tag\n      <button class=\"focus-visible:border-ring focus-visible:ring-ring/50 text-foreground/60 hover:text-foreground -my-[5px] -ms-0.5 -me-2 inline-flex size-7 shrink-0 cursor-pointer items-center justify-center rounded-[inherit] p-0 transition-[color,box-shadow] outline-none focus-visible:ring-[3px]\" bindtap=\"setIsActive(false)\" aria-label=\"Delete\"><svg width=\"{{14}}\" height=\"{{14}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M18 6 6 18\" /><path d=\"M6 6 18 18\" /></svg></button></badge>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "badge",
          "chip",
          "tag"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "badge-13",
          "group": "badge",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "badge-13",
              "path": "registry/default/components/badge/badge-13.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "badge-13",
              "path": "registry/default/components/badge/badge-13.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "badge-13",
              "path": "registry/default/components/badge/badge-13.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "badge-13",
              "path": "registry/default/components/badge/badge-13.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "badge",
        "title": "Badge · Rounded badge"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "badge"
      ]
    },
    {
      "name": "tabs-01",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/tabs.json"
      ],
      "files": [
        {
          "path": "registry/default/components/tabs/tabs-01.tsx",
          "type": "registry:component",
          "target": "components/ui/tabs-01.tsx",
          "content": "import { Tabs, TabsContent, TabsList, TabsTrigger } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Tabs defaultValue=\"tab-1\" className=\"items-center\">\n      <TabsList>\n        <TabsTrigger value=\"tab-1\">Tab 1</TabsTrigger>\n        <TabsTrigger value=\"tab-2\">Tab 2</TabsTrigger>\n        <TabsTrigger value=\"tab-3\">Tab 3</TabsTrigger>\n      </TabsList>\n      <TabsContent value=\"tab-1\">\n        <p className=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</p>\n      </TabsContent>\n      <TabsContent value=\"tab-2\">\n        <p className=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</p>\n      </TabsContent>\n      <TabsContent value=\"tab-3\">\n        <p className=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</p>\n      </TabsContent>\n    </Tabs>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-01.vue",
          "target": "components/ui/tabs-01.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Tabs } from '@timui/vue';\nimport { TabsContent } from '@timui/vue';\nimport { TabsList } from '@timui/vue';\nimport { TabsTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Tabs default-value=\"tab-1\" class=\"items-center\"><TabsList><TabsTrigger value=\"tab-1\">Tab 1</TabsTrigger><TabsTrigger value=\"tab-2\">Tab 2</TabsTrigger><TabsTrigger value=\"tab-3\">Tab 3</TabsTrigger></TabsList><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</p></TabsContent></Tabs>\n</template>\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-01.html",
          "target": "components/ui/tabs-01.html",
          "type": "registry:component",
          "content": "<template>\n  <Tabs default-value=\"tab-1\" class=\"items-center\"><TabsList><TabsTrigger value=\"tab-1\">Tab 1</TabsTrigger><TabsTrigger value=\"tab-2\">Tab 2</TabsTrigger><TabsTrigger value=\"tab-3\">Tab 3</TabsTrigger></TabsList><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</p></TabsContent></Tabs>\n</template>"
        },
        {
          "path": "registry/default/components/tabs/tabs-01.wxml",
          "target": "components/ui/tabs-01/tabs-01.wxml",
          "type": "registry:component",
          "content": "<view>\n  <tabs default-value=\"tab-1\" class=\"items-center\"><tabslist><tabstrigger value=\"tab-1\">Tab 1</tabstrigger><tabstrigger value=\"tab-2\">Tab 2</tabstrigger><tabstrigger value=\"tab-3\">Tab 3</tabstrigger></tabslist><tabscontent value=\"tab-1\"><text class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</text></tabscontent><tabscontent value=\"tab-2\"><text class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</text></tabscontent><tabscontent value=\"tab-3\"><text class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</text></tabscontent></tabs>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tabs",
          "radix"
        ],
        "colSpan": 2,
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tabs-01",
          "group": "tabs",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tabs-01",
              "path": "registry/default/components/tabs/tabs-01.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tabs-01",
              "path": "registry/default/components/tabs/tabs-01.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tabs-01",
              "path": "registry/default/components/tabs/tabs-01.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tabs-01",
              "path": "registry/default/components/tabs/tabs-01.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tabs",
        "title": "Tabs · Basic tabs"
      },
      "categories": [
        "tabs"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "tabs-02",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/tabs.json"
      ],
      "files": [
        {
          "path": "registry/default/components/tabs/tabs-02.tsx",
          "type": "registry:component",
          "target": "components/ui/tabs-02.tsx",
          "content": "import { Tabs, TabsContent, TabsList, TabsTrigger } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Tabs defaultValue=\"tab-1\" className=\"items-center\">\n      <TabsList className=\"bg-transparent\">\n        <TabsTrigger\n          value=\"tab-1\"\n          className=\"data-[state=active]:bg-muted data-[state=active]:shadow-none\"\n        >\n          Tab 1\n        </TabsTrigger>\n        <TabsTrigger\n          value=\"tab-2\"\n          className=\"data-[state=active]:bg-muted data-[state=active]:shadow-none\"\n        >\n          Tab 2\n        </TabsTrigger>\n        <TabsTrigger\n          value=\"tab-3\"\n          className=\"data-[state=active]:bg-muted data-[state=active]:shadow-none\"\n        >\n          Tab 3\n        </TabsTrigger>\n      </TabsList>\n      <TabsContent value=\"tab-1\">\n        <p className=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</p>\n      </TabsContent>\n      <TabsContent value=\"tab-2\">\n        <p className=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</p>\n      </TabsContent>\n      <TabsContent value=\"tab-3\">\n        <p className=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</p>\n      </TabsContent>\n    </Tabs>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-02.vue",
          "target": "components/ui/tabs-02.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Tabs } from '@timui/vue';\nimport { TabsContent } from '@timui/vue';\nimport { TabsList } from '@timui/vue';\nimport { TabsTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Tabs default-value=\"tab-1\" class=\"items-center\"><TabsList class=\"bg-transparent\"><TabsTrigger value=\"tab-1\" class=\"data-[state=active]:bg-muted data-[state=active]:shadow-none\">Tab 1\n        </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"data-[state=active]:bg-muted data-[state=active]:shadow-none\">Tab 2\n        </TabsTrigger><TabsTrigger value=\"tab-3\" class=\"data-[state=active]:bg-muted data-[state=active]:shadow-none\">Tab 3\n        </TabsTrigger></TabsList><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</p></TabsContent></Tabs>\n</template>\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-02.html",
          "target": "components/ui/tabs-02.html",
          "type": "registry:component",
          "content": "<template>\n  <Tabs default-value=\"tab-1\" class=\"items-center\"><TabsList class=\"bg-transparent\"><TabsTrigger value=\"tab-1\" class=\"data-[state=active]:bg-muted data-[state=active]:shadow-none\">Tab 1\n        </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"data-[state=active]:bg-muted data-[state=active]:shadow-none\">Tab 2\n        </TabsTrigger><TabsTrigger value=\"tab-3\" class=\"data-[state=active]:bg-muted data-[state=active]:shadow-none\">Tab 3\n        </TabsTrigger></TabsList><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</p></TabsContent></Tabs>\n</template>"
        },
        {
          "path": "registry/default/components/tabs/tabs-02.wxml",
          "target": "components/ui/tabs-02/tabs-02.wxml",
          "type": "registry:component",
          "content": "<view>\n  <tabs default-value=\"tab-1\" class=\"items-center\"><tabslist class=\"bg-transparent\"><tabstrigger value=\"tab-1\" class=\"data-[state=active]:bg-muted data-[state=active]:shadow-none\">Tab 1\n        </tabstrigger><tabstrigger value=\"tab-2\" class=\"data-[state=active]:bg-muted data-[state=active]:shadow-none\">Tab 2\n        </tabstrigger><tabstrigger value=\"tab-3\" class=\"data-[state=active]:bg-muted data-[state=active]:shadow-none\">Tab 3\n        </tabstrigger></tabslist><tabscontent value=\"tab-1\"><text class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</text></tabscontent><tabscontent value=\"tab-2\"><text class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</text></tabscontent><tabscontent value=\"tab-3\"><text class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</text></tabscontent></tabs>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tabs",
          "radix"
        ],
        "colSpan": 2,
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tabs-02",
          "group": "tabs",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tabs-02",
              "path": "registry/default/components/tabs/tabs-02.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tabs-02",
              "path": "registry/default/components/tabs/tabs-02.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tabs-02",
              "path": "registry/default/components/tabs/tabs-02.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tabs-02",
              "path": "registry/default/components/tabs/tabs-02.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tabs",
        "title": "Tabs · Basic tabs"
      },
      "categories": [
        "tabs"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "tabs-03",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/tabs.json"
      ],
      "files": [
        {
          "path": "registry/default/components/tabs/tabs-03.tsx",
          "type": "registry:component",
          "target": "components/ui/tabs-03.tsx",
          "content": "import { Tabs, TabsContent, TabsList, TabsTrigger } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Tabs defaultValue=\"tab-1\" className=\"items-center\">\n      <TabsList className=\"gap-1 bg-transparent\">\n        <TabsTrigger\n          value=\"tab-1\"\n          className=\"data-[state=active]:bg-primary data-[state=active]:text-primary-foreground rounded-full data-[state=active]:shadow-none\"\n        >\n          Tab 1\n        </TabsTrigger>\n        <TabsTrigger\n          value=\"tab-2\"\n          className=\"data-[state=active]:bg-primary data-[state=active]:text-primary-foreground rounded-full data-[state=active]:shadow-none\"\n        >\n          Tab 2\n        </TabsTrigger>\n        <TabsTrigger\n          value=\"tab-3\"\n          className=\"data-[state=active]:bg-primary data-[state=active]:text-primary-foreground rounded-full data-[state=active]:shadow-none\"\n        >\n          Tab 3\n        </TabsTrigger>\n      </TabsList>\n      <TabsContent value=\"tab-1\">\n        <p className=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</p>\n      </TabsContent>\n      <TabsContent value=\"tab-2\">\n        <p className=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</p>\n      </TabsContent>\n      <TabsContent value=\"tab-3\">\n        <p className=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</p>\n      </TabsContent>\n    </Tabs>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-03.vue",
          "target": "components/ui/tabs-03.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Tabs } from '@timui/vue';\nimport { TabsContent } from '@timui/vue';\nimport { TabsList } from '@timui/vue';\nimport { TabsTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Tabs default-value=\"tab-1\" class=\"items-center\"><TabsList class=\"gap-1 bg-transparent\"><TabsTrigger value=\"tab-1\" class=\"data-[state=active]:bg-primary data-[state=active]:text-primary-foreground rounded-full data-[state=active]:shadow-none\">Tab 1\n        </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"data-[state=active]:bg-primary data-[state=active]:text-primary-foreground rounded-full data-[state=active]:shadow-none\">Tab 2\n        </TabsTrigger><TabsTrigger value=\"tab-3\" class=\"data-[state=active]:bg-primary data-[state=active]:text-primary-foreground rounded-full data-[state=active]:shadow-none\">Tab 3\n        </TabsTrigger></TabsList><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</p></TabsContent></Tabs>\n</template>\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-03.html",
          "target": "components/ui/tabs-03.html",
          "type": "registry:component",
          "content": "<template>\n  <Tabs default-value=\"tab-1\" class=\"items-center\"><TabsList class=\"gap-1 bg-transparent\"><TabsTrigger value=\"tab-1\" class=\"data-[state=active]:bg-primary data-[state=active]:text-primary-foreground rounded-full data-[state=active]:shadow-none\">Tab 1\n        </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"data-[state=active]:bg-primary data-[state=active]:text-primary-foreground rounded-full data-[state=active]:shadow-none\">Tab 2\n        </TabsTrigger><TabsTrigger value=\"tab-3\" class=\"data-[state=active]:bg-primary data-[state=active]:text-primary-foreground rounded-full data-[state=active]:shadow-none\">Tab 3\n        </TabsTrigger></TabsList><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</p></TabsContent></Tabs>\n</template>"
        },
        {
          "path": "registry/default/components/tabs/tabs-03.wxml",
          "target": "components/ui/tabs-03/tabs-03.wxml",
          "type": "registry:component",
          "content": "<view>\n  <tabs default-value=\"tab-1\" class=\"items-center\"><tabslist class=\"gap-1 bg-transparent\"><tabstrigger value=\"tab-1\" class=\"data-[state=active]:bg-primary data-[state=active]:text-primary-foreground rounded-full data-[state=active]:shadow-none\">Tab 1\n        </tabstrigger><tabstrigger value=\"tab-2\" class=\"data-[state=active]:bg-primary data-[state=active]:text-primary-foreground rounded-full data-[state=active]:shadow-none\">Tab 2\n        </tabstrigger><tabstrigger value=\"tab-3\" class=\"data-[state=active]:bg-primary data-[state=active]:text-primary-foreground rounded-full data-[state=active]:shadow-none\">Tab 3\n        </tabstrigger></tabslist><tabscontent value=\"tab-1\"><text class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</text></tabscontent><tabscontent value=\"tab-2\"><text class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</text></tabscontent><tabscontent value=\"tab-3\"><text class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</text></tabscontent></tabs>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tabs",
          "radix"
        ],
        "colSpan": 2,
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tabs-03",
          "group": "tabs",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tabs-03",
              "path": "registry/default/components/tabs/tabs-03.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tabs-03",
              "path": "registry/default/components/tabs/tabs-03.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tabs-03",
              "path": "registry/default/components/tabs/tabs-03.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tabs-03",
              "path": "registry/default/components/tabs/tabs-03.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tabs",
        "title": "Tabs · Basic tabs"
      },
      "categories": [
        "tabs"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "tabs-04",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/tabs.json"
      ],
      "files": [
        {
          "path": "registry/default/components/tabs/tabs-04.tsx",
          "type": "registry:component",
          "target": "components/ui/tabs-04.tsx",
          "content": "import { Tabs, TabsContent, TabsList, TabsTrigger } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Tabs defaultValue=\"tab-1\" className=\"items-center\">\n      <TabsList className=\"h-auto rounded-none border-b bg-transparent p-0\">\n        <TabsTrigger\n          value=\"tab-1\"\n          className=\"data-[state=active]:after:bg-primary relative rounded-none py-2 after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"\n        >\n          Tab 1\n        </TabsTrigger>\n        <TabsTrigger\n          value=\"tab-2\"\n          className=\"data-[state=active]:after:bg-primary relative rounded-none py-2 after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"\n        >\n          Tab 2\n        </TabsTrigger>\n        <TabsTrigger\n          value=\"tab-3\"\n          className=\"data-[state=active]:after:bg-primary relative rounded-none py-2 after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"\n        >\n          Tab 3\n        </TabsTrigger>\n      </TabsList>\n      <TabsContent value=\"tab-1\">\n        <p className=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</p>\n      </TabsContent>\n      <TabsContent value=\"tab-2\">\n        <p className=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</p>\n      </TabsContent>\n      <TabsContent value=\"tab-3\">\n        <p className=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</p>\n      </TabsContent>\n    </Tabs>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-04.vue",
          "target": "components/ui/tabs-04.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Tabs } from '@timui/vue';\nimport { TabsContent } from '@timui/vue';\nimport { TabsList } from '@timui/vue';\nimport { TabsTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Tabs default-value=\"tab-1\" class=\"items-center\"><TabsList class=\"h-auto rounded-none border-b bg-transparent p-0\"><TabsTrigger value=\"tab-1\" class=\"data-[state=active]:after:bg-primary relative rounded-none py-2 after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\">Tab 1\n        </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"data-[state=active]:after:bg-primary relative rounded-none py-2 after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\">Tab 2\n        </TabsTrigger><TabsTrigger value=\"tab-3\" class=\"data-[state=active]:after:bg-primary relative rounded-none py-2 after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\">Tab 3\n        </TabsTrigger></TabsList><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</p></TabsContent></Tabs>\n</template>\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-04.html",
          "target": "components/ui/tabs-04.html",
          "type": "registry:component",
          "content": "<template>\n  <Tabs default-value=\"tab-1\" class=\"items-center\"><TabsList class=\"h-auto rounded-none border-b bg-transparent p-0\"><TabsTrigger value=\"tab-1\" class=\"data-[state=active]:after:bg-primary relative rounded-none py-2 after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\">Tab 1\n        </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"data-[state=active]:after:bg-primary relative rounded-none py-2 after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\">Tab 2\n        </TabsTrigger><TabsTrigger value=\"tab-3\" class=\"data-[state=active]:after:bg-primary relative rounded-none py-2 after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\">Tab 3\n        </TabsTrigger></TabsList><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</p></TabsContent></Tabs>\n</template>"
        },
        {
          "path": "registry/default/components/tabs/tabs-04.wxml",
          "target": "components/ui/tabs-04/tabs-04.wxml",
          "type": "registry:component",
          "content": "<view>\n  <tabs default-value=\"tab-1\" class=\"items-center\"><tabslist class=\"h-auto rounded-none border-b bg-transparent p-0\"><tabstrigger value=\"tab-1\" class=\"data-[state=active]:after:bg-primary relative rounded-none py-2 after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\">Tab 1\n        </tabstrigger><tabstrigger value=\"tab-2\" class=\"data-[state=active]:after:bg-primary relative rounded-none py-2 after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\">Tab 2\n        </tabstrigger><tabstrigger value=\"tab-3\" class=\"data-[state=active]:after:bg-primary relative rounded-none py-2 after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\">Tab 3\n        </tabstrigger></tabslist><tabscontent value=\"tab-1\"><text class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</text></tabscontent><tabscontent value=\"tab-2\"><text class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</text></tabscontent><tabscontent value=\"tab-3\"><text class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</text></tabscontent></tabs>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tabs",
          "radix"
        ],
        "colSpan": 2,
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tabs-04",
          "group": "tabs",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tabs-04",
              "path": "registry/default/components/tabs/tabs-04.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tabs-04",
              "path": "registry/default/components/tabs/tabs-04.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tabs-04",
              "path": "registry/default/components/tabs/tabs-04.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tabs-04",
              "path": "registry/default/components/tabs/tabs-04.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tabs",
        "title": "Tabs · Basic tabs"
      },
      "categories": [
        "tabs"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "tabs-05",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/tabs.json"
      ],
      "files": [
        {
          "path": "registry/default/components/tabs/tabs-05.tsx",
          "type": "registry:component",
          "target": "components/ui/tabs-05.tsx",
          "content": "import { Tabs, TabsContent, TabsList, TabsTrigger } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Tabs defaultValue=\"tab-1\" className=\"items-center\">\n      <TabsList className=\"text-foreground h-auto gap-2 rounded-none border-b bg-transparent px-0 py-1\">\n        <TabsTrigger\n          value=\"tab-1\"\n          className=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"\n        >\n          Tab 1\n        </TabsTrigger>\n        <TabsTrigger\n          value=\"tab-2\"\n          className=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"\n        >\n          Tab 2\n        </TabsTrigger>\n        <TabsTrigger\n          value=\"tab-3\"\n          className=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"\n        >\n          Tab 3\n        </TabsTrigger>\n      </TabsList>\n      <TabsContent value=\"tab-1\">\n        <p className=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</p>\n      </TabsContent>\n      <TabsContent value=\"tab-2\">\n        <p className=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</p>\n      </TabsContent>\n      <TabsContent value=\"tab-3\">\n        <p className=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</p>\n      </TabsContent>\n    </Tabs>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-05.vue",
          "target": "components/ui/tabs-05.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Tabs } from '@timui/vue';\nimport { TabsContent } from '@timui/vue';\nimport { TabsList } from '@timui/vue';\nimport { TabsTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Tabs default-value=\"tab-1\" class=\"items-center\"><TabsList class=\"text-foreground h-auto gap-2 rounded-none border-b bg-transparent px-0 py-1\"><TabsTrigger value=\"tab-1\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\">Tab 1\n        </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\">Tab 2\n        </TabsTrigger><TabsTrigger value=\"tab-3\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\">Tab 3\n        </TabsTrigger></TabsList><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</p></TabsContent></Tabs>\n</template>\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-05.html",
          "target": "components/ui/tabs-05.html",
          "type": "registry:component",
          "content": "<template>\n  <Tabs default-value=\"tab-1\" class=\"items-center\"><TabsList class=\"text-foreground h-auto gap-2 rounded-none border-b bg-transparent px-0 py-1\"><TabsTrigger value=\"tab-1\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\">Tab 1\n        </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\">Tab 2\n        </TabsTrigger><TabsTrigger value=\"tab-3\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\">Tab 3\n        </TabsTrigger></TabsList><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</p></TabsContent></Tabs>\n</template>"
        },
        {
          "path": "registry/default/components/tabs/tabs-05.wxml",
          "target": "components/ui/tabs-05/tabs-05.wxml",
          "type": "registry:component",
          "content": "<view>\n  <tabs default-value=\"tab-1\" class=\"items-center\"><tabslist class=\"text-foreground h-auto gap-2 rounded-none border-b bg-transparent px-0 py-1\"><tabstrigger value=\"tab-1\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\">Tab 1\n        </tabstrigger><tabstrigger value=\"tab-2\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\">Tab 2\n        </tabstrigger><tabstrigger value=\"tab-3\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\">Tab 3\n        </tabstrigger></tabslist><tabscontent value=\"tab-1\"><text class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</text></tabscontent><tabscontent value=\"tab-2\"><text class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</text></tabscontent><tabscontent value=\"tab-3\"><text class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</text></tabscontent></tabs>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tabs",
          "radix"
        ],
        "colSpan": 2,
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tabs-05",
          "group": "tabs",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tabs-05",
              "path": "registry/default/components/tabs/tabs-05.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tabs-05",
              "path": "registry/default/components/tabs/tabs-05.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tabs-05",
              "path": "registry/default/components/tabs/tabs-05.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tabs-05",
              "path": "registry/default/components/tabs/tabs-05.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tabs",
        "title": "Tabs · Basic tabs"
      },
      "categories": [
        "tabs"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "tabs-06",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/tabs.json"
      ],
      "files": [
        {
          "path": "registry/default/components/tabs/tabs-06.tsx",
          "type": "registry:component",
          "target": "components/ui/tabs-06.tsx",
          "content": "import { Tabs, TabsContent, TabsList, TabsTrigger } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Tabs defaultValue=\"tab-1\" className=\"items-center\">\n      <TabsList className=\"bg-background h-auto -space-x-px p-0 shadow-xs rtl:space-x-reverse\">\n        <TabsTrigger\n          value=\"tab-1\"\n          className=\"data-[state=active]:bg-muted data-[state=active]:after:bg-primary relative overflow-hidden rounded-none border py-2 after:pointer-events-none after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 first:rounded-s last:rounded-e\"\n        >\n          Tab 1\n        </TabsTrigger>\n        <TabsTrigger\n          value=\"tab-2\"\n          className=\"data-[state=active]:bg-muted data-[state=active]:after:bg-primary relative overflow-hidden rounded-none border py-2 after:pointer-events-none after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 first:rounded-s last:rounded-e\"\n        >\n          Tab 2\n        </TabsTrigger>\n        <TabsTrigger\n          value=\"tab-3\"\n          className=\"data-[state=active]:bg-muted data-[state=active]:after:bg-primary relative overflow-hidden rounded-none border py-2 after:pointer-events-none after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 first:rounded-s last:rounded-e\"\n        >\n          Tab 3\n        </TabsTrigger>\n      </TabsList>\n      <TabsContent value=\"tab-1\">\n        <p className=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</p>\n      </TabsContent>\n      <TabsContent value=\"tab-2\">\n        <p className=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</p>\n      </TabsContent>\n      <TabsContent value=\"tab-3\">\n        <p className=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</p>\n      </TabsContent>\n    </Tabs>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-06.vue",
          "target": "components/ui/tabs-06.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Tabs } from '@timui/vue';\nimport { TabsContent } from '@timui/vue';\nimport { TabsList } from '@timui/vue';\nimport { TabsTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Tabs default-value=\"tab-1\" class=\"items-center\"><TabsList class=\"bg-background h-auto -space-x-px p-0 shadow-xs rtl:space-x-reverse\"><TabsTrigger value=\"tab-1\" class=\"data-[state=active]:bg-muted data-[state=active]:after:bg-primary relative overflow-hidden rounded-none border py-2 after:pointer-events-none after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 first:rounded-s last:rounded-e\">Tab 1\n        </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"data-[state=active]:bg-muted data-[state=active]:after:bg-primary relative overflow-hidden rounded-none border py-2 after:pointer-events-none after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 first:rounded-s last:rounded-e\">Tab 2\n        </TabsTrigger><TabsTrigger value=\"tab-3\" class=\"data-[state=active]:bg-muted data-[state=active]:after:bg-primary relative overflow-hidden rounded-none border py-2 after:pointer-events-none after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 first:rounded-s last:rounded-e\">Tab 3\n        </TabsTrigger></TabsList><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</p></TabsContent></Tabs>\n</template>\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-06.html",
          "target": "components/ui/tabs-06.html",
          "type": "registry:component",
          "content": "<template>\n  <Tabs default-value=\"tab-1\" class=\"items-center\"><TabsList class=\"bg-background h-auto -space-x-px p-0 shadow-xs rtl:space-x-reverse\"><TabsTrigger value=\"tab-1\" class=\"data-[state=active]:bg-muted data-[state=active]:after:bg-primary relative overflow-hidden rounded-none border py-2 after:pointer-events-none after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 first:rounded-s last:rounded-e\">Tab 1\n        </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"data-[state=active]:bg-muted data-[state=active]:after:bg-primary relative overflow-hidden rounded-none border py-2 after:pointer-events-none after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 first:rounded-s last:rounded-e\">Tab 2\n        </TabsTrigger><TabsTrigger value=\"tab-3\" class=\"data-[state=active]:bg-muted data-[state=active]:after:bg-primary relative overflow-hidden rounded-none border py-2 after:pointer-events-none after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 first:rounded-s last:rounded-e\">Tab 3\n        </TabsTrigger></TabsList><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</p></TabsContent></Tabs>\n</template>"
        },
        {
          "path": "registry/default/components/tabs/tabs-06.wxml",
          "target": "components/ui/tabs-06/tabs-06.wxml",
          "type": "registry:component",
          "content": "<view>\n  <tabs default-value=\"tab-1\" class=\"items-center\"><tabslist class=\"bg-background h-auto -space-x-px p-0 shadow-xs rtl:space-x-reverse\"><tabstrigger value=\"tab-1\" class=\"data-[state=active]:bg-muted data-[state=active]:after:bg-primary relative overflow-hidden rounded-none border py-2 after:pointer-events-none after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 first:rounded-s last:rounded-e\">Tab 1\n        </tabstrigger><tabstrigger value=\"tab-2\" class=\"data-[state=active]:bg-muted data-[state=active]:after:bg-primary relative overflow-hidden rounded-none border py-2 after:pointer-events-none after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 first:rounded-s last:rounded-e\">Tab 2\n        </tabstrigger><tabstrigger value=\"tab-3\" class=\"data-[state=active]:bg-muted data-[state=active]:after:bg-primary relative overflow-hidden rounded-none border py-2 after:pointer-events-none after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 first:rounded-s last:rounded-e\">Tab 3\n        </tabstrigger></tabslist><tabscontent value=\"tab-1\"><text class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</text></tabscontent><tabscontent value=\"tab-2\"><text class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</text></tabscontent><tabscontent value=\"tab-3\"><text class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</text></tabscontent></tabs>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tabs",
          "radix"
        ],
        "colSpan": 2,
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tabs-06",
          "group": "tabs",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tabs-06",
              "path": "registry/default/components/tabs/tabs-06.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tabs-06",
              "path": "registry/default/components/tabs/tabs-06.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tabs-06",
              "path": "registry/default/components/tabs/tabs-06.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tabs-06",
              "path": "registry/default/components/tabs/tabs-06.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tabs",
        "title": "Tabs · Basic tabs"
      },
      "categories": [
        "tabs"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "tabs-07",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/tabs.json"
      ],
      "files": [
        {
          "path": "registry/default/components/tabs/tabs-07.tsx",
          "type": "registry:component",
          "target": "components/ui/tabs-07.tsx",
          "content": "import { Tabs, TabsContent, TabsList, TabsTrigger } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Tabs defaultValue=\"tab-1\">\n      <TabsList className=\"before:bg-border relative h-auto w-full gap-0.5 bg-transparent p-0 before:absolute before:inset-x-0 before:bottom-0 before:h-px\">\n        <TabsTrigger\n          value=\"tab-1\"\n          className=\"bg-muted overflow-hidden rounded-b-none border-x border-t py-2 data-[state=active]:z-10 data-[state=active]:shadow-none\"\n        >\n          Tab 1\n        </TabsTrigger>\n        <TabsTrigger\n          value=\"tab-2\"\n          className=\"bg-muted overflow-hidden rounded-b-none border-x border-t py-2 data-[state=active]:z-10 data-[state=active]:shadow-none\"\n        >\n          Tab 2\n        </TabsTrigger>\n        <TabsTrigger\n          value=\"tab-3\"\n          className=\"bg-muted overflow-hidden rounded-b-none border-x border-t py-2 data-[state=active]:z-10 data-[state=active]:shadow-none\"\n        >\n          Tab 3\n        </TabsTrigger>\n      </TabsList>\n      <TabsContent value=\"tab-1\">\n        <p className=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</p>\n      </TabsContent>\n      <TabsContent value=\"tab-2\">\n        <p className=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</p>\n      </TabsContent>\n      <TabsContent value=\"tab-3\">\n        <p className=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</p>\n      </TabsContent>\n    </Tabs>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-07.vue",
          "target": "components/ui/tabs-07.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Tabs } from '@timui/vue';\nimport { TabsContent } from '@timui/vue';\nimport { TabsList } from '@timui/vue';\nimport { TabsTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Tabs default-value=\"tab-1\"><TabsList class=\"before:bg-border relative h-auto w-full gap-0.5 bg-transparent p-0 before:absolute before:inset-x-0 before:bottom-0 before:h-px\"><TabsTrigger value=\"tab-1\" class=\"bg-muted overflow-hidden rounded-b-none border-x border-t py-2 data-[state=active]:z-10 data-[state=active]:shadow-none\">Tab 1\n        </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"bg-muted overflow-hidden rounded-b-none border-x border-t py-2 data-[state=active]:z-10 data-[state=active]:shadow-none\">Tab 2\n        </TabsTrigger><TabsTrigger value=\"tab-3\" class=\"bg-muted overflow-hidden rounded-b-none border-x border-t py-2 data-[state=active]:z-10 data-[state=active]:shadow-none\">Tab 3\n        </TabsTrigger></TabsList><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</p></TabsContent></Tabs>\n</template>\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-07.html",
          "target": "components/ui/tabs-07.html",
          "type": "registry:component",
          "content": "<template>\n  <Tabs default-value=\"tab-1\"><TabsList class=\"before:bg-border relative h-auto w-full gap-0.5 bg-transparent p-0 before:absolute before:inset-x-0 before:bottom-0 before:h-px\"><TabsTrigger value=\"tab-1\" class=\"bg-muted overflow-hidden rounded-b-none border-x border-t py-2 data-[state=active]:z-10 data-[state=active]:shadow-none\">Tab 1\n        </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"bg-muted overflow-hidden rounded-b-none border-x border-t py-2 data-[state=active]:z-10 data-[state=active]:shadow-none\">Tab 2\n        </TabsTrigger><TabsTrigger value=\"tab-3\" class=\"bg-muted overflow-hidden rounded-b-none border-x border-t py-2 data-[state=active]:z-10 data-[state=active]:shadow-none\">Tab 3\n        </TabsTrigger></TabsList><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</p></TabsContent></Tabs>\n</template>"
        },
        {
          "path": "registry/default/components/tabs/tabs-07.wxml",
          "target": "components/ui/tabs-07/tabs-07.wxml",
          "type": "registry:component",
          "content": "<view>\n  <tabs default-value=\"tab-1\"><tabslist class=\"before:bg-border relative h-auto w-full gap-0.5 bg-transparent p-0 before:absolute before:inset-x-0 before:bottom-0 before:h-px\"><tabstrigger value=\"tab-1\" class=\"bg-muted overflow-hidden rounded-b-none border-x border-t py-2 data-[state=active]:z-10 data-[state=active]:shadow-none\">Tab 1\n        </tabstrigger><tabstrigger value=\"tab-2\" class=\"bg-muted overflow-hidden rounded-b-none border-x border-t py-2 data-[state=active]:z-10 data-[state=active]:shadow-none\">Tab 2\n        </tabstrigger><tabstrigger value=\"tab-3\" class=\"bg-muted overflow-hidden rounded-b-none border-x border-t py-2 data-[state=active]:z-10 data-[state=active]:shadow-none\">Tab 3\n        </tabstrigger></tabslist><tabscontent value=\"tab-1\"><text class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</text></tabscontent><tabscontent value=\"tab-2\"><text class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</text></tabscontent><tabscontent value=\"tab-3\"><text class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</text></tabscontent></tabs>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tabs",
          "radix"
        ],
        "colSpan": 2,
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tabs-07",
          "group": "tabs",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tabs-07",
              "path": "registry/default/components/tabs/tabs-07.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tabs-07",
              "path": "registry/default/components/tabs/tabs-07.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tabs-07",
              "path": "registry/default/components/tabs/tabs-07.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tabs-07",
              "path": "registry/default/components/tabs/tabs-07.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tabs",
        "title": "Tabs · Basic tabs"
      },
      "categories": [
        "tabs"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "tabs-08",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/scroll-area.json",
        "https://ui.timkit.cn/r/tabs.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/tabs/tabs-08.tsx",
          "type": "registry:component",
          "target": "components/ui/tabs-08.tsx",
          "content": "import {\n  Badge,\n  ScrollArea,\n  ScrollBar,\n  Tabs,\n  TabsContent,\n  TabsList,\n  TabsTrigger,\n} from '@timui/react'\nimport { BoxIcon, HouseIcon, PanelsTopLeftIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <Tabs defaultValue=\"tab-1\">\n      <ScrollArea>\n        <TabsList className=\"mb-3\">\n          <TabsTrigger value=\"tab-1\">\n            <HouseIcon className=\"-ms-0.5 me-1.5 opacity-60\" size={16} aria-hidden=\"true\" />\n            Overview\n          </TabsTrigger>\n          <TabsTrigger value=\"tab-2\" className=\"group\">\n            <PanelsTopLeftIcon className=\"-ms-0.5 me-1.5 opacity-60\" size={16} aria-hidden=\"true\" />\n            Projects\n            <Badge\n              className=\"bg-primary/15 ms-1.5 min-w-5 px-1 transition-opacity group-data-[state=inactive]:opacity-50\"\n              variant=\"secondary\"\n            >\n              3\n            </Badge>\n          </TabsTrigger>\n          <TabsTrigger value=\"tab-3\" className=\"group\">\n            <BoxIcon className=\"-ms-0.5 me-1.5 opacity-60\" size={16} aria-hidden=\"true\" />\n            Packages\n            <Badge className=\"ms-1.5 transition-opacity group-data-[state=inactive]:opacity-50\">\n              New\n            </Badge>\n          </TabsTrigger>\n        </TabsList>\n        <ScrollBar orientation=\"horizontal\" />\n      </ScrollArea>\n      <TabsContent value=\"tab-1\">\n        <p className=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 1</p>\n      </TabsContent>\n      <TabsContent value=\"tab-2\">\n        <p className=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 2</p>\n      </TabsContent>\n      <TabsContent value=\"tab-3\">\n        <p className=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 3</p>\n      </TabsContent>\n    </Tabs>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-08.vue",
          "target": "components/ui/tabs-08.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { BoxIcon, HouseIcon, PanelsTopLeftIcon } from 'lucide-vue-next';\nimport { Badge } from '@timui/vue';\nimport { ScrollArea } from '@timui/vue';\nimport { ScrollBar } from '@timui/vue';\nimport { Tabs } from '@timui/vue';\nimport { TabsContent } from '@timui/vue';\nimport { TabsList } from '@timui/vue';\nimport { TabsTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Tabs default-value=\"tab-1\"><ScrollArea><TabsList class=\"mb-3\"><TabsTrigger value=\"tab-1\"><HouseIcon class=\"-ms-0.5 me-1.5 opacity-60\" :size=\"16\" aria-hidden=\"true\" />Overview\n          </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"group\"><PanelsTopLeftIcon class=\"-ms-0.5 me-1.5 opacity-60\" :size=\"16\" aria-hidden=\"true\" />Projects\n            <Badge class=\"bg-primary/15 ms-1.5 min-w-5 px-1 transition-opacity group-data-[state=inactive]:opacity-50\" variant=\"secondary\">3\n            </Badge></TabsTrigger><TabsTrigger value=\"tab-3\" class=\"group\"><BoxIcon class=\"-ms-0.5 me-1.5 opacity-60\" :size=\"16\" aria-hidden=\"true\" />Packages\n            <Badge class=\"ms-1.5 transition-opacity group-data-[state=inactive]:opacity-50\">New\n            </Badge></TabsTrigger></TabsList><ScrollBar orientation=\"horizontal\" /></ScrollArea><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 3</p></TabsContent></Tabs>\n</template>\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-08.html",
          "target": "components/ui/tabs-08.html",
          "type": "registry:component",
          "content": "<template>\n  <Tabs default-value=\"tab-1\"><ScrollArea><TabsList class=\"mb-3\"><TabsTrigger value=\"tab-1\"><HouseIcon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Overview\n          </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"group\"><PanelsTopLeftIcon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Projects\n            <Badge class=\"bg-primary/15 ms-1.5 min-w-5 px-1 transition-opacity group-data-[state=inactive]:opacity-50\" variant=\"secondary\">3\n            </Badge></TabsTrigger><TabsTrigger value=\"tab-3\" class=\"group\"><BoxIcon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Packages\n            <Badge class=\"ms-1.5 transition-opacity group-data-[state=inactive]:opacity-50\">New\n            </Badge></TabsTrigger></TabsList><ScrollBar orientation=\"horizontal\" /></ScrollArea><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 3</p></TabsContent></Tabs>\n</template>"
        },
        {
          "path": "registry/default/components/tabs/tabs-08.wxml",
          "target": "components/ui/tabs-08/tabs-08.wxml",
          "type": "registry:component",
          "content": "<view>\n  <tabs default-value=\"tab-1\"><scrollarea><tabslist class=\"mb-3\"><tabstrigger value=\"tab-1\"><houseicon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Overview\n          </tabstrigger><tabstrigger value=\"tab-2\" class=\"group\"><panelstoplefticon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Projects\n            <badge class=\"bg-primary/15 ms-1.5 min-w-5 px-1 transition-opacity group-data-[state=inactive]:opacity-50\" variant=\"secondary\">3\n            </badge></tabstrigger><tabstrigger value=\"tab-3\" class=\"group\"><boxicon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Packages\n            <badge class=\"ms-1.5 transition-opacity group-data-[state=inactive]:opacity-50\">New\n            </badge></tabstrigger></tabslist><scrollbar orientation=\"horizontal\" /></scrollarea><tabscontent value=\"tab-1\"><text class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 1</text></tabscontent><tabscontent value=\"tab-2\"><text class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 2</text></tabscontent><tabscontent value=\"tab-3\"><text class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 3</text></tabscontent></tabs>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tabs",
          "radix"
        ],
        "colSpan": 2,
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tabs-08",
          "group": "tabs",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tabs-08",
              "path": "registry/default/components/tabs/tabs-08.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tabs-08",
              "path": "registry/default/components/tabs/tabs-08.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tabs-08",
              "path": "registry/default/components/tabs/tabs-08.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tabs-08",
              "path": "registry/default/components/tabs/tabs-08.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tabs",
        "title": "Tabs · Basic tabs"
      },
      "categories": [
        "tabs"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "tabs-09",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/scroll-area.json",
        "https://ui.timkit.cn/r/tabs.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/tabs/tabs-09.tsx",
          "type": "registry:component",
          "target": "components/ui/tabs-09.tsx",
          "content": "import { ScrollArea, ScrollBar, Tabs, TabsContent, TabsList, TabsTrigger } from '@timui/react'\nimport { BoxIcon, HouseIcon, PanelsTopLeftIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <Tabs defaultValue=\"tab-1\">\n      <ScrollArea>\n        <TabsList className=\"mb-3 gap-1 bg-transparent\">\n          <TabsTrigger\n            value=\"tab-1\"\n            className=\"data-[state=active]:bg-primary data-[state=active]:text-primary-foreground rounded-full data-[state=active]:shadow-none\"\n          >\n            <HouseIcon className=\"-ms-0.5 me-1.5 opacity-60\" size={16} aria-hidden=\"true\" />\n            Overview\n          </TabsTrigger>\n          <TabsTrigger\n            value=\"tab-2\"\n            className=\"data-[state=active]:bg-primary data-[state=active]:text-primary-foreground rounded-full data-[state=active]:shadow-none\"\n          >\n            <PanelsTopLeftIcon className=\"-ms-0.5 me-1.5 opacity-60\" size={16} aria-hidden=\"true\" />\n            Projects\n          </TabsTrigger>\n          <TabsTrigger\n            value=\"tab-3\"\n            className=\"data-[state=active]:bg-primary data-[state=active]:text-primary-foreground rounded-full data-[state=active]:shadow-none\"\n          >\n            <BoxIcon className=\"-ms-0.5 me-1.5 opacity-60\" size={16} aria-hidden=\"true\" />\n            Packages\n          </TabsTrigger>\n        </TabsList>\n        <ScrollBar orientation=\"horizontal\" />\n      </ScrollArea>\n      <TabsContent value=\"tab-1\">\n        <p className=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 1</p>\n      </TabsContent>\n      <TabsContent value=\"tab-2\">\n        <p className=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 2</p>\n      </TabsContent>\n      <TabsContent value=\"tab-3\">\n        <p className=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 3</p>\n      </TabsContent>\n    </Tabs>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-09.vue",
          "target": "components/ui/tabs-09.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { BoxIcon, HouseIcon, PanelsTopLeftIcon } from 'lucide-vue-next';\nimport { ScrollArea } from '@timui/vue';\nimport { ScrollBar } from '@timui/vue';\nimport { Tabs } from '@timui/vue';\nimport { TabsContent } from '@timui/vue';\nimport { TabsList } from '@timui/vue';\nimport { TabsTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Tabs default-value=\"tab-1\"><ScrollArea><TabsList class=\"mb-3 gap-1 bg-transparent\"><TabsTrigger value=\"tab-1\" class=\"data-[state=active]:bg-primary data-[state=active]:text-primary-foreground rounded-full data-[state=active]:shadow-none\"><HouseIcon class=\"-ms-0.5 me-1.5 opacity-60\" :size=\"16\" aria-hidden=\"true\" />Overview\n          </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"data-[state=active]:bg-primary data-[state=active]:text-primary-foreground rounded-full data-[state=active]:shadow-none\"><PanelsTopLeftIcon class=\"-ms-0.5 me-1.5 opacity-60\" :size=\"16\" aria-hidden=\"true\" />Projects\n          </TabsTrigger><TabsTrigger value=\"tab-3\" class=\"data-[state=active]:bg-primary data-[state=active]:text-primary-foreground rounded-full data-[state=active]:shadow-none\"><BoxIcon class=\"-ms-0.5 me-1.5 opacity-60\" :size=\"16\" aria-hidden=\"true\" />Packages\n          </TabsTrigger></TabsList><ScrollBar orientation=\"horizontal\" /></ScrollArea><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 3</p></TabsContent></Tabs>\n</template>\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-09.html",
          "target": "components/ui/tabs-09.html",
          "type": "registry:component",
          "content": "<template>\n  <Tabs default-value=\"tab-1\"><ScrollArea><TabsList class=\"mb-3 gap-1 bg-transparent\"><TabsTrigger value=\"tab-1\" class=\"data-[state=active]:bg-primary data-[state=active]:text-primary-foreground rounded-full data-[state=active]:shadow-none\"><HouseIcon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Overview\n          </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"data-[state=active]:bg-primary data-[state=active]:text-primary-foreground rounded-full data-[state=active]:shadow-none\"><PanelsTopLeftIcon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Projects\n          </TabsTrigger><TabsTrigger value=\"tab-3\" class=\"data-[state=active]:bg-primary data-[state=active]:text-primary-foreground rounded-full data-[state=active]:shadow-none\"><BoxIcon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Packages\n          </TabsTrigger></TabsList><ScrollBar orientation=\"horizontal\" /></ScrollArea><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 3</p></TabsContent></Tabs>\n</template>"
        },
        {
          "path": "registry/default/components/tabs/tabs-09.wxml",
          "target": "components/ui/tabs-09/tabs-09.wxml",
          "type": "registry:component",
          "content": "<view>\n  <tabs default-value=\"tab-1\"><scrollarea><tabslist class=\"mb-3 gap-1 bg-transparent\"><tabstrigger value=\"tab-1\" class=\"data-[state=active]:bg-primary data-[state=active]:text-primary-foreground rounded-full data-[state=active]:shadow-none\"><houseicon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Overview\n          </tabstrigger><tabstrigger value=\"tab-2\" class=\"data-[state=active]:bg-primary data-[state=active]:text-primary-foreground rounded-full data-[state=active]:shadow-none\"><panelstoplefticon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Projects\n          </tabstrigger><tabstrigger value=\"tab-3\" class=\"data-[state=active]:bg-primary data-[state=active]:text-primary-foreground rounded-full data-[state=active]:shadow-none\"><boxicon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Packages\n          </tabstrigger></tabslist><scrollbar orientation=\"horizontal\" /></scrollarea><tabscontent value=\"tab-1\"><text class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 1</text></tabscontent><tabscontent value=\"tab-2\"><text class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 2</text></tabscontent><tabscontent value=\"tab-3\"><text class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 3</text></tabscontent></tabs>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tabs",
          "radix"
        ],
        "colSpan": 2,
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tabs-09",
          "group": "tabs",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tabs-09",
              "path": "registry/default/components/tabs/tabs-09.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tabs-09",
              "path": "registry/default/components/tabs/tabs-09.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tabs-09",
              "path": "registry/default/components/tabs/tabs-09.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tabs-09",
              "path": "registry/default/components/tabs/tabs-09.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tabs",
        "title": "Tabs · Basic tabs"
      },
      "categories": [
        "tabs"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "tabs-10",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/scroll-area.json",
        "https://ui.timkit.cn/r/tabs.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/tabs/tabs-10.tsx",
          "type": "registry:component",
          "target": "components/ui/tabs-10.tsx",
          "content": "import { ScrollArea, ScrollBar, Tabs, TabsContent, TabsList, TabsTrigger } from '@timui/react'\nimport { BoxIcon, HouseIcon, PanelsTopLeftIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <Tabs defaultValue=\"tab-1\">\n      <ScrollArea>\n        <TabsList className=\"bg-background mb-3 h-auto -space-x-px p-0 shadow-xs rtl:space-x-reverse\">\n          <TabsTrigger\n            value=\"tab-1\"\n            className=\"data-[state=active]:bg-muted data-[state=active]:after:bg-primary relative overflow-hidden rounded-none border py-2 after:pointer-events-none after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 first:rounded-s last:rounded-e\"\n          >\n            <HouseIcon className=\"-ms-0.5 me-1.5 opacity-60\" size={16} aria-hidden=\"true\" />\n            Overview\n          </TabsTrigger>\n          <TabsTrigger\n            value=\"tab-2\"\n            className=\"data-[state=active]:bg-muted data-[state=active]:after:bg-primary relative overflow-hidden rounded-none border py-2 after:pointer-events-none after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 first:rounded-s last:rounded-e\"\n          >\n            <PanelsTopLeftIcon className=\"-ms-0.5 me-1.5 opacity-60\" size={16} aria-hidden=\"true\" />\n            Projects\n          </TabsTrigger>\n          <TabsTrigger\n            value=\"tab-3\"\n            className=\"data-[state=active]:bg-muted data-[state=active]:after:bg-primary relative overflow-hidden rounded-none border py-2 after:pointer-events-none after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 first:rounded-s last:rounded-e\"\n          >\n            <BoxIcon className=\"-ms-0.5 me-1.5 opacity-60\" size={16} aria-hidden=\"true\" />\n            Packages\n          </TabsTrigger>\n        </TabsList>\n        <ScrollBar orientation=\"horizontal\" />\n      </ScrollArea>\n      <TabsContent value=\"tab-1\">\n        <p className=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 1</p>\n      </TabsContent>\n      <TabsContent value=\"tab-2\">\n        <p className=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 2</p>\n      </TabsContent>\n      <TabsContent value=\"tab-3\">\n        <p className=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 3</p>\n      </TabsContent>\n    </Tabs>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-10.vue",
          "target": "components/ui/tabs-10.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { BoxIcon, HouseIcon, PanelsTopLeftIcon } from 'lucide-vue-next';\nimport { ScrollArea } from '@timui/vue';\nimport { ScrollBar } from '@timui/vue';\nimport { Tabs } from '@timui/vue';\nimport { TabsContent } from '@timui/vue';\nimport { TabsList } from '@timui/vue';\nimport { TabsTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Tabs default-value=\"tab-1\"><ScrollArea><TabsList class=\"bg-background mb-3 h-auto -space-x-px p-0 shadow-xs rtl:space-x-reverse\"><TabsTrigger value=\"tab-1\" class=\"data-[state=active]:bg-muted data-[state=active]:after:bg-primary relative overflow-hidden rounded-none border py-2 after:pointer-events-none after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 first:rounded-s last:rounded-e\"><HouseIcon class=\"-ms-0.5 me-1.5 opacity-60\" :size=\"16\" aria-hidden=\"true\" />Overview\n          </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"data-[state=active]:bg-muted data-[state=active]:after:bg-primary relative overflow-hidden rounded-none border py-2 after:pointer-events-none after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 first:rounded-s last:rounded-e\"><PanelsTopLeftIcon class=\"-ms-0.5 me-1.5 opacity-60\" :size=\"16\" aria-hidden=\"true\" />Projects\n          </TabsTrigger><TabsTrigger value=\"tab-3\" class=\"data-[state=active]:bg-muted data-[state=active]:after:bg-primary relative overflow-hidden rounded-none border py-2 after:pointer-events-none after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 first:rounded-s last:rounded-e\"><BoxIcon class=\"-ms-0.5 me-1.5 opacity-60\" :size=\"16\" aria-hidden=\"true\" />Packages\n          </TabsTrigger></TabsList><ScrollBar orientation=\"horizontal\" /></ScrollArea><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 3</p></TabsContent></Tabs>\n</template>\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-10.html",
          "target": "components/ui/tabs-10.html",
          "type": "registry:component",
          "content": "<template>\n  <Tabs default-value=\"tab-1\"><ScrollArea><TabsList class=\"bg-background mb-3 h-auto -space-x-px p-0 shadow-xs rtl:space-x-reverse\"><TabsTrigger value=\"tab-1\" class=\"data-[state=active]:bg-muted data-[state=active]:after:bg-primary relative overflow-hidden rounded-none border py-2 after:pointer-events-none after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 first:rounded-s last:rounded-e\"><HouseIcon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Overview\n          </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"data-[state=active]:bg-muted data-[state=active]:after:bg-primary relative overflow-hidden rounded-none border py-2 after:pointer-events-none after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 first:rounded-s last:rounded-e\"><PanelsTopLeftIcon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Projects\n          </TabsTrigger><TabsTrigger value=\"tab-3\" class=\"data-[state=active]:bg-muted data-[state=active]:after:bg-primary relative overflow-hidden rounded-none border py-2 after:pointer-events-none after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 first:rounded-s last:rounded-e\"><BoxIcon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Packages\n          </TabsTrigger></TabsList><ScrollBar orientation=\"horizontal\" /></ScrollArea><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 3</p></TabsContent></Tabs>\n</template>"
        },
        {
          "path": "registry/default/components/tabs/tabs-10.wxml",
          "target": "components/ui/tabs-10/tabs-10.wxml",
          "type": "registry:component",
          "content": "<view>\n  <tabs default-value=\"tab-1\"><scrollarea><tabslist class=\"bg-background mb-3 h-auto -space-x-px p-0 shadow-xs rtl:space-x-reverse\"><tabstrigger value=\"tab-1\" class=\"data-[state=active]:bg-muted data-[state=active]:after:bg-primary relative overflow-hidden rounded-none border py-2 after:pointer-events-none after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 first:rounded-s last:rounded-e\"><houseicon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Overview\n          </tabstrigger><tabstrigger value=\"tab-2\" class=\"data-[state=active]:bg-muted data-[state=active]:after:bg-primary relative overflow-hidden rounded-none border py-2 after:pointer-events-none after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 first:rounded-s last:rounded-e\"><panelstoplefticon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Projects\n          </tabstrigger><tabstrigger value=\"tab-3\" class=\"data-[state=active]:bg-muted data-[state=active]:after:bg-primary relative overflow-hidden rounded-none border py-2 after:pointer-events-none after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 first:rounded-s last:rounded-e\"><boxicon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Packages\n          </tabstrigger></tabslist><scrollbar orientation=\"horizontal\" /></scrollarea><tabscontent value=\"tab-1\"><text class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 1</text></tabscontent><tabscontent value=\"tab-2\"><text class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 2</text></tabscontent><tabscontent value=\"tab-3\"><text class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 3</text></tabscontent></tabs>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tabs",
          "radix"
        ],
        "colSpan": 2,
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tabs-10",
          "group": "tabs",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tabs-10",
              "path": "registry/default/components/tabs/tabs-10.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tabs-10",
              "path": "registry/default/components/tabs/tabs-10.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tabs-10",
              "path": "registry/default/components/tabs/tabs-10.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tabs-10",
              "path": "registry/default/components/tabs/tabs-10.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tabs",
        "title": "Tabs · Basic tabs"
      },
      "categories": [
        "tabs"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "tabs-11",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/scroll-area.json",
        "https://ui.timkit.cn/r/tabs.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/tabs/tabs-11.tsx",
          "type": "registry:component",
          "target": "components/ui/tabs-11.tsx",
          "content": "import { ScrollArea, ScrollBar, Tabs, TabsContent, TabsList, TabsTrigger } from '@timui/react'\nimport { BoxIcon, HouseIcon, PanelsTopLeftIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <Tabs defaultValue=\"tab-1\">\n      <ScrollArea>\n        <TabsList className=\"before:bg-border relative mb-3 h-auto w-full gap-0.5 bg-transparent p-0 before:absolute before:inset-x-0 before:bottom-0 before:h-px\">\n          <TabsTrigger\n            value=\"tab-1\"\n            className=\"bg-muted overflow-hidden rounded-b-none border-x border-t py-2 data-[state=active]:z-10 data-[state=active]:shadow-none\"\n          >\n            <HouseIcon className=\"-ms-0.5 me-1.5 opacity-60\" size={16} aria-hidden=\"true\" />\n            Overview\n          </TabsTrigger>\n          <TabsTrigger\n            value=\"tab-2\"\n            className=\"bg-muted overflow-hidden rounded-b-none border-x border-t py-2 data-[state=active]:z-10 data-[state=active]:shadow-none\"\n          >\n            <PanelsTopLeftIcon className=\"-ms-0.5 me-1.5 opacity-60\" size={16} aria-hidden=\"true\" />\n            Projects\n          </TabsTrigger>\n          <TabsTrigger\n            value=\"tab-3\"\n            className=\"bg-muted overflow-hidden rounded-b-none border-x border-t py-2 data-[state=active]:z-10 data-[state=active]:shadow-none\"\n          >\n            <BoxIcon className=\"-ms-0.5 me-1.5 opacity-60\" size={16} aria-hidden=\"true\" />\n            Packages\n          </TabsTrigger>\n        </TabsList>\n        <ScrollBar orientation=\"horizontal\" />\n      </ScrollArea>\n      <TabsContent value=\"tab-1\">\n        <p className=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 1</p>\n      </TabsContent>\n      <TabsContent value=\"tab-2\">\n        <p className=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 2</p>\n      </TabsContent>\n      <TabsContent value=\"tab-3\">\n        <p className=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 3</p>\n      </TabsContent>\n    </Tabs>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-11.vue",
          "target": "components/ui/tabs-11.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { BoxIcon, HouseIcon, PanelsTopLeftIcon } from 'lucide-vue-next';\nimport { ScrollArea } from '@timui/vue';\nimport { ScrollBar } from '@timui/vue';\nimport { Tabs } from '@timui/vue';\nimport { TabsContent } from '@timui/vue';\nimport { TabsList } from '@timui/vue';\nimport { TabsTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Tabs default-value=\"tab-1\"><ScrollArea><TabsList class=\"before:bg-border relative mb-3 h-auto w-full gap-0.5 bg-transparent p-0 before:absolute before:inset-x-0 before:bottom-0 before:h-px\"><TabsTrigger value=\"tab-1\" class=\"bg-muted overflow-hidden rounded-b-none border-x border-t py-2 data-[state=active]:z-10 data-[state=active]:shadow-none\"><HouseIcon class=\"-ms-0.5 me-1.5 opacity-60\" :size=\"16\" aria-hidden=\"true\" />Overview\n          </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"bg-muted overflow-hidden rounded-b-none border-x border-t py-2 data-[state=active]:z-10 data-[state=active]:shadow-none\"><PanelsTopLeftIcon class=\"-ms-0.5 me-1.5 opacity-60\" :size=\"16\" aria-hidden=\"true\" />Projects\n          </TabsTrigger><TabsTrigger value=\"tab-3\" class=\"bg-muted overflow-hidden rounded-b-none border-x border-t py-2 data-[state=active]:z-10 data-[state=active]:shadow-none\"><BoxIcon class=\"-ms-0.5 me-1.5 opacity-60\" :size=\"16\" aria-hidden=\"true\" />Packages\n          </TabsTrigger></TabsList><ScrollBar orientation=\"horizontal\" /></ScrollArea><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 3</p></TabsContent></Tabs>\n</template>\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-11.html",
          "target": "components/ui/tabs-11.html",
          "type": "registry:component",
          "content": "<template>\n  <Tabs default-value=\"tab-1\"><ScrollArea><TabsList class=\"before:bg-border relative mb-3 h-auto w-full gap-0.5 bg-transparent p-0 before:absolute before:inset-x-0 before:bottom-0 before:h-px\"><TabsTrigger value=\"tab-1\" class=\"bg-muted overflow-hidden rounded-b-none border-x border-t py-2 data-[state=active]:z-10 data-[state=active]:shadow-none\"><HouseIcon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Overview\n          </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"bg-muted overflow-hidden rounded-b-none border-x border-t py-2 data-[state=active]:z-10 data-[state=active]:shadow-none\"><PanelsTopLeftIcon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Projects\n          </TabsTrigger><TabsTrigger value=\"tab-3\" class=\"bg-muted overflow-hidden rounded-b-none border-x border-t py-2 data-[state=active]:z-10 data-[state=active]:shadow-none\"><BoxIcon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Packages\n          </TabsTrigger></TabsList><ScrollBar orientation=\"horizontal\" /></ScrollArea><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 3</p></TabsContent></Tabs>\n</template>"
        },
        {
          "path": "registry/default/components/tabs/tabs-11.wxml",
          "target": "components/ui/tabs-11/tabs-11.wxml",
          "type": "registry:component",
          "content": "<view>\n  <tabs default-value=\"tab-1\"><scrollarea><tabslist class=\"before:bg-border relative mb-3 h-auto w-full gap-0.5 bg-transparent p-0 before:absolute before:inset-x-0 before:bottom-0 before:h-px\"><tabstrigger value=\"tab-1\" class=\"bg-muted overflow-hidden rounded-b-none border-x border-t py-2 data-[state=active]:z-10 data-[state=active]:shadow-none\"><houseicon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Overview\n          </tabstrigger><tabstrigger value=\"tab-2\" class=\"bg-muted overflow-hidden rounded-b-none border-x border-t py-2 data-[state=active]:z-10 data-[state=active]:shadow-none\"><panelstoplefticon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Projects\n          </tabstrigger><tabstrigger value=\"tab-3\" class=\"bg-muted overflow-hidden rounded-b-none border-x border-t py-2 data-[state=active]:z-10 data-[state=active]:shadow-none\"><boxicon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Packages\n          </tabstrigger></tabslist><scrollbar orientation=\"horizontal\" /></scrollarea><tabscontent value=\"tab-1\"><text class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 1</text></tabscontent><tabscontent value=\"tab-2\"><text class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 2</text></tabscontent><tabscontent value=\"tab-3\"><text class=\"text-muted-foreground p-4 pt-1 text-center text-xs\">Content for Tab 3</text></tabscontent></tabs>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tabs",
          "radix"
        ],
        "colSpan": 2,
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tabs-11",
          "group": "tabs",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tabs-11",
              "path": "registry/default/components/tabs/tabs-11.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tabs-11",
              "path": "registry/default/components/tabs/tabs-11.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tabs-11",
              "path": "registry/default/components/tabs/tabs-11.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tabs-11",
              "path": "registry/default/components/tabs/tabs-11.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tabs",
        "title": "Tabs · Basic tabs"
      },
      "categories": [
        "tabs"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "tabs-12",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/badge.json",
        "https://ui.timkit.cn/r/scroll-area.json",
        "https://ui.timkit.cn/r/tabs.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/tabs/tabs-12.tsx",
          "type": "registry:component",
          "target": "components/ui/tabs-12.tsx",
          "content": "import {\n  Badge,\n  ScrollArea,\n  ScrollBar,\n  Tabs,\n  TabsContent,\n  TabsList,\n  TabsTrigger,\n} from '@timui/react'\nimport {\n  BoxIcon,\n  ChartLine,\n  HouseIcon,\n  PanelsTopLeftIcon,\n  SettingsIcon,\n  UsersRoundIcon,\n} from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <Tabs defaultValue=\"tab-1\">\n      <ScrollArea>\n        <TabsList className=\"text-foreground mb-3 h-auto gap-2 rounded-none border-b bg-transparent px-0 py-1\">\n          <TabsTrigger\n            value=\"tab-1\"\n            className=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"\n          >\n            <HouseIcon className=\"-ms-0.5 me-1.5 opacity-60\" size={16} aria-hidden=\"true\" />\n            Overview\n          </TabsTrigger>\n          <TabsTrigger\n            value=\"tab-2\"\n            className=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"\n          >\n            <PanelsTopLeftIcon className=\"-ms-0.5 me-1.5 opacity-60\" size={16} aria-hidden=\"true\" />\n            Projects\n            <Badge className=\"bg-primary/15 ms-1.5 min-w-5 px-1\" variant=\"secondary\">\n              3\n            </Badge>\n          </TabsTrigger>\n          <TabsTrigger\n            value=\"tab-3\"\n            className=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"\n          >\n            <BoxIcon className=\"-ms-0.5 me-1.5 opacity-60\" size={16} aria-hidden=\"true\" />\n            Packages\n            <Badge className=\"ms-1.5\">New</Badge>\n          </TabsTrigger>\n          <TabsTrigger\n            value=\"tab-4\"\n            className=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"\n          >\n            <UsersRoundIcon className=\"-ms-0.5 me-1.5 opacity-60\" size={16} aria-hidden=\"true\" />\n            Team\n          </TabsTrigger>\n          <TabsTrigger\n            value=\"tab-5\"\n            className=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"\n          >\n            <ChartLine className=\"-ms-0.5 me-1.5 opacity-60\" size={16} aria-hidden=\"true\" />\n            Insights\n          </TabsTrigger>\n          <TabsTrigger\n            value=\"tab-6\"\n            className=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"\n          >\n            <SettingsIcon className=\"-ms-0.5 me-1.5 opacity-60\" size={16} aria-hidden=\"true\" />\n            Settings\n          </TabsTrigger>\n        </TabsList>\n        <ScrollBar orientation=\"horizontal\" />\n      </ScrollArea>\n      <TabsContent value=\"tab-1\">\n        <p className=\"text-muted-foreground pt-1 text-center text-xs\">Content for Tab 1</p>\n      </TabsContent>\n      <TabsContent value=\"tab-2\">\n        <p className=\"text-muted-foreground pt-1 text-center text-xs\">Content for Tab 2</p>\n      </TabsContent>\n      <TabsContent value=\"tab-3\">\n        <p className=\"text-muted-foreground pt-1 text-center text-xs\">Content for Tab 3</p>\n      </TabsContent>\n      <TabsContent value=\"tab-4\">\n        <p className=\"text-muted-foreground pt-1 text-center text-xs\">Content for Tab 4</p>\n      </TabsContent>\n      <TabsContent value=\"tab-5\">\n        <p className=\"text-muted-foreground pt-1 text-center text-xs\">Content for Tab 5</p>\n      </TabsContent>\n      <TabsContent value=\"tab-6\">\n        <p className=\"text-muted-foreground pt-1 text-center text-xs\">Content for Tab 6</p>\n      </TabsContent>\n    </Tabs>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-12.vue",
          "target": "components/ui/tabs-12.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { BoxIcon, ChartLine, HouseIcon, PanelsTopLeftIcon, SettingsIcon, UsersRoundIcon } from 'lucide-vue-next';\nimport { Badge } from '@timui/vue';\nimport { ScrollArea } from '@timui/vue';\nimport { ScrollBar } from '@timui/vue';\nimport { Tabs } from '@timui/vue';\nimport { TabsContent } from '@timui/vue';\nimport { TabsList } from '@timui/vue';\nimport { TabsTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Tabs default-value=\"tab-1\"><ScrollArea><TabsList class=\"text-foreground mb-3 h-auto gap-2 rounded-none border-b bg-transparent px-0 py-1\"><TabsTrigger value=\"tab-1\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><HouseIcon class=\"-ms-0.5 me-1.5 opacity-60\" :size=\"16\" aria-hidden=\"true\" />Overview\n          </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><PanelsTopLeftIcon class=\"-ms-0.5 me-1.5 opacity-60\" :size=\"16\" aria-hidden=\"true\" />Projects\n            <Badge class=\"bg-primary/15 ms-1.5 min-w-5 px-1\" variant=\"secondary\">3\n            </Badge></TabsTrigger><TabsTrigger value=\"tab-3\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><BoxIcon class=\"-ms-0.5 me-1.5 opacity-60\" :size=\"16\" aria-hidden=\"true\" />Packages\n            <Badge class=\"ms-1.5\">New</Badge></TabsTrigger><TabsTrigger value=\"tab-4\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><UsersRoundIcon class=\"-ms-0.5 me-1.5 opacity-60\" :size=\"16\" aria-hidden=\"true\" />Team\n          </TabsTrigger><TabsTrigger value=\"tab-5\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><ChartLine class=\"-ms-0.5 me-1.5 opacity-60\" :size=\"16\" aria-hidden=\"true\" />Insights\n          </TabsTrigger><TabsTrigger value=\"tab-6\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><SettingsIcon class=\"-ms-0.5 me-1.5 opacity-60\" :size=\"16\" aria-hidden=\"true\" />Settings\n          </TabsTrigger></TabsList><ScrollBar orientation=\"horizontal\" /></ScrollArea><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground pt-1 text-center text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground pt-1 text-center text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground pt-1 text-center text-xs\">Content for Tab 3</p></TabsContent><TabsContent value=\"tab-4\"><p class=\"text-muted-foreground pt-1 text-center text-xs\">Content for Tab 4</p></TabsContent><TabsContent value=\"tab-5\"><p class=\"text-muted-foreground pt-1 text-center text-xs\">Content for Tab 5</p></TabsContent><TabsContent value=\"tab-6\"><p class=\"text-muted-foreground pt-1 text-center text-xs\">Content for Tab 6</p></TabsContent></Tabs>\n</template>\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-12.html",
          "target": "components/ui/tabs-12.html",
          "type": "registry:component",
          "content": "<template>\n  <Tabs default-value=\"tab-1\"><ScrollArea><TabsList class=\"text-foreground mb-3 h-auto gap-2 rounded-none border-b bg-transparent px-0 py-1\"><TabsTrigger value=\"tab-1\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><HouseIcon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Overview\n          </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><PanelsTopLeftIcon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Projects\n            <Badge class=\"bg-primary/15 ms-1.5 min-w-5 px-1\" variant=\"secondary\">3\n            </Badge></TabsTrigger><TabsTrigger value=\"tab-3\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><BoxIcon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Packages\n            <Badge class=\"ms-1.5\">New</Badge></TabsTrigger><TabsTrigger value=\"tab-4\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><UsersRoundIcon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Team\n          </TabsTrigger><TabsTrigger value=\"tab-5\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><ChartLine class=\"-ms-0.5 me-1.5 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Insights\n          </TabsTrigger><TabsTrigger value=\"tab-6\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><SettingsIcon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Settings\n          </TabsTrigger></TabsList><ScrollBar orientation=\"horizontal\" /></ScrollArea><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground pt-1 text-center text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground pt-1 text-center text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground pt-1 text-center text-xs\">Content for Tab 3</p></TabsContent><TabsContent value=\"tab-4\"><p class=\"text-muted-foreground pt-1 text-center text-xs\">Content for Tab 4</p></TabsContent><TabsContent value=\"tab-5\"><p class=\"text-muted-foreground pt-1 text-center text-xs\">Content for Tab 5</p></TabsContent><TabsContent value=\"tab-6\"><p class=\"text-muted-foreground pt-1 text-center text-xs\">Content for Tab 6</p></TabsContent></Tabs>\n</template>"
        },
        {
          "path": "registry/default/components/tabs/tabs-12.wxml",
          "target": "components/ui/tabs-12/tabs-12.wxml",
          "type": "registry:component",
          "content": "<view>\n  <tabs default-value=\"tab-1\"><scrollarea><tabslist class=\"text-foreground mb-3 h-auto gap-2 rounded-none border-b bg-transparent px-0 py-1\"><tabstrigger value=\"tab-1\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><houseicon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Overview\n          </tabstrigger><tabstrigger value=\"tab-2\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><panelstoplefticon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Projects\n            <badge class=\"bg-primary/15 ms-1.5 min-w-5 px-1\" variant=\"secondary\">3\n            </badge></tabstrigger><tabstrigger value=\"tab-3\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><boxicon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Packages\n            <badge class=\"ms-1.5\">New</badge></tabstrigger><tabstrigger value=\"tab-4\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><usersroundicon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Team\n          </tabstrigger><tabstrigger value=\"tab-5\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><chartline class=\"-ms-0.5 me-1.5 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Insights\n          </tabstrigger><tabstrigger value=\"tab-6\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><settingsicon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Settings\n          </tabstrigger></tabslist><scrollbar orientation=\"horizontal\" /></scrollarea><tabscontent value=\"tab-1\"><text class=\"text-muted-foreground pt-1 text-center text-xs\">Content for Tab 1</text></tabscontent><tabscontent value=\"tab-2\"><text class=\"text-muted-foreground pt-1 text-center text-xs\">Content for Tab 2</text></tabscontent><tabscontent value=\"tab-3\"><text class=\"text-muted-foreground pt-1 text-center text-xs\">Content for Tab 3</text></tabscontent><tabscontent value=\"tab-4\"><text class=\"text-muted-foreground pt-1 text-center text-xs\">Content for Tab 4</text></tabscontent><tabscontent value=\"tab-5\"><text class=\"text-muted-foreground pt-1 text-center text-xs\">Content for Tab 5</text></tabscontent><tabscontent value=\"tab-6\"><text class=\"text-muted-foreground pt-1 text-center text-xs\">Content for Tab 6</text></tabscontent></tabs>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tabs",
          "radix"
        ],
        "colSpan": 2,
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tabs-12",
          "group": "tabs",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tabs-12",
              "path": "registry/default/components/tabs/tabs-12.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tabs-12",
              "path": "registry/default/components/tabs/tabs-12.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tabs-12",
              "path": "registry/default/components/tabs/tabs-12.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tabs-12",
              "path": "registry/default/components/tabs/tabs-12.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tabs",
        "title": "Tabs · Basic tabs"
      },
      "categories": [
        "tabs"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "tabs-13",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/tabs.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/tabs/tabs-13.tsx",
          "type": "registry:component",
          "target": "components/ui/tabs-13.tsx",
          "content": "import { Tabs, TabsContent, TabsList, TabsTrigger } from '@timui/react'\nimport { BoxIcon, HouseIcon, PanelsTopLeftIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <Tabs defaultValue=\"tab-1\" className=\"items-center\">\n      <TabsList className=\"h-auto rounded-none border-b bg-transparent p-0\">\n        <TabsTrigger\n          value=\"tab-1\"\n          className=\"data-[state=active]:after:bg-primary relative flex-col rounded-none px-4 py-2 text-xs after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"\n        >\n          <HouseIcon className=\"mb-1.5 opacity-60\" size={16} aria-hidden=\"true\" />\n          Overview\n        </TabsTrigger>\n        <TabsTrigger\n          value=\"tab-2\"\n          className=\"data-[state=active]:after:bg-primary relative flex-col rounded-none px-4 py-2 text-xs after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"\n        >\n          <PanelsTopLeftIcon className=\"mb-1.5 opacity-60\" size={16} aria-hidden=\"true\" />\n          Projects\n        </TabsTrigger>\n        <TabsTrigger\n          value=\"tab-3\"\n          className=\"data-[state=active]:after:bg-primary relative flex-col rounded-none px-4 py-2 text-xs after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"\n        >\n          <BoxIcon className=\"mb-1.5 opacity-60\" size={16} aria-hidden=\"true\" />\n          Packages\n        </TabsTrigger>\n      </TabsList>\n      <TabsContent value=\"tab-1\">\n        <p className=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</p>\n      </TabsContent>\n      <TabsContent value=\"tab-2\">\n        <p className=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</p>\n      </TabsContent>\n      <TabsContent value=\"tab-3\">\n        <p className=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</p>\n      </TabsContent>\n    </Tabs>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-13.vue",
          "target": "components/ui/tabs-13.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { BoxIcon, HouseIcon, PanelsTopLeftIcon } from 'lucide-vue-next';\nimport { Tabs } from '@timui/vue';\nimport { TabsContent } from '@timui/vue';\nimport { TabsList } from '@timui/vue';\nimport { TabsTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Tabs default-value=\"tab-1\" class=\"items-center\"><TabsList class=\"h-auto rounded-none border-b bg-transparent p-0\"><TabsTrigger value=\"tab-1\" class=\"data-[state=active]:after:bg-primary relative flex-col rounded-none px-4 py-2 text-xs after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><HouseIcon class=\"mb-1.5 opacity-60\" :size=\"16\" aria-hidden=\"true\" />Overview\n        </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"data-[state=active]:after:bg-primary relative flex-col rounded-none px-4 py-2 text-xs after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><PanelsTopLeftIcon class=\"mb-1.5 opacity-60\" :size=\"16\" aria-hidden=\"true\" />Projects\n        </TabsTrigger><TabsTrigger value=\"tab-3\" class=\"data-[state=active]:after:bg-primary relative flex-col rounded-none px-4 py-2 text-xs after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><BoxIcon class=\"mb-1.5 opacity-60\" :size=\"16\" aria-hidden=\"true\" />Packages\n        </TabsTrigger></TabsList><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</p></TabsContent></Tabs>\n</template>\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-13.html",
          "target": "components/ui/tabs-13.html",
          "type": "registry:component",
          "content": "<template>\n  <Tabs default-value=\"tab-1\" class=\"items-center\"><TabsList class=\"h-auto rounded-none border-b bg-transparent p-0\"><TabsTrigger value=\"tab-1\" class=\"data-[state=active]:after:bg-primary relative flex-col rounded-none px-4 py-2 text-xs after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><HouseIcon class=\"mb-1.5 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Overview\n        </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"data-[state=active]:after:bg-primary relative flex-col rounded-none px-4 py-2 text-xs after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><PanelsTopLeftIcon class=\"mb-1.5 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Projects\n        </TabsTrigger><TabsTrigger value=\"tab-3\" class=\"data-[state=active]:after:bg-primary relative flex-col rounded-none px-4 py-2 text-xs after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><BoxIcon class=\"mb-1.5 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Packages\n        </TabsTrigger></TabsList><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</p></TabsContent></Tabs>\n</template>"
        },
        {
          "path": "registry/default/components/tabs/tabs-13.wxml",
          "target": "components/ui/tabs-13/tabs-13.wxml",
          "type": "registry:component",
          "content": "<view>\n  <tabs default-value=\"tab-1\" class=\"items-center\"><tabslist class=\"h-auto rounded-none border-b bg-transparent p-0\"><tabstrigger value=\"tab-1\" class=\"data-[state=active]:after:bg-primary relative flex-col rounded-none px-4 py-2 text-xs after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><houseicon class=\"mb-1.5 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Overview\n        </tabstrigger><tabstrigger value=\"tab-2\" class=\"data-[state=active]:after:bg-primary relative flex-col rounded-none px-4 py-2 text-xs after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><panelstoplefticon class=\"mb-1.5 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Projects\n        </tabstrigger><tabstrigger value=\"tab-3\" class=\"data-[state=active]:after:bg-primary relative flex-col rounded-none px-4 py-2 text-xs after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><boxicon class=\"mb-1.5 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Packages\n        </tabstrigger></tabslist><tabscontent value=\"tab-1\"><text class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</text></tabscontent><tabscontent value=\"tab-2\"><text class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</text></tabscontent><tabscontent value=\"tab-3\"><text class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</text></tabscontent></tabs>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tabs",
          "radix"
        ],
        "colSpan": 2,
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tabs-13",
          "group": "tabs",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tabs-13",
              "path": "registry/default/components/tabs/tabs-13.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tabs-13",
              "path": "registry/default/components/tabs/tabs-13.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tabs-13",
              "path": "registry/default/components/tabs/tabs-13.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tabs-13",
              "path": "registry/default/components/tabs/tabs-13.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tabs",
        "title": "Tabs · Basic tabs"
      },
      "categories": [
        "tabs"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "tabs-14",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/tabs.json"
      ],
      "files": [
        {
          "path": "registry/default/components/tabs/tabs-14.tsx",
          "type": "registry:component",
          "target": "components/ui/tabs-14.tsx",
          "content": "import { Badge, Tabs, TabsContent, TabsList, TabsTrigger } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Tabs defaultValue=\"tab-1\">\n      <TabsList className=\"mx-auto flex w-full max-w-xs bg-transparent\">\n        <TabsTrigger\n          value=\"tab-1\"\n          className=\"group data-[state=active]:bg-muted flex-1 flex-col p-3 text-xs data-[state=active]:shadow-none\"\n        >\n          <Badge className=\"mb-1.5 min-w-5 px-1 transition-opacity group-data-[state=inactive]:opacity-50\">\n            3\n          </Badge>\n          Overview\n        </TabsTrigger>\n        <TabsTrigger\n          value=\"tab-2\"\n          className=\"group data-[state=active]:bg-muted flex-1 flex-col p-3 text-xs data-[state=active]:shadow-none\"\n        >\n          <Badge className=\"mb-1.5 min-w-5 px-1 transition-opacity group-data-[state=inactive]:opacity-50\">\n            0\n          </Badge>\n          Projects\n        </TabsTrigger>\n        <TabsTrigger\n          value=\"tab-3\"\n          className=\"group data-[state=active]:bg-muted flex-1 flex-col p-3 text-xs data-[state=active]:shadow-none\"\n        >\n          <Badge className=\"mb-1.5 min-w-5 px-1 transition-opacity group-data-[state=inactive]:opacity-50\">\n            7\n          </Badge>\n          Packages\n        </TabsTrigger>\n      </TabsList>\n      <TabsContent value=\"tab-1\">\n        <p className=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</p>\n      </TabsContent>\n      <TabsContent value=\"tab-2\">\n        <p className=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</p>\n      </TabsContent>\n      <TabsContent value=\"tab-3\">\n        <p className=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</p>\n      </TabsContent>\n    </Tabs>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-14.vue",
          "target": "components/ui/tabs-14.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Badge } from '@timui/vue';\nimport { Tabs } from '@timui/vue';\nimport { TabsContent } from '@timui/vue';\nimport { TabsList } from '@timui/vue';\nimport { TabsTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Tabs default-value=\"tab-1\"><TabsList class=\"mx-auto flex w-full max-w-xs bg-transparent\"><TabsTrigger value=\"tab-1\" class=\"group data-[state=active]:bg-muted flex-1 flex-col p-3 text-xs data-[state=active]:shadow-none\"><Badge class=\"mb-1.5 min-w-5 px-1 transition-opacity group-data-[state=inactive]:opacity-50\">3\n          </Badge>Overview\n        </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"group data-[state=active]:bg-muted flex-1 flex-col p-3 text-xs data-[state=active]:shadow-none\"><Badge class=\"mb-1.5 min-w-5 px-1 transition-opacity group-data-[state=inactive]:opacity-50\">0\n          </Badge>Projects\n        </TabsTrigger><TabsTrigger value=\"tab-3\" class=\"group data-[state=active]:bg-muted flex-1 flex-col p-3 text-xs data-[state=active]:shadow-none\"><Badge class=\"mb-1.5 min-w-5 px-1 transition-opacity group-data-[state=inactive]:opacity-50\">7\n          </Badge>Packages\n        </TabsTrigger></TabsList><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</p></TabsContent></Tabs>\n</template>\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-14.html",
          "target": "components/ui/tabs-14.html",
          "type": "registry:component",
          "content": "<template>\n  <Tabs default-value=\"tab-1\"><TabsList class=\"mx-auto flex w-full max-w-xs bg-transparent\"><TabsTrigger value=\"tab-1\" class=\"group data-[state=active]:bg-muted flex-1 flex-col p-3 text-xs data-[state=active]:shadow-none\"><Badge class=\"mb-1.5 min-w-5 px-1 transition-opacity group-data-[state=inactive]:opacity-50\">3\n          </Badge>Overview\n        </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"group data-[state=active]:bg-muted flex-1 flex-col p-3 text-xs data-[state=active]:shadow-none\"><Badge class=\"mb-1.5 min-w-5 px-1 transition-opacity group-data-[state=inactive]:opacity-50\">0\n          </Badge>Projects\n        </TabsTrigger><TabsTrigger value=\"tab-3\" class=\"group data-[state=active]:bg-muted flex-1 flex-col p-3 text-xs data-[state=active]:shadow-none\"><Badge class=\"mb-1.5 min-w-5 px-1 transition-opacity group-data-[state=inactive]:opacity-50\">7\n          </Badge>Packages\n        </TabsTrigger></TabsList><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</p></TabsContent></Tabs>\n</template>"
        },
        {
          "path": "registry/default/components/tabs/tabs-14.wxml",
          "target": "components/ui/tabs-14/tabs-14.wxml",
          "type": "registry:component",
          "content": "<view>\n  <tabs default-value=\"tab-1\"><tabslist class=\"mx-auto flex w-full max-w-xs bg-transparent\"><tabstrigger value=\"tab-1\" class=\"group data-[state=active]:bg-muted flex-1 flex-col p-3 text-xs data-[state=active]:shadow-none\"><badge class=\"mb-1.5 min-w-5 px-1 transition-opacity group-data-[state=inactive]:opacity-50\">3\n          </badge>Overview\n        </tabstrigger><tabstrigger value=\"tab-2\" class=\"group data-[state=active]:bg-muted flex-1 flex-col p-3 text-xs data-[state=active]:shadow-none\"><badge class=\"mb-1.5 min-w-5 px-1 transition-opacity group-data-[state=inactive]:opacity-50\">0\n          </badge>Projects\n        </tabstrigger><tabstrigger value=\"tab-3\" class=\"group data-[state=active]:bg-muted flex-1 flex-col p-3 text-xs data-[state=active]:shadow-none\"><badge class=\"mb-1.5 min-w-5 px-1 transition-opacity group-data-[state=inactive]:opacity-50\">7\n          </badge>Packages\n        </tabstrigger></tabslist><tabscontent value=\"tab-1\"><text class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</text></tabscontent><tabscontent value=\"tab-2\"><text class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</text></tabscontent><tabscontent value=\"tab-3\"><text class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</text></tabscontent></tabs>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tabs",
          "radix"
        ],
        "colSpan": 2,
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tabs-14",
          "group": "tabs",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tabs-14",
              "path": "registry/default/components/tabs/tabs-14.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tabs-14",
              "path": "registry/default/components/tabs/tabs-14.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tabs-14",
              "path": "registry/default/components/tabs/tabs-14.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tabs-14",
              "path": "registry/default/components/tabs/tabs-14.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tabs",
        "title": "Tabs · Basic tabs"
      },
      "categories": [
        "tabs"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "tabs-15",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/tabs.json",
        "https://ui.timkit.cn/r/tooltip.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/tabs/tabs-15.tsx",
          "type": "registry:component",
          "target": "components/ui/tabs-15.tsx",
          "content": "import {\n  Badge,\n  Tabs,\n  TabsContent,\n  TabsList,\n  TabsTrigger,\n  Tooltip,\n  TooltipContent,\n  TooltipProvider,\n  TooltipTrigger,\n} from '@timui/react'\nimport { BoxIcon, HouseIcon, PanelsTopLeftIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <Tabs defaultValue=\"tab-1\" className=\"items-center\">\n      <TabsList>\n        <TooltipProvider delayDuration={0}>\n          <Tooltip>\n            <TooltipTrigger asChild>\n              <span>\n                <TabsTrigger value=\"tab-1\" className=\"py-3\">\n                  <HouseIcon size={16} aria-hidden=\"true\" />\n                </TabsTrigger>\n              </span>\n            </TooltipTrigger>\n            <TooltipContent className=\"px-2 py-1 text-xs\">Overview</TooltipContent>\n          </Tooltip>\n        </TooltipProvider>\n        <TooltipProvider delayDuration={0}>\n          <Tooltip>\n            <TooltipTrigger asChild>\n              <span>\n                <TabsTrigger value=\"tab-2\" className=\"group py-3\">\n                  <span className=\"relative\">\n                    <PanelsTopLeftIcon size={16} aria-hidden=\"true\" />\n                    <Badge className=\"border-background absolute -top-2.5 left-full min-w-4 -translate-x-1.5 px-0.5 text-[10px]/[.875rem] transition-opacity group-data-[state=inactive]:opacity-50\">\n                      3\n                    </Badge>\n                  </span>\n                </TabsTrigger>\n              </span>\n            </TooltipTrigger>\n            <TooltipContent className=\"px-2 py-1 text-xs\">Projects</TooltipContent>\n          </Tooltip>\n        </TooltipProvider>\n        <TooltipProvider delayDuration={0}>\n          <Tooltip>\n            <TooltipTrigger asChild>\n              <span>\n                <TabsTrigger value=\"tab-3\" className=\"py-3\">\n                  <BoxIcon size={16} aria-hidden=\"true\" />\n                </TabsTrigger>\n              </span>\n            </TooltipTrigger>\n            <TooltipContent className=\"px-2 py-1 text-xs\">Packages</TooltipContent>\n          </Tooltip>\n        </TooltipProvider>\n      </TabsList>\n      <TabsContent value=\"tab-1\">\n        <p className=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</p>\n      </TabsContent>\n      <TabsContent value=\"tab-2\">\n        <p className=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</p>\n      </TabsContent>\n      <TabsContent value=\"tab-3\">\n        <p className=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</p>\n      </TabsContent>\n    </Tabs>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-15.vue",
          "target": "components/ui/tabs-15.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { BoxIcon, HouseIcon, PanelsTopLeftIcon } from 'lucide-vue-next';\nimport { Badge } from '@timui/vue';\nimport { Tabs } from '@timui/vue';\nimport { TabsContent } from '@timui/vue';\nimport { TabsList } from '@timui/vue';\nimport { TabsTrigger } from '@timui/vue';\nimport { Tooltip } from '@timui/vue';\nimport { TooltipContent } from '@timui/vue';\nimport { TooltipProvider } from '@timui/vue';\nimport { TooltipTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Tabs default-value=\"tab-1\" class=\"items-center\"><TabsList><TooltipProvider :delayDuration=\"0\"><Tooltip><TooltipTrigger as-child><span><TabsTrigger value=\"tab-1\" class=\"py-3\"><HouseIcon :size=\"16\" aria-hidden=\"true\" /></TabsTrigger></span></TooltipTrigger><TooltipContent class=\"px-2 py-1 text-xs\">Overview</TooltipContent></Tooltip></TooltipProvider><TooltipProvider :delayDuration=\"0\"><Tooltip><TooltipTrigger as-child><span><TabsTrigger value=\"tab-2\" class=\"group py-3\"><span class=\"relative\"><PanelsTopLeftIcon :size=\"16\" aria-hidden=\"true\" /><Badge class=\"border-background absolute -top-2.5 left-full min-w-4 -translate-x-1.5 px-0.5 text-[10px]/[.875rem] transition-opacity group-data-[state=inactive]:opacity-50\">3\n                    </Badge></span></TabsTrigger></span></TooltipTrigger><TooltipContent class=\"px-2 py-1 text-xs\">Projects</TooltipContent></Tooltip></TooltipProvider><TooltipProvider :delayDuration=\"0\"><Tooltip><TooltipTrigger as-child><span><TabsTrigger value=\"tab-3\" class=\"py-3\"><BoxIcon :size=\"16\" aria-hidden=\"true\" /></TabsTrigger></span></TooltipTrigger><TooltipContent class=\"px-2 py-1 text-xs\">Packages</TooltipContent></Tooltip></TooltipProvider></TabsList><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</p></TabsContent></Tabs>\n</template>\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-15.html",
          "target": "components/ui/tabs-15.html",
          "type": "registry:component",
          "content": "<template>\n  <Tabs default-value=\"tab-1\" class=\"items-center\"><TabsList><TooltipProvider delayduration=\"${0}\"><Tooltip><TooltipTrigger aschild><span><TabsTrigger value=\"tab-1\" class=\"py-3\"><HouseIcon size=\"${16}\" aria-hidden=\"true\" /></TabsTrigger></span></TooltipTrigger><TooltipContent class=\"px-2 py-1 text-xs\">Overview</TooltipContent></Tooltip></TooltipProvider><TooltipProvider delayduration=\"${0}\"><Tooltip><TooltipTrigger aschild><span><TabsTrigger value=\"tab-2\" class=\"group py-3\"><span class=\"relative\"><PanelsTopLeftIcon size=\"${16}\" aria-hidden=\"true\" /><Badge class=\"border-background absolute -top-2.5 left-full min-w-4 -translate-x-1.5 px-0.5 text-[10px]/[.875rem] transition-opacity group-data-[state=inactive]:opacity-50\">3\n                    </Badge></span></TabsTrigger></span></TooltipTrigger><TooltipContent class=\"px-2 py-1 text-xs\">Projects</TooltipContent></Tooltip></TooltipProvider><TooltipProvider delayduration=\"${0}\"><Tooltip><TooltipTrigger aschild><span><TabsTrigger value=\"tab-3\" class=\"py-3\"><BoxIcon size=\"${16}\" aria-hidden=\"true\" /></TabsTrigger></span></TooltipTrigger><TooltipContent class=\"px-2 py-1 text-xs\">Packages</TooltipContent></Tooltip></TooltipProvider></TabsList><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</p></TabsContent></Tabs>\n</template>"
        },
        {
          "path": "registry/default/components/tabs/tabs-15.wxml",
          "target": "components/ui/tabs-15/tabs-15.wxml",
          "type": "registry:component",
          "content": "<view>\n  <tabs default-value=\"tab-1\" class=\"items-center\"><tabslist><tooltipprovider delayduration=\"{{0}}\"><tooltip><tooltiptrigger aschild><text><tabstrigger value=\"tab-1\" class=\"py-3\"><houseicon size=\"{{16}}\" aria-hidden=\"true\" /></tabstrigger></text></tooltiptrigger><tooltipcontent class=\"px-2 py-1 text-xs\">Overview</tooltipcontent></tooltip></tooltipprovider><tooltipprovider delayduration=\"{{0}}\"><tooltip><tooltiptrigger aschild><text><tabstrigger value=\"tab-2\" class=\"group py-3\"><text class=\"relative\"><panelstoplefticon size=\"{{16}}\" aria-hidden=\"true\" /><badge class=\"border-background absolute -top-2.5 left-full min-w-4 -translate-x-1.5 px-0.5 text-[10px]/[.875rem] transition-opacity group-data-[state=inactive]:opacity-50\">3\n                    </badge></text></tabstrigger></text></tooltiptrigger><tooltipcontent class=\"px-2 py-1 text-xs\">Projects</tooltipcontent></tooltip></tooltipprovider><tooltipprovider delayduration=\"{{0}}\"><tooltip><tooltiptrigger aschild><text><tabstrigger value=\"tab-3\" class=\"py-3\"><boxicon size=\"{{16}}\" aria-hidden=\"true\" /></tabstrigger></text></tooltiptrigger><tooltipcontent class=\"px-2 py-1 text-xs\">Packages</tooltipcontent></tooltip></tooltipprovider></tabslist><tabscontent value=\"tab-1\"><text class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 1</text></tabscontent><tabscontent value=\"tab-2\"><text class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 2</text></tabscontent><tabscontent value=\"tab-3\"><text class=\"text-muted-foreground p-4 text-center text-xs\">Content for Tab 3</text></tabscontent></tabs>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tabs",
          "radix"
        ],
        "colSpan": 2,
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tabs-15",
          "group": "tabs",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tabs-15",
              "path": "registry/default/components/tabs/tabs-15.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tabs-15",
              "path": "registry/default/components/tabs/tabs-15.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tabs-15",
              "path": "registry/default/components/tabs/tabs-15.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tabs-15",
              "path": "registry/default/components/tabs/tabs-15.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tabs",
        "title": "Tabs · Basic tabs"
      },
      "categories": [
        "tabs"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "tabs-16",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/tabs.json",
        "https://ui.timkit.cn/r/tooltip.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/tabs/tabs-16.tsx",
          "type": "registry:component",
          "target": "components/ui/tabs-16.tsx",
          "content": "import {\n  Badge,\n  Tabs,\n  TabsContent,\n  TabsList,\n  TabsTrigger,\n  Tooltip,\n  TooltipContent,\n  TooltipProvider,\n  TooltipTrigger,\n} from '@timui/react'\nimport { BoxIcon, HouseIcon, PanelsTopLeftIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <Tabs defaultValue=\"tab-1\" orientation=\"vertical\" className=\"w-full flex-row\">\n      <TabsList className=\"flex-col\">\n        <TooltipProvider delayDuration={0}>\n          <Tooltip>\n            <TooltipTrigger asChild>\n              <span>\n                <TabsTrigger value=\"tab-1\" className=\"py-3\">\n                  <HouseIcon size={16} aria-hidden=\"true\" />\n                </TabsTrigger>\n              </span>\n            </TooltipTrigger>\n            <TooltipContent side=\"right\" className=\"px-2 py-1 text-xs\">\n              Overview\n            </TooltipContent>\n          </Tooltip>\n        </TooltipProvider>\n        <TooltipProvider delayDuration={0}>\n          <Tooltip>\n            <TooltipTrigger asChild>\n              <span>\n                <TabsTrigger value=\"tab-2\" className=\"group py-3\">\n                  <span className=\"relative\">\n                    <PanelsTopLeftIcon size={16} aria-hidden=\"true\" />\n                    <Badge className=\"border-background absolute -top-2.5 left-full min-w-4 -translate-x-1.5 px-0.5 text-[10px]/[.875rem] transition-opacity group-data-[state=inactive]:opacity-50\">\n                      3\n                    </Badge>\n                  </span>\n                </TabsTrigger>\n              </span>\n            </TooltipTrigger>\n            <TooltipContent side=\"right\" className=\"px-2 py-1 text-xs\">\n              Projects\n            </TooltipContent>\n          </Tooltip>\n        </TooltipProvider>\n        <TooltipProvider delayDuration={0}>\n          <Tooltip>\n            <TooltipTrigger asChild>\n              <span>\n                <TabsTrigger value=\"tab-3\" className=\"py-3\">\n                  <BoxIcon size={16} aria-hidden=\"true\" />\n                </TabsTrigger>\n              </span>\n            </TooltipTrigger>\n            <TooltipContent side=\"right\" className=\"px-2 py-1 text-xs\">\n              Packages\n            </TooltipContent>\n          </Tooltip>\n        </TooltipProvider>\n      </TabsList>\n      <div className=\"grow rounded-md border text-start\">\n        <TabsContent value=\"tab-1\">\n          <p className=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 1</p>\n        </TabsContent>\n        <TabsContent value=\"tab-2\">\n          <p className=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 2</p>\n        </TabsContent>\n        <TabsContent value=\"tab-3\">\n          <p className=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 3</p>\n        </TabsContent>\n      </div>\n    </Tabs>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-16.vue",
          "target": "components/ui/tabs-16.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { BoxIcon, HouseIcon, PanelsTopLeftIcon } from 'lucide-vue-next';\nimport { Badge } from '@timui/vue';\nimport { Tabs } from '@timui/vue';\nimport { TabsContent } from '@timui/vue';\nimport { TabsList } from '@timui/vue';\nimport { TabsTrigger } from '@timui/vue';\nimport { Tooltip } from '@timui/vue';\nimport { TooltipContent } from '@timui/vue';\nimport { TooltipProvider } from '@timui/vue';\nimport { TooltipTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Tabs default-value=\"tab-1\" orientation=\"vertical\" class=\"w-full flex-row\"><TabsList class=\"flex-col\"><TooltipProvider :delayDuration=\"0\"><Tooltip><TooltipTrigger as-child><span><TabsTrigger value=\"tab-1\" class=\"py-3\"><HouseIcon :size=\"16\" aria-hidden=\"true\" /></TabsTrigger></span></TooltipTrigger><TooltipContent side=\"right\" class=\"px-2 py-1 text-xs\">Overview\n            </TooltipContent></Tooltip></TooltipProvider><TooltipProvider :delayDuration=\"0\"><Tooltip><TooltipTrigger as-child><span><TabsTrigger value=\"tab-2\" class=\"group py-3\"><span class=\"relative\"><PanelsTopLeftIcon :size=\"16\" aria-hidden=\"true\" /><Badge class=\"border-background absolute -top-2.5 left-full min-w-4 -translate-x-1.5 px-0.5 text-[10px]/[.875rem] transition-opacity group-data-[state=inactive]:opacity-50\">3\n                    </Badge></span></TabsTrigger></span></TooltipTrigger><TooltipContent side=\"right\" class=\"px-2 py-1 text-xs\">Projects\n            </TooltipContent></Tooltip></TooltipProvider><TooltipProvider :delayDuration=\"0\"><Tooltip><TooltipTrigger as-child><span><TabsTrigger value=\"tab-3\" class=\"py-3\"><BoxIcon :size=\"16\" aria-hidden=\"true\" /></TabsTrigger></span></TooltipTrigger><TooltipContent side=\"right\" class=\"px-2 py-1 text-xs\">Packages\n            </TooltipContent></Tooltip></TooltipProvider></TabsList><div class=\"grow rounded-md border text-start\"><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 3</p></TabsContent></div></Tabs>\n</template>\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-16.html",
          "target": "components/ui/tabs-16.html",
          "type": "registry:component",
          "content": "<template>\n  <Tabs default-value=\"tab-1\" orientation=\"vertical\" class=\"w-full flex-row\"><TabsList class=\"flex-col\"><TooltipProvider delayduration=\"${0}\"><Tooltip><TooltipTrigger aschild><span><TabsTrigger value=\"tab-1\" class=\"py-3\"><HouseIcon size=\"${16}\" aria-hidden=\"true\" /></TabsTrigger></span></TooltipTrigger><TooltipContent side=\"right\" class=\"px-2 py-1 text-xs\">Overview\n            </TooltipContent></Tooltip></TooltipProvider><TooltipProvider delayduration=\"${0}\"><Tooltip><TooltipTrigger aschild><span><TabsTrigger value=\"tab-2\" class=\"group py-3\"><span class=\"relative\"><PanelsTopLeftIcon size=\"${16}\" aria-hidden=\"true\" /><Badge class=\"border-background absolute -top-2.5 left-full min-w-4 -translate-x-1.5 px-0.5 text-[10px]/[.875rem] transition-opacity group-data-[state=inactive]:opacity-50\">3\n                    </Badge></span></TabsTrigger></span></TooltipTrigger><TooltipContent side=\"right\" class=\"px-2 py-1 text-xs\">Projects\n            </TooltipContent></Tooltip></TooltipProvider><TooltipProvider delayduration=\"${0}\"><Tooltip><TooltipTrigger aschild><span><TabsTrigger value=\"tab-3\" class=\"py-3\"><BoxIcon size=\"${16}\" aria-hidden=\"true\" /></TabsTrigger></span></TooltipTrigger><TooltipContent side=\"right\" class=\"px-2 py-1 text-xs\">Packages\n            </TooltipContent></Tooltip></TooltipProvider></TabsList><div class=\"grow rounded-md border text-start\"><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 3</p></TabsContent></div></Tabs>\n</template>"
        },
        {
          "path": "registry/default/components/tabs/tabs-16.wxml",
          "target": "components/ui/tabs-16/tabs-16.wxml",
          "type": "registry:component",
          "content": "<view>\n  <tabs default-value=\"tab-1\" orientation=\"vertical\" class=\"w-full flex-row\"><tabslist class=\"flex-col\"><tooltipprovider delayduration=\"{{0}}\"><tooltip><tooltiptrigger aschild><text><tabstrigger value=\"tab-1\" class=\"py-3\"><houseicon size=\"{{16}}\" aria-hidden=\"true\" /></tabstrigger></text></tooltiptrigger><tooltipcontent side=\"right\" class=\"px-2 py-1 text-xs\">Overview\n            </tooltipcontent></tooltip></tooltipprovider><tooltipprovider delayduration=\"{{0}}\"><tooltip><tooltiptrigger aschild><text><tabstrigger value=\"tab-2\" class=\"group py-3\"><text class=\"relative\"><panelstoplefticon size=\"{{16}}\" aria-hidden=\"true\" /><badge class=\"border-background absolute -top-2.5 left-full min-w-4 -translate-x-1.5 px-0.5 text-[10px]/[.875rem] transition-opacity group-data-[state=inactive]:opacity-50\">3\n                    </badge></text></tabstrigger></text></tooltiptrigger><tooltipcontent side=\"right\" class=\"px-2 py-1 text-xs\">Projects\n            </tooltipcontent></tooltip></tooltipprovider><tooltipprovider delayduration=\"{{0}}\"><tooltip><tooltiptrigger aschild><text><tabstrigger value=\"tab-3\" class=\"py-3\"><boxicon size=\"{{16}}\" aria-hidden=\"true\" /></tabstrigger></text></tooltiptrigger><tooltipcontent side=\"right\" class=\"px-2 py-1 text-xs\">Packages\n            </tooltipcontent></tooltip></tooltipprovider></tabslist><view class=\"grow rounded-md border text-start\"><tabscontent value=\"tab-1\"><text class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 1</text></tabscontent><tabscontent value=\"tab-2\"><text class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 2</text></tabscontent><tabscontent value=\"tab-3\"><text class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 3</text></tabscontent></view></tabs>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tabs",
          "radix"
        ],
        "colSpan": 2,
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tabs-16",
          "group": "tabs",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tabs-16",
              "path": "registry/default/components/tabs/tabs-16.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tabs-16",
              "path": "registry/default/components/tabs/tabs-16.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tabs-16",
              "path": "registry/default/components/tabs/tabs-16.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tabs-16",
              "path": "registry/default/components/tabs/tabs-16.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tabs",
        "title": "Tabs · Basic tabs"
      },
      "categories": [
        "tabs"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "tabs-17",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/tabs.json"
      ],
      "files": [
        {
          "path": "registry/default/components/tabs/tabs-17.tsx",
          "type": "registry:component",
          "target": "components/ui/tabs-17.tsx",
          "content": "import { Tabs, TabsContent, TabsList, TabsTrigger } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Tabs defaultValue=\"tab-1\" orientation=\"vertical\" className=\"w-full flex-row\">\n      <TabsList className=\"flex-col\">\n        <TabsTrigger value=\"tab-1\" className=\"w-full\">\n          Overview\n        </TabsTrigger>\n        <TabsTrigger value=\"tab-2\" className=\"w-full\">\n          Projects\n        </TabsTrigger>\n        <TabsTrigger value=\"tab-3\" className=\"w-full\">\n          Packages\n        </TabsTrigger>\n      </TabsList>\n      <div className=\"grow rounded-md border text-start\">\n        <TabsContent value=\"tab-1\">\n          <p className=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 1</p>\n        </TabsContent>\n        <TabsContent value=\"tab-2\">\n          <p className=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 2</p>\n        </TabsContent>\n        <TabsContent value=\"tab-3\">\n          <p className=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 3</p>\n        </TabsContent>\n      </div>\n    </Tabs>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-17.vue",
          "target": "components/ui/tabs-17.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Tabs } from '@timui/vue';\nimport { TabsContent } from '@timui/vue';\nimport { TabsList } from '@timui/vue';\nimport { TabsTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Tabs default-value=\"tab-1\" orientation=\"vertical\" class=\"w-full flex-row\"><TabsList class=\"flex-col\"><TabsTrigger value=\"tab-1\" class=\"w-full\">Overview\n        </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"w-full\">Projects\n        </TabsTrigger><TabsTrigger value=\"tab-3\" class=\"w-full\">Packages\n        </TabsTrigger></TabsList><div class=\"grow rounded-md border text-start\"><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 3</p></TabsContent></div></Tabs>\n</template>\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-17.html",
          "target": "components/ui/tabs-17.html",
          "type": "registry:component",
          "content": "<template>\n  <Tabs default-value=\"tab-1\" orientation=\"vertical\" class=\"w-full flex-row\"><TabsList class=\"flex-col\"><TabsTrigger value=\"tab-1\" class=\"w-full\">Overview\n        </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"w-full\">Projects\n        </TabsTrigger><TabsTrigger value=\"tab-3\" class=\"w-full\">Packages\n        </TabsTrigger></TabsList><div class=\"grow rounded-md border text-start\"><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 3</p></TabsContent></div></Tabs>\n</template>"
        },
        {
          "path": "registry/default/components/tabs/tabs-17.wxml",
          "target": "components/ui/tabs-17/tabs-17.wxml",
          "type": "registry:component",
          "content": "<view>\n  <tabs default-value=\"tab-1\" orientation=\"vertical\" class=\"w-full flex-row\"><tabslist class=\"flex-col\"><tabstrigger value=\"tab-1\" class=\"w-full\">Overview\n        </tabstrigger><tabstrigger value=\"tab-2\" class=\"w-full\">Projects\n        </tabstrigger><tabstrigger value=\"tab-3\" class=\"w-full\">Packages\n        </tabstrigger></tabslist><view class=\"grow rounded-md border text-start\"><tabscontent value=\"tab-1\"><text class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 1</text></tabscontent><tabscontent value=\"tab-2\"><text class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 2</text></tabscontent><tabscontent value=\"tab-3\"><text class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 3</text></tabscontent></view></tabs>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tabs",
          "vertical tabs",
          "radix"
        ],
        "colSpan": 2,
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tabs-17",
          "group": "tabs",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tabs-17",
              "path": "registry/default/components/tabs/tabs-17.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tabs-17",
              "path": "registry/default/components/tabs/tabs-17.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tabs-17",
              "path": "registry/default/components/tabs/tabs-17.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tabs-17",
              "path": "registry/default/components/tabs/tabs-17.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tabs",
        "title": "Tabs · Basic tabs"
      },
      "categories": [
        "tabs"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "tabs-18",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/tabs.json"
      ],
      "files": [
        {
          "path": "registry/default/components/tabs/tabs-18.tsx",
          "type": "registry:component",
          "target": "components/ui/tabs-18.tsx",
          "content": "import { Tabs, TabsContent, TabsList, TabsTrigger } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Tabs defaultValue=\"tab-1\" orientation=\"vertical\" className=\"w-full flex-row\">\n      <TabsList className=\"flex-col rounded-none border-l bg-transparent p-0\">\n        <TabsTrigger\n          value=\"tab-1\"\n          className=\"data-[state=active]:after:bg-primary relative w-full justify-start rounded-none after:absolute after:inset-y-0 after:start-0 after:w-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"\n        >\n          Overview\n        </TabsTrigger>\n        <TabsTrigger\n          value=\"tab-2\"\n          className=\"data-[state=active]:after:bg-primary relative w-full justify-start rounded-none after:absolute after:inset-y-0 after:start-0 after:w-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"\n        >\n          Projects\n        </TabsTrigger>\n        <TabsTrigger\n          value=\"tab-3\"\n          className=\"data-[state=active]:after:bg-primary relative w-full justify-start rounded-none after:absolute after:inset-y-0 after:start-0 after:w-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"\n        >\n          Packages\n        </TabsTrigger>\n      </TabsList>\n      <div className=\"grow rounded-md border text-start\">\n        <TabsContent value=\"tab-1\">\n          <p className=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 1</p>\n        </TabsContent>\n        <TabsContent value=\"tab-2\">\n          <p className=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 2</p>\n        </TabsContent>\n        <TabsContent value=\"tab-3\">\n          <p className=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 3</p>\n        </TabsContent>\n      </div>\n    </Tabs>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-18.vue",
          "target": "components/ui/tabs-18.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Tabs } from '@timui/vue';\nimport { TabsContent } from '@timui/vue';\nimport { TabsList } from '@timui/vue';\nimport { TabsTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Tabs default-value=\"tab-1\" orientation=\"vertical\" class=\"w-full flex-row\"><TabsList class=\"flex-col rounded-none border-l bg-transparent p-0\"><TabsTrigger value=\"tab-1\" class=\"data-[state=active]:after:bg-primary relative w-full justify-start rounded-none after:absolute after:inset-y-0 after:start-0 after:w-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\">Overview\n        </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"data-[state=active]:after:bg-primary relative w-full justify-start rounded-none after:absolute after:inset-y-0 after:start-0 after:w-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\">Projects\n        </TabsTrigger><TabsTrigger value=\"tab-3\" class=\"data-[state=active]:after:bg-primary relative w-full justify-start rounded-none after:absolute after:inset-y-0 after:start-0 after:w-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\">Packages\n        </TabsTrigger></TabsList><div class=\"grow rounded-md border text-start\"><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 3</p></TabsContent></div></Tabs>\n</template>\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-18.html",
          "target": "components/ui/tabs-18.html",
          "type": "registry:component",
          "content": "<template>\n  <Tabs default-value=\"tab-1\" orientation=\"vertical\" class=\"w-full flex-row\"><TabsList class=\"flex-col rounded-none border-l bg-transparent p-0\"><TabsTrigger value=\"tab-1\" class=\"data-[state=active]:after:bg-primary relative w-full justify-start rounded-none after:absolute after:inset-y-0 after:start-0 after:w-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\">Overview\n        </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"data-[state=active]:after:bg-primary relative w-full justify-start rounded-none after:absolute after:inset-y-0 after:start-0 after:w-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\">Projects\n        </TabsTrigger><TabsTrigger value=\"tab-3\" class=\"data-[state=active]:after:bg-primary relative w-full justify-start rounded-none after:absolute after:inset-y-0 after:start-0 after:w-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\">Packages\n        </TabsTrigger></TabsList><div class=\"grow rounded-md border text-start\"><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 3</p></TabsContent></div></Tabs>\n</template>"
        },
        {
          "path": "registry/default/components/tabs/tabs-18.wxml",
          "target": "components/ui/tabs-18/tabs-18.wxml",
          "type": "registry:component",
          "content": "<view>\n  <tabs default-value=\"tab-1\" orientation=\"vertical\" class=\"w-full flex-row\"><tabslist class=\"flex-col rounded-none border-l bg-transparent p-0\"><tabstrigger value=\"tab-1\" class=\"data-[state=active]:after:bg-primary relative w-full justify-start rounded-none after:absolute after:inset-y-0 after:start-0 after:w-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\">Overview\n        </tabstrigger><tabstrigger value=\"tab-2\" class=\"data-[state=active]:after:bg-primary relative w-full justify-start rounded-none after:absolute after:inset-y-0 after:start-0 after:w-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\">Projects\n        </tabstrigger><tabstrigger value=\"tab-3\" class=\"data-[state=active]:after:bg-primary relative w-full justify-start rounded-none after:absolute after:inset-y-0 after:start-0 after:w-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\">Packages\n        </tabstrigger></tabslist><view class=\"grow rounded-md border text-start\"><tabscontent value=\"tab-1\"><text class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 1</text></tabscontent><tabscontent value=\"tab-2\"><text class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 2</text></tabscontent><tabscontent value=\"tab-3\"><text class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 3</text></tabscontent></view></tabs>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tabs",
          "vertical tabs",
          "radix"
        ],
        "colSpan": 2,
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tabs-18",
          "group": "tabs",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tabs-18",
              "path": "registry/default/components/tabs/tabs-18.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tabs-18",
              "path": "registry/default/components/tabs/tabs-18.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tabs-18",
              "path": "registry/default/components/tabs/tabs-18.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tabs-18",
              "path": "registry/default/components/tabs/tabs-18.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tabs",
        "title": "Tabs · Basic tabs"
      },
      "categories": [
        "tabs"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "tabs-19",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/tabs.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/tabs/tabs-19.tsx",
          "type": "registry:component",
          "target": "components/ui/tabs-19.tsx",
          "content": "import { Tabs, TabsContent, TabsList, TabsTrigger } from '@timui/react'\nimport { BoxIcon, HouseIcon, PanelsTopLeftIcon } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <Tabs defaultValue=\"tab-1\" orientation=\"vertical\" className=\"w-full flex-row\">\n      <TabsList className=\"text-foreground flex-col gap-1 rounded-none bg-transparent px-1 py-0\">\n        <TabsTrigger\n          value=\"tab-1\"\n          className=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative w-full justify-start after:absolute after:inset-y-0 after:start-0 after:-ms-1 after:w-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"\n        >\n          <HouseIcon className=\"-ms-0.5 me-1.5 opacity-60\" size={16} aria-hidden=\"true\" />\n          Overview\n        </TabsTrigger>\n        <TabsTrigger\n          value=\"tab-2\"\n          className=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative w-full justify-start after:absolute after:inset-y-0 after:start-0 after:-ms-1 after:w-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"\n        >\n          <PanelsTopLeftIcon className=\"-ms-0.5 me-1.5 opacity-60\" size={16} aria-hidden=\"true\" />\n          Projects\n        </TabsTrigger>\n        <TabsTrigger\n          value=\"tab-3\"\n          className=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative w-full justify-start after:absolute after:inset-y-0 after:start-0 after:-ms-1 after:w-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"\n        >\n          <BoxIcon className=\"-ms-0.5 me-1.5 opacity-60\" size={16} aria-hidden=\"true\" />\n          Packages\n        </TabsTrigger>\n      </TabsList>\n      <div className=\"grow rounded-md border text-start\">\n        <TabsContent value=\"tab-1\">\n          <p className=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 1</p>\n        </TabsContent>\n        <TabsContent value=\"tab-2\">\n          <p className=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 2</p>\n        </TabsContent>\n        <TabsContent value=\"tab-3\">\n          <p className=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 3</p>\n        </TabsContent>\n      </div>\n    </Tabs>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-19.vue",
          "target": "components/ui/tabs-19.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { BoxIcon, HouseIcon, PanelsTopLeftIcon } from 'lucide-vue-next';\nimport { Tabs } from '@timui/vue';\nimport { TabsContent } from '@timui/vue';\nimport { TabsList } from '@timui/vue';\nimport { TabsTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Tabs default-value=\"tab-1\" orientation=\"vertical\" class=\"w-full flex-row\"><TabsList class=\"text-foreground flex-col gap-1 rounded-none bg-transparent px-1 py-0\"><TabsTrigger value=\"tab-1\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative w-full justify-start after:absolute after:inset-y-0 after:start-0 after:-ms-1 after:w-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><HouseIcon class=\"-ms-0.5 me-1.5 opacity-60\" :size=\"16\" aria-hidden=\"true\" />Overview\n        </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative w-full justify-start after:absolute after:inset-y-0 after:start-0 after:-ms-1 after:w-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><PanelsTopLeftIcon class=\"-ms-0.5 me-1.5 opacity-60\" :size=\"16\" aria-hidden=\"true\" />Projects\n        </TabsTrigger><TabsTrigger value=\"tab-3\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative w-full justify-start after:absolute after:inset-y-0 after:start-0 after:-ms-1 after:w-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><BoxIcon class=\"-ms-0.5 me-1.5 opacity-60\" :size=\"16\" aria-hidden=\"true\" />Packages\n        </TabsTrigger></TabsList><div class=\"grow rounded-md border text-start\"><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 3</p></TabsContent></div></Tabs>\n</template>\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-19.html",
          "target": "components/ui/tabs-19.html",
          "type": "registry:component",
          "content": "<template>\n  <Tabs default-value=\"tab-1\" orientation=\"vertical\" class=\"w-full flex-row\"><TabsList class=\"text-foreground flex-col gap-1 rounded-none bg-transparent px-1 py-0\"><TabsTrigger value=\"tab-1\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative w-full justify-start after:absolute after:inset-y-0 after:start-0 after:-ms-1 after:w-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><HouseIcon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Overview\n        </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative w-full justify-start after:absolute after:inset-y-0 after:start-0 after:-ms-1 after:w-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><PanelsTopLeftIcon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Projects\n        </TabsTrigger><TabsTrigger value=\"tab-3\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative w-full justify-start after:absolute after:inset-y-0 after:start-0 after:-ms-1 after:w-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><BoxIcon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Packages\n        </TabsTrigger></TabsList><div class=\"grow rounded-md border text-start\"><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 3</p></TabsContent></div></Tabs>\n</template>"
        },
        {
          "path": "registry/default/components/tabs/tabs-19.wxml",
          "target": "components/ui/tabs-19/tabs-19.wxml",
          "type": "registry:component",
          "content": "<view>\n  <tabs default-value=\"tab-1\" orientation=\"vertical\" class=\"w-full flex-row\"><tabslist class=\"text-foreground flex-col gap-1 rounded-none bg-transparent px-1 py-0\"><tabstrigger value=\"tab-1\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative w-full justify-start after:absolute after:inset-y-0 after:start-0 after:-ms-1 after:w-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><houseicon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Overview\n        </tabstrigger><tabstrigger value=\"tab-2\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative w-full justify-start after:absolute after:inset-y-0 after:start-0 after:-ms-1 after:w-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><panelstoplefticon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Projects\n        </tabstrigger><tabstrigger value=\"tab-3\" class=\"hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative w-full justify-start after:absolute after:inset-y-0 after:start-0 after:-ms-1 after:w-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none\"><boxicon class=\"-ms-0.5 me-1.5 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Packages\n        </tabstrigger></tabslist><view class=\"grow rounded-md border text-start\"><tabscontent value=\"tab-1\"><text class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 1</text></tabscontent><tabscontent value=\"tab-2\"><text class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 2</text></tabscontent><tabscontent value=\"tab-3\"><text class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 3</text></tabscontent></view></tabs>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tabs",
          "vertical tabs",
          "radix"
        ],
        "colSpan": 2,
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tabs-19",
          "group": "tabs",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tabs-19",
              "path": "registry/default/components/tabs/tabs-19.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tabs-19",
              "path": "registry/default/components/tabs/tabs-19.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tabs-19",
              "path": "registry/default/components/tabs/tabs-19.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tabs-19",
              "path": "registry/default/components/tabs/tabs-19.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tabs",
        "title": "Tabs · Basic tabs"
      },
      "categories": [
        "tabs"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "tabs-20",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/tabs.json"
      ],
      "files": [
        {
          "path": "registry/default/components/tabs/tabs-20.tsx",
          "type": "registry:component",
          "target": "components/ui/tabs-20.tsx",
          "content": "import { Tabs, TabsContent, TabsList, TabsTrigger } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Tabs defaultValue=\"tab-1\" orientation=\"vertical\" className=\"w-full flex-row\">\n      <TabsList className=\"flex-col gap-1 bg-transparent py-0\">\n        <TabsTrigger\n          value=\"tab-1\"\n          className=\"data-[state=active]:bg-muted w-full justify-start data-[state=active]:shadow-none\"\n        >\n          Overview\n        </TabsTrigger>\n        <TabsTrigger\n          value=\"tab-2\"\n          className=\"data-[state=active]:bg-muted w-full justify-start data-[state=active]:shadow-none\"\n        >\n          Projects\n        </TabsTrigger>\n        <TabsTrigger\n          value=\"tab-3\"\n          className=\"data-[state=active]:bg-muted w-full justify-start data-[state=active]:shadow-none\"\n        >\n          Packages\n        </TabsTrigger>\n      </TabsList>\n      <div className=\"grow rounded-md border text-start\">\n        <TabsContent value=\"tab-1\">\n          <p className=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 1</p>\n        </TabsContent>\n        <TabsContent value=\"tab-2\">\n          <p className=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 2</p>\n        </TabsContent>\n        <TabsContent value=\"tab-3\">\n          <p className=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 3</p>\n        </TabsContent>\n      </div>\n    </Tabs>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-20.vue",
          "target": "components/ui/tabs-20.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Tabs } from '@timui/vue';\nimport { TabsContent } from '@timui/vue';\nimport { TabsList } from '@timui/vue';\nimport { TabsTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Tabs default-value=\"tab-1\" orientation=\"vertical\" class=\"w-full flex-row\"><TabsList class=\"flex-col gap-1 bg-transparent py-0\"><TabsTrigger value=\"tab-1\" class=\"data-[state=active]:bg-muted w-full justify-start data-[state=active]:shadow-none\">Overview\n        </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"data-[state=active]:bg-muted w-full justify-start data-[state=active]:shadow-none\">Projects\n        </TabsTrigger><TabsTrigger value=\"tab-3\" class=\"data-[state=active]:bg-muted w-full justify-start data-[state=active]:shadow-none\">Packages\n        </TabsTrigger></TabsList><div class=\"grow rounded-md border text-start\"><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 3</p></TabsContent></div></Tabs>\n</template>\n"
        },
        {
          "path": "registry/default/components/tabs/tabs-20.html",
          "target": "components/ui/tabs-20.html",
          "type": "registry:component",
          "content": "<template>\n  <Tabs default-value=\"tab-1\" orientation=\"vertical\" class=\"w-full flex-row\"><TabsList class=\"flex-col gap-1 bg-transparent py-0\"><TabsTrigger value=\"tab-1\" class=\"data-[state=active]:bg-muted w-full justify-start data-[state=active]:shadow-none\">Overview\n        </TabsTrigger><TabsTrigger value=\"tab-2\" class=\"data-[state=active]:bg-muted w-full justify-start data-[state=active]:shadow-none\">Projects\n        </TabsTrigger><TabsTrigger value=\"tab-3\" class=\"data-[state=active]:bg-muted w-full justify-start data-[state=active]:shadow-none\">Packages\n        </TabsTrigger></TabsList><div class=\"grow rounded-md border text-start\"><TabsContent value=\"tab-1\"><p class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 1</p></TabsContent><TabsContent value=\"tab-2\"><p class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 2</p></TabsContent><TabsContent value=\"tab-3\"><p class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 3</p></TabsContent></div></Tabs>\n</template>"
        },
        {
          "path": "registry/default/components/tabs/tabs-20.wxml",
          "target": "components/ui/tabs-20/tabs-20.wxml",
          "type": "registry:component",
          "content": "<view>\n  <tabs default-value=\"tab-1\" orientation=\"vertical\" class=\"w-full flex-row\"><tabslist class=\"flex-col gap-1 bg-transparent py-0\"><tabstrigger value=\"tab-1\" class=\"data-[state=active]:bg-muted w-full justify-start data-[state=active]:shadow-none\">Overview\n        </tabstrigger><tabstrigger value=\"tab-2\" class=\"data-[state=active]:bg-muted w-full justify-start data-[state=active]:shadow-none\">Projects\n        </tabstrigger><tabstrigger value=\"tab-3\" class=\"data-[state=active]:bg-muted w-full justify-start data-[state=active]:shadow-none\">Packages\n        </tabstrigger></tabslist><view class=\"grow rounded-md border text-start\"><tabscontent value=\"tab-1\"><text class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 1</text></tabscontent><tabscontent value=\"tab-2\"><text class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 2</text></tabscontent><tabscontent value=\"tab-3\"><text class=\"text-muted-foreground px-4 py-3 text-xs\">Content for Tab 3</text></tabscontent></view></tabs>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tabs",
          "vertical tabs",
          "radix"
        ],
        "colSpan": 2,
        "style": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tabs-20",
          "group": "tabs",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tabs-20",
              "path": "registry/default/components/tabs/tabs-20.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tabs-20",
              "path": "registry/default/components/tabs/tabs-20.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tabs-20",
              "path": "registry/default/components/tabs/tabs-20.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tabs-20",
              "path": "registry/default/components/tabs/tabs-20.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tabs",
        "title": "Tabs · Basic tabs"
      },
      "categories": [
        "tabs"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "breadcrumb-01",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/breadcrumb.json",
        "https://ui.timkit.cn/r/dropdown-menu.json"
      ],
      "files": [
        {
          "path": "registry/default/components/breadcrumb/breadcrumb-01.tsx",
          "type": "registry:component",
          "target": "components/ui/breadcrumb-01.tsx",
          "content": "import {\n  Breadcrumb,\n  BreadcrumbEllipsis,\n  BreadcrumbItem,\n  BreadcrumbLink,\n  BreadcrumbList,\n  BreadcrumbPage,\n  BreadcrumbSeparator,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuTrigger,\n} from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Breadcrumb>\n      <BreadcrumbList>\n        <BreadcrumbItem>\n          <BreadcrumbLink href=\"#\">Home</BreadcrumbLink>\n        </BreadcrumbItem>\n        <BreadcrumbSeparator />\n        <BreadcrumbItem>\n          <DropdownMenu>\n            <DropdownMenuTrigger className=\"hover:text-foreground\">\n              <BreadcrumbEllipsis />\n              <span className=\"sr-only\">Toggle menu</span>\n            </DropdownMenuTrigger>\n            <DropdownMenuContent align=\"start\">\n              <DropdownMenuItem asChild>\n                <a href=\"#\">Documentation</a>\n              </DropdownMenuItem>\n              <DropdownMenuItem asChild>\n                <a href=\"#\">Themes</a>\n              </DropdownMenuItem>\n              <DropdownMenuItem asChild>\n                <a href=\"#\">GitHub</a>\n              </DropdownMenuItem>\n            </DropdownMenuContent>\n          </DropdownMenu>\n        </BreadcrumbItem>\n        <BreadcrumbSeparator />\n        <BreadcrumbItem>\n          <BreadcrumbLink href=\"#\">Components</BreadcrumbLink>\n        </BreadcrumbItem>\n        <BreadcrumbSeparator />\n        <BreadcrumbItem>\n          <BreadcrumbPage>Breadcrumb</BreadcrumbPage>\n        </BreadcrumbItem>\n      </BreadcrumbList>\n    </Breadcrumb>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/breadcrumb/breadcrumb-01.vue",
          "target": "components/ui/breadcrumb-01.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from '@timui/vue';\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Breadcrumb><BreadcrumbList><BreadcrumbItem><BreadcrumbLink href=\"#\">Home</BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator /><BreadcrumbItem><DropdownMenu><DropdownMenuTrigger class=\"hover:text-foreground\"><BreadcrumbEllipsis /><span class=\"sr-only\">Toggle menu</span></DropdownMenuTrigger><DropdownMenuContent align=\"start\"><DropdownMenuItem as-child><a href=\"#\">Documentation</a></DropdownMenuItem><DropdownMenuItem as-child><a href=\"#\">Themes</a></DropdownMenuItem><DropdownMenuItem as-child><a href=\"#\">GitHub</a></DropdownMenuItem></DropdownMenuContent></DropdownMenu></BreadcrumbItem><BreadcrumbSeparator /><BreadcrumbItem><BreadcrumbLink href=\"#\">Components</BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator /><BreadcrumbItem><BreadcrumbPage>Breadcrumb</BreadcrumbPage></BreadcrumbItem></BreadcrumbList></Breadcrumb>\n</template>\n"
        },
        {
          "path": "registry/default/components/breadcrumb/breadcrumb-01.html",
          "target": "components/ui/breadcrumb-01.html",
          "type": "registry:component",
          "content": "<template>\n  <Breadcrumb><BreadcrumbList><BreadcrumbItem><BreadcrumbLink href=\"#\">Home</BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator /><BreadcrumbItem><DropdownMenu><DropdownMenuTrigger class=\"hover:text-foreground\"><BreadcrumbEllipsis /><span class=\"sr-only\">Toggle menu</span></DropdownMenuTrigger><DropdownMenuContent align=\"start\"><DropdownMenuItem aschild><a href=\"#\">Documentation</a></DropdownMenuItem><DropdownMenuItem aschild><a href=\"#\">Themes</a></DropdownMenuItem><DropdownMenuItem aschild><a href=\"#\">GitHub</a></DropdownMenuItem></DropdownMenuContent></DropdownMenu></BreadcrumbItem><BreadcrumbSeparator /><BreadcrumbItem><BreadcrumbLink href=\"#\">Components</BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator /><BreadcrumbItem><BreadcrumbPage>Breadcrumb</BreadcrumbPage></BreadcrumbItem></BreadcrumbList></Breadcrumb>\n</template>"
        },
        {
          "path": "registry/default/components/breadcrumb/breadcrumb-01.wxml",
          "target": "components/ui/breadcrumb-01/breadcrumb-01.wxml",
          "type": "registry:component",
          "content": "<view>\n  <breadcrumb><breadcrumblist><breadcrumbitem><breadcrumblink href=\"#\">Home</breadcrumblink></breadcrumbitem><breadcrumbseparator /><breadcrumbitem><dropdownmenu><dropdownmenutrigger class=\"hover:text-foreground\"><breadcrumbellipsis /><text class=\"sr-only\">Toggle menu</text></dropdownmenutrigger><dropdownmenucontent align=\"start\"><dropdownmenuitem aschild><a href=\"#\">Documentation</a></dropdownmenuitem><dropdownmenuitem aschild><a href=\"#\">Themes</a></dropdownmenuitem><dropdownmenuitem aschild><a href=\"#\">GitHub</a></dropdownmenuitem></dropdownmenucontent></dropdownmenu></breadcrumbitem><breadcrumbseparator /><breadcrumbitem><breadcrumblink href=\"#\">Components</breadcrumblink></breadcrumbitem><breadcrumbseparator /><breadcrumbitem><breadcrumbpage>Breadcrumb</breadcrumbpage></breadcrumbitem></breadcrumblist></breadcrumb>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "breadcrumb",
          "radix"
        ],
        "colSpan": 2,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "breadcrumb-01",
          "group": "breadcrumb",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "breadcrumb-01",
              "path": "registry/default/components/breadcrumb/breadcrumb-01.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "breadcrumb-01",
              "path": "registry/default/components/breadcrumb/breadcrumb-01.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "breadcrumb-01",
              "path": "registry/default/components/breadcrumb/breadcrumb-01.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "breadcrumb-01",
              "path": "registry/default/components/breadcrumb/breadcrumb-01.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "breadcrumb",
        "title": "Breadcrumb · Interactive State"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "breadcrumb"
      ]
    },
    {
      "name": "breadcrumb-02",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/breadcrumb.json",
        "https://ui.timkit.cn/r/dropdown-menu.json"
      ],
      "files": [
        {
          "path": "registry/default/components/breadcrumb/breadcrumb-02.tsx",
          "type": "registry:component",
          "target": "components/ui/breadcrumb-02.tsx",
          "content": "import {\n  Breadcrumb,\n  BreadcrumbItem,\n  BreadcrumbLink,\n  BreadcrumbList,\n  BreadcrumbPage,\n  BreadcrumbSeparator,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuTrigger,\n} from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Breadcrumb>\n      <BreadcrumbList>\n        <BreadcrumbItem>\n          <BreadcrumbLink href=\"#\">Home</BreadcrumbLink>\n        </BreadcrumbItem>\n        <BreadcrumbSeparator />\n        <BreadcrumbItem>\n          <DropdownMenu>\n            <DropdownMenuTrigger className=\"hover:text-foreground\">\n              <span\n                role=\"presentation\"\n                aria-hidden=\"true\"\n                className=\"flex size-5 items-center justify-center\"\n              >\n                <svg\n                  width={16}\n                  height={16}\n                  viewBox=\"0 0 24 24\"\n                  fill=\"none\"\n                  stroke=\"currentColor\"\n                  strokeWidth=\"2\"\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  aria-hidden=\"true\"\n                >\n                  <path d=\"M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\" />\n                </svg>\n              </span>\n              <span className=\"sr-only\">Toggle menu</span>\n            </DropdownMenuTrigger>\n            <DropdownMenuContent align=\"start\">\n              <DropdownMenuItem asChild>\n                <a href=\"#\">Documentation</a>\n              </DropdownMenuItem>\n              <DropdownMenuItem asChild>\n                <a href=\"#\">Themes</a>\n              </DropdownMenuItem>\n              <DropdownMenuItem asChild>\n                <a href=\"#\">GitHub</a>\n              </DropdownMenuItem>\n            </DropdownMenuContent>\n          </DropdownMenu>\n        </BreadcrumbItem>\n        <BreadcrumbSeparator />\n        <BreadcrumbItem>\n          <BreadcrumbPage>Breadcrumb</BreadcrumbPage>\n        </BreadcrumbItem>\n      </BreadcrumbList>\n    </Breadcrumb>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/breadcrumb/breadcrumb-02.vue",
          "target": "components/ui/breadcrumb-02.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from '@timui/vue';\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Breadcrumb><BreadcrumbList><BreadcrumbItem><BreadcrumbLink href=\"#\">Home</BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator /><BreadcrumbItem><DropdownMenu><DropdownMenuTrigger class=\"hover:text-foreground\"><span role=\"presentation\" aria-hidden=\"true\" class=\"flex size-5 items-center justify-center\"><svg :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\" /></svg></span><span class=\"sr-only\">Toggle menu</span></DropdownMenuTrigger><DropdownMenuContent align=\"start\"><DropdownMenuItem as-child><a href=\"#\">Documentation</a></DropdownMenuItem><DropdownMenuItem as-child><a href=\"#\">Themes</a></DropdownMenuItem><DropdownMenuItem as-child><a href=\"#\">GitHub</a></DropdownMenuItem></DropdownMenuContent></DropdownMenu></BreadcrumbItem><BreadcrumbSeparator /><BreadcrumbItem><BreadcrumbPage>Breadcrumb</BreadcrumbPage></BreadcrumbItem></BreadcrumbList></Breadcrumb>\n</template>\n"
        },
        {
          "path": "registry/default/components/breadcrumb/breadcrumb-02.html",
          "target": "components/ui/breadcrumb-02.html",
          "type": "registry:component",
          "content": "<template>\n  <Breadcrumb><BreadcrumbList><BreadcrumbItem><BreadcrumbLink href=\"#\">Home</BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator /><BreadcrumbItem><DropdownMenu><DropdownMenuTrigger class=\"hover:text-foreground\"><span role=\"presentation\" aria-hidden=\"true\" class=\"flex size-5 items-center justify-center\"><svg width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\" /></svg></span><span class=\"sr-only\">Toggle menu</span></DropdownMenuTrigger><DropdownMenuContent align=\"start\"><DropdownMenuItem aschild><a href=\"#\">Documentation</a></DropdownMenuItem><DropdownMenuItem aschild><a href=\"#\">Themes</a></DropdownMenuItem><DropdownMenuItem aschild><a href=\"#\">GitHub</a></DropdownMenuItem></DropdownMenuContent></DropdownMenu></BreadcrumbItem><BreadcrumbSeparator /><BreadcrumbItem><BreadcrumbPage>Breadcrumb</BreadcrumbPage></BreadcrumbItem></BreadcrumbList></Breadcrumb>\n</template>"
        },
        {
          "path": "registry/default/components/breadcrumb/breadcrumb-02.wxml",
          "target": "components/ui/breadcrumb-02/breadcrumb-02.wxml",
          "type": "registry:component",
          "content": "<view>\n  <breadcrumb><breadcrumblist><breadcrumbitem><breadcrumblink href=\"#\">Home</breadcrumblink></breadcrumbitem><breadcrumbseparator /><breadcrumbitem><dropdownmenu><dropdownmenutrigger class=\"hover:text-foreground\"><text role=\"presentation\" aria-hidden=\"true\" class=\"flex size-5 items-center justify-center\"><svg width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\" /></svg></text><text class=\"sr-only\">Toggle menu</text></dropdownmenutrigger><dropdownmenucontent align=\"start\"><dropdownmenuitem aschild><a href=\"#\">Documentation</a></dropdownmenuitem><dropdownmenuitem aschild><a href=\"#\">Themes</a></dropdownmenuitem><dropdownmenuitem aschild><a href=\"#\">GitHub</a></dropdownmenuitem></dropdownmenucontent></dropdownmenu></breadcrumbitem><breadcrumbseparator /><breadcrumbitem><breadcrumbpage>Breadcrumb</breadcrumbpage></breadcrumbitem></breadcrumblist></breadcrumb>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "breadcrumb",
          "dropdown",
          "radix"
        ],
        "colSpan": 2,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "breadcrumb-02",
          "group": "breadcrumb",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "breadcrumb-02",
              "path": "registry/default/components/breadcrumb/breadcrumb-02.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "breadcrumb-02",
              "path": "registry/default/components/breadcrumb/breadcrumb-02.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "breadcrumb-02",
              "path": "registry/default/components/breadcrumb/breadcrumb-02.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "breadcrumb-02",
              "path": "registry/default/components/breadcrumb/breadcrumb-02.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "breadcrumb",
        "title": "Breadcrumb · Interactive State"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "breadcrumb"
      ]
    },
    {
      "name": "breadcrumb-03",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/breadcrumb.json"
      ],
      "files": [
        {
          "path": "registry/default/components/breadcrumb/breadcrumb-03.tsx",
          "type": "registry:component",
          "target": "components/ui/breadcrumb-03.tsx",
          "content": "import {\n  Breadcrumb,\n  BreadcrumbItem,\n  BreadcrumbLink,\n  BreadcrumbList,\n  BreadcrumbPage,\n  BreadcrumbSeparator,\n} from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Breadcrumb>\n      <BreadcrumbList>\n        <BreadcrumbItem>\n          <BreadcrumbLink href=\"#\">\n            <svg\n              width={16}\n              height={16}\n              viewBox=\"0 0 24 24\"\n              fill=\"none\"\n              stroke=\"currentColor\"\n              strokeWidth=\"2\"\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              aria-hidden=\"true\"\n            >\n              <path d=\"M3 10l9-7 9 7\" />\n              <path d=\"M5 10v10h5v-6h4v6h5V10\" />\n            </svg>\n            <span className=\"sr-only\">Home</span>\n          </BreadcrumbLink>\n        </BreadcrumbItem>\n        <BreadcrumbSeparator />\n        <BreadcrumbItem>\n          <BreadcrumbLink href=\"#\">Components</BreadcrumbLink>\n        </BreadcrumbItem>\n        <BreadcrumbSeparator />\n        <BreadcrumbItem>\n          <BreadcrumbPage>Breadcrumb</BreadcrumbPage>\n        </BreadcrumbItem>\n      </BreadcrumbList>\n    </Breadcrumb>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/breadcrumb/breadcrumb-03.vue",
          "target": "components/ui/breadcrumb-03.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Breadcrumb><BreadcrumbList><BreadcrumbItem><BreadcrumbLink href=\"#\"><svg :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 10l9-7 9 7\" /><path d=\"M5 10v10h5v-6h4v6h5V10\" /></svg><span class=\"sr-only\">Home</span></BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator /><BreadcrumbItem><BreadcrumbLink href=\"#\">Components</BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator /><BreadcrumbItem><BreadcrumbPage>Breadcrumb</BreadcrumbPage></BreadcrumbItem></BreadcrumbList></Breadcrumb>\n</template>\n"
        },
        {
          "path": "registry/default/components/breadcrumb/breadcrumb-03.html",
          "target": "components/ui/breadcrumb-03.html",
          "type": "registry:component",
          "content": "<template>\n  <Breadcrumb><BreadcrumbList><BreadcrumbItem><BreadcrumbLink href=\"#\"><svg width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 10l9-7 9 7\" /><path d=\"M5 10v10h5v-6h4v6h5V10\" /></svg><span class=\"sr-only\">Home</span></BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator /><BreadcrumbItem><BreadcrumbLink href=\"#\">Components</BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator /><BreadcrumbItem><BreadcrumbPage>Breadcrumb</BreadcrumbPage></BreadcrumbItem></BreadcrumbList></Breadcrumb>\n</template>"
        },
        {
          "path": "registry/default/components/breadcrumb/breadcrumb-03.wxml",
          "target": "components/ui/breadcrumb-03/breadcrumb-03.wxml",
          "type": "registry:component",
          "content": "<view>\n  <breadcrumb><breadcrumblist><breadcrumbitem><breadcrumblink href=\"#\"><svg width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 10l9-7 9 7\" /><path d=\"M5 10v10h5v-6h4v6h5V10\" /></svg><text class=\"sr-only\">Home</text></breadcrumblink></breadcrumbitem><breadcrumbseparator /><breadcrumbitem><breadcrumblink href=\"#\">Components</breadcrumblink></breadcrumbitem><breadcrumbseparator /><breadcrumbitem><breadcrumbpage>Breadcrumb</breadcrumbpage></breadcrumbitem></breadcrumblist></breadcrumb>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "breadcrumb",
          "radix"
        ],
        "colSpan": 2,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "breadcrumb-03",
          "group": "breadcrumb",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "breadcrumb-03",
              "path": "registry/default/components/breadcrumb/breadcrumb-03.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "breadcrumb-03",
              "path": "registry/default/components/breadcrumb/breadcrumb-03.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "breadcrumb-03",
              "path": "registry/default/components/breadcrumb/breadcrumb-03.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "breadcrumb-03",
              "path": "registry/default/components/breadcrumb/breadcrumb-03.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "breadcrumb",
        "title": "Breadcrumb · Paging Pattern"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "breadcrumb"
      ]
    },
    {
      "name": "breadcrumb-04",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/breadcrumb.json"
      ],
      "files": [
        {
          "path": "registry/default/components/breadcrumb/breadcrumb-04.tsx",
          "type": "registry:component",
          "target": "components/ui/breadcrumb-04.tsx",
          "content": "import {\n  Breadcrumb,\n  BreadcrumbItem,\n  BreadcrumbLink,\n  BreadcrumbList,\n  BreadcrumbPage,\n  BreadcrumbSeparator,\n} from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Breadcrumb>\n      <BreadcrumbList>\n        <BreadcrumbItem>\n          <BreadcrumbLink href=\"#\" className=\"inline-flex items-center gap-1.5\">\n            <svg\n              width={16}\n              height={16}\n              viewBox=\"0 0 24 24\"\n              fill=\"none\"\n              stroke=\"currentColor\"\n              strokeWidth=\"2\"\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              aria-hidden=\"true\"\n            >\n              <path d=\"M3 10l9-7 9 7\" />\n              <path d=\"M5 10v10h5v-6h4v6h5V10\" />\n            </svg>\n            Home\n          </BreadcrumbLink>\n        </BreadcrumbItem>\n        <BreadcrumbSeparator />\n        <BreadcrumbItem>\n          <BreadcrumbLink href=\"#\" className=\"inline-flex items-center gap-1.5\">\n            <svg\n              width={16}\n              height={16}\n              viewBox=\"0 0 24 24\"\n              fill=\"none\"\n              stroke=\"currentColor\"\n              strokeWidth=\"2\"\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              aria-hidden=\"true\"\n            >\n              <rect x=\"3\" y=\"3\" width=\"7\" height=\"7\" rx=\"1\" />\n              <rect x=\"14\" y=\"3\" width=\"7\" height=\"7\" rx=\"1\" />\n              <rect x=\"14\" y=\"14\" width=\"7\" height=\"7\" rx=\"1\" />\n              <rect x=\"3\" y=\"14\" width=\"7\" height=\"7\" rx=\"1\" />\n            </svg>\n            Components\n          </BreadcrumbLink>\n        </BreadcrumbItem>\n        <BreadcrumbSeparator />\n        <BreadcrumbItem>\n          <BreadcrumbPage>Breadcrumb</BreadcrumbPage>\n        </BreadcrumbItem>\n      </BreadcrumbList>\n    </Breadcrumb>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/breadcrumb/breadcrumb-04.vue",
          "target": "components/ui/breadcrumb-04.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Breadcrumb><BreadcrumbList><BreadcrumbItem><BreadcrumbLink href=\"#\" class=\"inline-flex items-center gap-1.5\"><svg :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 10l9-7 9 7\" /><path d=\"M5 10v10h5v-6h4v6h5V10\" /></svg>Home\n          </BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator /><BreadcrumbItem><BreadcrumbLink href=\"#\" class=\"inline-flex items-center gap-1.5\"><svg :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"3\" y=\"3\" width=\"7\" height=\"7\" rx=\"1\" /><rect x=\"14\" y=\"3\" width=\"7\" height=\"7\" rx=\"1\" /><rect x=\"14\" y=\"14\" width=\"7\" height=\"7\" rx=\"1\" /><rect x=\"3\" y=\"14\" width=\"7\" height=\"7\" rx=\"1\" /></svg>Components\n          </BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator /><BreadcrumbItem><BreadcrumbPage>Breadcrumb</BreadcrumbPage></BreadcrumbItem></BreadcrumbList></Breadcrumb>\n</template>\n"
        },
        {
          "path": "registry/default/components/breadcrumb/breadcrumb-04.html",
          "target": "components/ui/breadcrumb-04.html",
          "type": "registry:component",
          "content": "<template>\n  <Breadcrumb><BreadcrumbList><BreadcrumbItem><BreadcrumbLink href=\"#\" class=\"inline-flex items-center gap-1.5\"><svg width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 10l9-7 9 7\" /><path d=\"M5 10v10h5v-6h4v6h5V10\" /></svg>Home\n          </BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator /><BreadcrumbItem><BreadcrumbLink href=\"#\" class=\"inline-flex items-center gap-1.5\"><svg width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"3\" y=\"3\" width=\"7\" height=\"7\" rx=\"1\" /><rect x=\"14\" y=\"3\" width=\"7\" height=\"7\" rx=\"1\" /><rect x=\"14\" y=\"14\" width=\"7\" height=\"7\" rx=\"1\" /><rect x=\"3\" y=\"14\" width=\"7\" height=\"7\" rx=\"1\" /></svg>Components\n          </BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator /><BreadcrumbItem><BreadcrumbPage>Breadcrumb</BreadcrumbPage></BreadcrumbItem></BreadcrumbList></Breadcrumb>\n</template>"
        },
        {
          "path": "registry/default/components/breadcrumb/breadcrumb-04.wxml",
          "target": "components/ui/breadcrumb-04/breadcrumb-04.wxml",
          "type": "registry:component",
          "content": "<view>\n  <breadcrumb><breadcrumblist><breadcrumbitem><breadcrumblink href=\"#\" class=\"inline-flex items-center gap-1.5\"><svg width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 10l9-7 9 7\" /><path d=\"M5 10v10h5v-6h4v6h5V10\" /></svg>Home\n          </breadcrumblink></breadcrumbitem><breadcrumbseparator /><breadcrumbitem><breadcrumblink href=\"#\" class=\"inline-flex items-center gap-1.5\"><svg width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"3\" y=\"3\" width=\"7\" height=\"7\" rx=\"1\" /><rect x=\"14\" y=\"3\" width=\"7\" height=\"7\" rx=\"1\" /><rect x=\"14\" y=\"14\" width=\"7\" height=\"7\" rx=\"1\" /><rect x=\"3\" y=\"14\" width=\"7\" height=\"7\" rx=\"1\" /></svg>Components\n          </breadcrumblink></breadcrumbitem><breadcrumbseparator /><breadcrumbitem><breadcrumbpage>Breadcrumb</breadcrumbpage></breadcrumbitem></breadcrumblist></breadcrumb>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "breadcrumb",
          "radix"
        ],
        "colSpan": 2,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "breadcrumb-04",
          "group": "breadcrumb",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "breadcrumb-04",
              "path": "registry/default/components/breadcrumb/breadcrumb-04.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "breadcrumb-04",
              "path": "registry/default/components/breadcrumb/breadcrumb-04.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "breadcrumb-04",
              "path": "registry/default/components/breadcrumb/breadcrumb-04.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "breadcrumb-04",
              "path": "registry/default/components/breadcrumb/breadcrumb-04.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "breadcrumb",
        "title": "Breadcrumb · Paging Pattern"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "breadcrumb"
      ]
    },
    {
      "name": "breadcrumb-05",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/breadcrumb.json"
      ],
      "files": [
        {
          "path": "registry/default/components/breadcrumb/breadcrumb-05.tsx",
          "type": "registry:component",
          "target": "components/ui/breadcrumb-05.tsx",
          "content": "import {\n  Breadcrumb,\n  BreadcrumbItem,\n  BreadcrumbLink,\n  BreadcrumbList,\n  BreadcrumbPage,\n  BreadcrumbSeparator,\n} from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Breadcrumb>\n      <BreadcrumbList>\n        <BreadcrumbItem>\n          <BreadcrumbLink href=\"#\">\n            <svg\n              width={16}\n              height={16}\n              viewBox=\"0 0 24 24\"\n              fill=\"none\"\n              stroke=\"currentColor\"\n              strokeWidth=\"2\"\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              aria-hidden=\"true\"\n            >\n              <path d=\"M3 10l9-7 9 7\" />\n              <path d=\"M5 10v10h5v-6h4v6h5V10\" />\n            </svg>\n            <span className=\"sr-only\">Home</span>\n          </BreadcrumbLink>\n        </BreadcrumbItem>\n        <BreadcrumbSeparator> / </BreadcrumbSeparator>\n        <BreadcrumbItem>\n          <BreadcrumbLink href=\"#\">Components</BreadcrumbLink>\n        </BreadcrumbItem>\n        <BreadcrumbSeparator> / </BreadcrumbSeparator>\n        <BreadcrumbItem>\n          <BreadcrumbPage>Breadcrumb</BreadcrumbPage>\n        </BreadcrumbItem>\n      </BreadcrumbList>\n    </Breadcrumb>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/breadcrumb/breadcrumb-05.vue",
          "target": "components/ui/breadcrumb-05.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Breadcrumb><BreadcrumbList><BreadcrumbItem><BreadcrumbLink href=\"#\"><svg :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 10l9-7 9 7\" /><path d=\"M5 10v10h5v-6h4v6h5V10\" /></svg><span class=\"sr-only\">Home</span></BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator>/ </BreadcrumbSeparator><BreadcrumbItem><BreadcrumbLink href=\"#\">Components</BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator>/ </BreadcrumbSeparator><BreadcrumbItem><BreadcrumbPage>Breadcrumb</BreadcrumbPage></BreadcrumbItem></BreadcrumbList></Breadcrumb>\n</template>\n"
        },
        {
          "path": "registry/default/components/breadcrumb/breadcrumb-05.html",
          "target": "components/ui/breadcrumb-05.html",
          "type": "registry:component",
          "content": "<template>\n  <Breadcrumb><BreadcrumbList><BreadcrumbItem><BreadcrumbLink href=\"#\"><svg width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 10l9-7 9 7\" /><path d=\"M5 10v10h5v-6h4v6h5V10\" /></svg><span class=\"sr-only\">Home</span></BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator>/ </BreadcrumbSeparator><BreadcrumbItem><BreadcrumbLink href=\"#\">Components</BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator>/ </BreadcrumbSeparator><BreadcrumbItem><BreadcrumbPage>Breadcrumb</BreadcrumbPage></BreadcrumbItem></BreadcrumbList></Breadcrumb>\n</template>"
        },
        {
          "path": "registry/default/components/breadcrumb/breadcrumb-05.wxml",
          "target": "components/ui/breadcrumb-05/breadcrumb-05.wxml",
          "type": "registry:component",
          "content": "<view>\n  <breadcrumb><breadcrumblist><breadcrumbitem><breadcrumblink href=\"#\"><svg width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 10l9-7 9 7\" /><path d=\"M5 10v10h5v-6h4v6h5V10\" /></svg><text class=\"sr-only\">Home</text></breadcrumblink></breadcrumbitem><breadcrumbseparator>/ </breadcrumbseparator><breadcrumbitem><breadcrumblink href=\"#\">Components</breadcrumblink></breadcrumbitem><breadcrumbseparator>/ </breadcrumbseparator><breadcrumbitem><breadcrumbpage>Breadcrumb</breadcrumbpage></breadcrumbitem></breadcrumblist></breadcrumb>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "breadcrumb",
          "radix"
        ],
        "colSpan": 2,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "breadcrumb-05",
          "group": "breadcrumb",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "breadcrumb-05",
              "path": "registry/default/components/breadcrumb/breadcrumb-05.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "breadcrumb-05",
              "path": "registry/default/components/breadcrumb/breadcrumb-05.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "breadcrumb-05",
              "path": "registry/default/components/breadcrumb/breadcrumb-05.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "breadcrumb-05",
              "path": "registry/default/components/breadcrumb/breadcrumb-05.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "breadcrumb",
        "title": "Breadcrumb · Paging Pattern"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "breadcrumb"
      ]
    },
    {
      "name": "breadcrumb-06",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/breadcrumb.json"
      ],
      "files": [
        {
          "path": "registry/default/components/breadcrumb/breadcrumb-06.tsx",
          "type": "registry:component",
          "target": "components/ui/breadcrumb-06.tsx",
          "content": "import {\n  Breadcrumb,\n  BreadcrumbItem,\n  BreadcrumbLink,\n  BreadcrumbList,\n  BreadcrumbPage,\n  BreadcrumbSeparator,\n} from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Breadcrumb>\n      <BreadcrumbList>\n        <BreadcrumbItem>\n          <BreadcrumbLink href=\"#\">\n            <svg\n              width={16}\n              height={16}\n              viewBox=\"0 0 24 24\"\n              fill=\"none\"\n              stroke=\"currentColor\"\n              strokeWidth=\"2\"\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              aria-hidden=\"true\"\n            >\n              <path d=\"M3 10l9-7 9 7\" />\n              <path d=\"M5 10v10h5v-6h4v6h5V10\" />\n            </svg>\n            <span className=\"sr-only\">Home</span>\n          </BreadcrumbLink>\n        </BreadcrumbItem>\n        <BreadcrumbSeparator> · </BreadcrumbSeparator>\n        <BreadcrumbItem>\n          <BreadcrumbLink href=\"#\">Components</BreadcrumbLink>\n        </BreadcrumbItem>\n        <BreadcrumbSeparator> · </BreadcrumbSeparator>\n        <BreadcrumbItem>\n          <BreadcrumbPage>Breadcrumb</BreadcrumbPage>\n        </BreadcrumbItem>\n      </BreadcrumbList>\n    </Breadcrumb>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/breadcrumb/breadcrumb-06.vue",
          "target": "components/ui/breadcrumb-06.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Breadcrumb><BreadcrumbList><BreadcrumbItem><BreadcrumbLink href=\"#\"><svg :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 10l9-7 9 7\" /><path d=\"M5 10v10h5v-6h4v6h5V10\" /></svg><span class=\"sr-only\">Home</span></BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator>· </BreadcrumbSeparator><BreadcrumbItem><BreadcrumbLink href=\"#\">Components</BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator>· </BreadcrumbSeparator><BreadcrumbItem><BreadcrumbPage>Breadcrumb</BreadcrumbPage></BreadcrumbItem></BreadcrumbList></Breadcrumb>\n</template>\n"
        },
        {
          "path": "registry/default/components/breadcrumb/breadcrumb-06.html",
          "target": "components/ui/breadcrumb-06.html",
          "type": "registry:component",
          "content": "<template>\n  <Breadcrumb><BreadcrumbList><BreadcrumbItem><BreadcrumbLink href=\"#\"><svg width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 10l9-7 9 7\" /><path d=\"M5 10v10h5v-6h4v6h5V10\" /></svg><span class=\"sr-only\">Home</span></BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator>· </BreadcrumbSeparator><BreadcrumbItem><BreadcrumbLink href=\"#\">Components</BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator>· </BreadcrumbSeparator><BreadcrumbItem><BreadcrumbPage>Breadcrumb</BreadcrumbPage></BreadcrumbItem></BreadcrumbList></Breadcrumb>\n</template>"
        },
        {
          "path": "registry/default/components/breadcrumb/breadcrumb-06.wxml",
          "target": "components/ui/breadcrumb-06/breadcrumb-06.wxml",
          "type": "registry:component",
          "content": "<view>\n  <breadcrumb><breadcrumblist><breadcrumbitem><breadcrumblink href=\"#\"><svg width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 10l9-7 9 7\" /><path d=\"M5 10v10h5v-6h4v6h5V10\" /></svg><text class=\"sr-only\">Home</text></breadcrumblink></breadcrumbitem><breadcrumbseparator>· </breadcrumbseparator><breadcrumbitem><breadcrumblink href=\"#\">Components</breadcrumblink></breadcrumbitem><breadcrumbseparator>· </breadcrumbseparator><breadcrumbitem><breadcrumbpage>Breadcrumb</breadcrumbpage></breadcrumbitem></breadcrumblist></breadcrumb>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "breadcrumb",
          "radix"
        ],
        "colSpan": 2,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "breadcrumb-06",
          "group": "breadcrumb",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "breadcrumb-06",
              "path": "registry/default/components/breadcrumb/breadcrumb-06.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "breadcrumb-06",
              "path": "registry/default/components/breadcrumb/breadcrumb-06.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "breadcrumb-06",
              "path": "registry/default/components/breadcrumb/breadcrumb-06.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "breadcrumb-06",
              "path": "registry/default/components/breadcrumb/breadcrumb-06.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "breadcrumb",
        "title": "Breadcrumb · Paging Pattern"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "breadcrumb"
      ]
    },
    {
      "name": "breadcrumb-07",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/breadcrumb.json"
      ],
      "files": [
        {
          "path": "registry/default/components/breadcrumb/breadcrumb-07.tsx",
          "type": "registry:component",
          "target": "components/ui/breadcrumb-07.tsx",
          "content": "import {\n  Breadcrumb,\n  BreadcrumbItem,\n  BreadcrumbLink,\n  BreadcrumbList,\n  BreadcrumbPage,\n  BreadcrumbSeparator,\n} from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Breadcrumb>\n      <BreadcrumbList className=\"bg-background rounded-md border px-3 py-2 shadow-xs\">\n        <BreadcrumbItem>\n          <BreadcrumbLink href=\"#\">\n            <svg\n              width={16}\n              height={16}\n              viewBox=\"0 0 24 24\"\n              fill=\"none\"\n              stroke=\"currentColor\"\n              strokeWidth=\"2\"\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              aria-hidden=\"true\"\n            >\n              <path d=\"M3 10l9-7 9 7\" />\n              <path d=\"M5 10v10h5v-6h4v6h5V10\" />\n            </svg>\n            <span className=\"sr-only\">Home</span>\n          </BreadcrumbLink>\n        </BreadcrumbItem>\n        <BreadcrumbSeparator />\n        <BreadcrumbItem>\n          <BreadcrumbLink href=\"#\">Components</BreadcrumbLink>\n        </BreadcrumbItem>\n        <BreadcrumbSeparator />\n        <BreadcrumbItem>\n          <BreadcrumbPage>Breadcrumb</BreadcrumbPage>\n        </BreadcrumbItem>\n      </BreadcrumbList>\n    </Breadcrumb>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/breadcrumb/breadcrumb-07.vue",
          "target": "components/ui/breadcrumb-07.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Breadcrumb><BreadcrumbList class=\"bg-background rounded-md border px-3 py-2 shadow-xs\"><BreadcrumbItem><BreadcrumbLink href=\"#\"><svg :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 10l9-7 9 7\" /><path d=\"M5 10v10h5v-6h4v6h5V10\" /></svg><span class=\"sr-only\">Home</span></BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator /><BreadcrumbItem><BreadcrumbLink href=\"#\">Components</BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator /><BreadcrumbItem><BreadcrumbPage>Breadcrumb</BreadcrumbPage></BreadcrumbItem></BreadcrumbList></Breadcrumb>\n</template>\n"
        },
        {
          "path": "registry/default/components/breadcrumb/breadcrumb-07.html",
          "target": "components/ui/breadcrumb-07.html",
          "type": "registry:component",
          "content": "<template>\n  <Breadcrumb><BreadcrumbList class=\"bg-background rounded-md border px-3 py-2 shadow-xs\"><BreadcrumbItem><BreadcrumbLink href=\"#\"><svg width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 10l9-7 9 7\" /><path d=\"M5 10v10h5v-6h4v6h5V10\" /></svg><span class=\"sr-only\">Home</span></BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator /><BreadcrumbItem><BreadcrumbLink href=\"#\">Components</BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator /><BreadcrumbItem><BreadcrumbPage>Breadcrumb</BreadcrumbPage></BreadcrumbItem></BreadcrumbList></Breadcrumb>\n</template>"
        },
        {
          "path": "registry/default/components/breadcrumb/breadcrumb-07.wxml",
          "target": "components/ui/breadcrumb-07/breadcrumb-07.wxml",
          "type": "registry:component",
          "content": "<view>\n  <breadcrumb><breadcrumblist class=\"bg-background rounded-md border px-3 py-2 shadow-xs\"><breadcrumbitem><breadcrumblink href=\"#\"><svg width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 10l9-7 9 7\" /><path d=\"M5 10v10h5v-6h4v6h5V10\" /></svg><text class=\"sr-only\">Home</text></breadcrumblink></breadcrumbitem><breadcrumbseparator /><breadcrumbitem><breadcrumblink href=\"#\">Components</breadcrumblink></breadcrumbitem><breadcrumbseparator /><breadcrumbitem><breadcrumbpage>Breadcrumb</breadcrumbpage></breadcrumbitem></breadcrumblist></breadcrumb>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "breadcrumb",
          "radix"
        ],
        "colSpan": 2,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "breadcrumb-07",
          "group": "breadcrumb",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "breadcrumb-07",
              "path": "registry/default/components/breadcrumb/breadcrumb-07.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "breadcrumb-07",
              "path": "registry/default/components/breadcrumb/breadcrumb-07.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "breadcrumb-07",
              "path": "registry/default/components/breadcrumb/breadcrumb-07.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "breadcrumb-07",
              "path": "registry/default/components/breadcrumb/breadcrumb-07.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "breadcrumb",
        "title": "Breadcrumb · Paging Pattern"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "breadcrumb"
      ]
    },
    {
      "name": "breadcrumb-08",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/breadcrumb.json",
        "https://ui.timkit.cn/r/select.json"
      ],
      "files": [
        {
          "path": "registry/default/components/breadcrumb/breadcrumb-08.tsx",
          "type": "registry:component",
          "target": "components/ui/breadcrumb-08.tsx",
          "content": "import {\n  Breadcrumb,\n  BreadcrumbItem,\n  BreadcrumbLink,\n  BreadcrumbList,\n  BreadcrumbSeparator,\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from '@timui/react'\n\nexport default function Component() {\n  return (\n    <Breadcrumb>\n      <BreadcrumbList>\n        <BreadcrumbItem>\n          <BreadcrumbLink href=\"#\">Databases</BreadcrumbLink>\n        </BreadcrumbItem>\n        <BreadcrumbSeparator />\n        <BreadcrumbItem>\n          <Select defaultValue=\"1\">\n            <SelectTrigger\n              id=\"select-database\"\n              className=\"relative gap-2 ps-9\"\n              aria-label=\"Select database\"\n            >\n              <div className=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 group-has-[select[disabled]]:opacity-50\">\n                <svg\n                  width={16}\n                  height={16}\n                  viewBox=\"0 0 24 24\"\n                  fill=\"none\"\n                  stroke=\"currentColor\"\n                  strokeWidth=\"2\"\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  aria-hidden=\"true\"\n                >\n                  <ellipse cx=\"12\" cy=\"5\" rx=\"9\" ry=\"3\" />\n                  <path d=\"M3 5v6c0 1.7 4 3 9 3s9-1.3 9-3V5\" />\n                  <path d=\"M3 11v6c0 1.7 4 3 9 3s9-1.3 9-3v-6\" />\n                </svg>\n              </div>\n              <SelectValue placeholder=\"Select database\" />\n            </SelectTrigger>\n            <SelectContent>\n              <SelectItem value=\"1\">Orion</SelectItem>\n              <SelectItem value=\"2\">Sigma</SelectItem>\n              <SelectItem value=\"3\">Dorado</SelectItem>\n            </SelectContent>\n          </Select>\n        </BreadcrumbItem>\n      </BreadcrumbList>\n    </Breadcrumb>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/breadcrumb/breadcrumb-08.vue",
          "target": "components/ui/breadcrumb-08.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbSeparator } from '@timui/vue';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Breadcrumb><BreadcrumbList><BreadcrumbItem><BreadcrumbLink href=\"#\">Databases</BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator /><BreadcrumbItem><Select default-value=\"1\"><SelectTrigger id=\"select-database\" class=\"relative gap-2 ps-9\" aria-label=\"Select database\"><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 group-has-[select[disabled]]:opacity-50\"><svg :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><ellipse cx=\"12\" cy=\"5\" rx=\"9\" ry=\"3\" /><path d=\"M3 5v6c0 1.7 4 3 9 3s9-1.3 9-3V5\" /><path d=\"M3 11v6c0 1.7 4 3 9 3s9-1.3 9-3v-6\" /></svg></div><SelectValue placeholder=\"Select database\" /></SelectTrigger><SelectContent><SelectItem value=\"1\">Orion</SelectItem><SelectItem value=\"2\">Sigma</SelectItem><SelectItem value=\"3\">Dorado</SelectItem></SelectContent></Select></BreadcrumbItem></BreadcrumbList></Breadcrumb>\n</template>\n"
        },
        {
          "path": "registry/default/components/breadcrumb/breadcrumb-08.html",
          "target": "components/ui/breadcrumb-08.html",
          "type": "registry:component",
          "content": "<template>\n  <Breadcrumb><BreadcrumbList><BreadcrumbItem><BreadcrumbLink href=\"#\">Databases</BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator /><BreadcrumbItem><Select default-value=\"1\"><SelectTrigger id=\"select-database\" class=\"relative gap-2 ps-9\" aria-label=\"Select database\"><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 group-has-[select[disabled]]:opacity-50\"><svg width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><ellipse cx=\"12\" cy=\"5\" rx=\"9\" ry=\"3\" /><path d=\"M3 5v6c0 1.7 4 3 9 3s9-1.3 9-3V5\" /><path d=\"M3 11v6c0 1.7 4 3 9 3s9-1.3 9-3v-6\" /></svg></div><SelectValue placeholder=\"Select database\" /></SelectTrigger><SelectContent><SelectItem value=\"1\">Orion</SelectItem><SelectItem value=\"2\">Sigma</SelectItem><SelectItem value=\"3\">Dorado</SelectItem></SelectContent></Select></BreadcrumbItem></BreadcrumbList></Breadcrumb>\n</template>"
        },
        {
          "path": "registry/default/components/breadcrumb/breadcrumb-08.wxml",
          "target": "components/ui/breadcrumb-08/breadcrumb-08.wxml",
          "type": "registry:component",
          "content": "<view>\n  <breadcrumb><breadcrumblist><breadcrumbitem><breadcrumblink href=\"#\">Databases</breadcrumblink></breadcrumbitem><breadcrumbseparator /><breadcrumbitem><select default-value=\"1\"><selecttrigger id=\"select-database\" class=\"relative gap-2 ps-9\" aria-label=\"Select database\"><view class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 group-has-[select[disabled]]:opacity-50\"><svg width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><ellipse cx=\"12\" cy=\"5\" rx=\"9\" ry=\"3\" /><path d=\"M3 5v6c0 1.7 4 3 9 3s9-1.3 9-3V5\" /><path d=\"M3 11v6c0 1.7 4 3 9 3s9-1.3 9-3v-6\" /></svg></view><selectvalue placeholder=\"Select database\" /></selecttrigger><selectcontent><selectitem value=\"1\">Orion</selectitem><selectitem value=\"2\">Sigma</selectitem><selectitem value=\"3\">Dorado</selectitem></selectcontent></select></breadcrumbitem></breadcrumblist></breadcrumb>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "breadcrumb",
          "select",
          "radix"
        ],
        "colSpan": 2,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "breadcrumb-08",
          "group": "breadcrumb",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "breadcrumb-08",
              "path": "registry/default/components/breadcrumb/breadcrumb-08.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "breadcrumb-08",
              "path": "registry/default/components/breadcrumb/breadcrumb-08.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "breadcrumb-08",
              "path": "registry/default/components/breadcrumb/breadcrumb-08.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "breadcrumb-08",
              "path": "registry/default/components/breadcrumb/breadcrumb-08.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "breadcrumb",
        "title": "Breadcrumb · Select database"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "breadcrumb"
      ]
    },
    {
      "name": "pagination-01",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/pagination.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/pagination/pagination-01.tsx",
          "type": "registry:component",
          "target": "components/ui/pagination-01.tsx",
          "content": "import { Button, Pagination, PaginationContent, PaginationItem } from '@timui/react'\nimport { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react'\n\ntype PaginationProps = {\n  currentPage: number\n  totalPages: number\n}\n\nexport default function Component({ currentPage, totalPages }: PaginationProps) {\n  return (\n    <Pagination>\n      <PaginationContent className=\"w-full justify-between gap-3\">\n        <PaginationItem>\n          <Button\n            variant=\"outline\"\n            className=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\"\n            aria-disabled={currentPage === 1 ? true : undefined}\n            role={currentPage === 1 ? 'link' : undefined}\n            asChild\n          >\n            <a href={currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}>\n              <ChevronLeftIcon className=\"-ms-1 opacity-60\" size={16} aria-hidden=\"true\" />\n              Previous\n            </a>\n          </Button>\n        </PaginationItem>\n        <PaginationItem>\n          <Button\n            variant=\"outline\"\n            className=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\"\n            aria-disabled={currentPage === totalPages ? true : undefined}\n            role={currentPage === totalPages ? 'link' : undefined}\n            asChild\n          >\n            <a href={currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`}>\n              Next\n              <ChevronRightIcon className=\"-me-1 opacity-60\" size={16} aria-hidden=\"true\" />\n            </a>\n          </Button>\n        </PaginationItem>\n      </PaginationContent>\n    </Pagination>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/pagination/pagination-01.vue",
          "target": "components/ui/pagination-01.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ChevronLeftIcon, ChevronRightIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { Pagination, PaginationContent, PaginationItem } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Pagination><PaginationContent class=\"w-full justify-between gap-3\"><PaginationItem><Button variant=\"outline\" class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" :aria-disabled=\"currentPage === 1 ? true : undefined\" :role=\"currentPage === 1 ? 'link' : undefined\" as-child><a :href=\"currentPage === 1 ? undefined : `#/page/${currentPage - 1}`\"><ChevronLeftIcon class=\"-ms-1 opacity-60\" :size=\"16\" aria-hidden=\"true\" />Previous\n            </a></Button></PaginationItem><PaginationItem><Button variant=\"outline\" class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" :aria-disabled=\"currentPage === totalPages ? true : undefined\" :role=\"currentPage === totalPages ? 'link' : undefined\" as-child><a :href=\"currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`\">Next\n              <ChevronRightIcon class=\"-me-1 opacity-60\" :size=\"16\" aria-hidden=\"true\" /></a></Button></PaginationItem></PaginationContent></Pagination>\n</template>\n"
        },
        {
          "path": "registry/default/components/pagination/pagination-01.html",
          "target": "components/ui/pagination-01.html",
          "type": "registry:component",
          "content": "<template>\n  <Pagination><PaginationContent class=\"w-full justify-between gap-3\"><PaginationItem><Button variant=\"outline\" class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" aria-disabled=\"${currentPage === 1 ? true : undefined}\" role=\"${currentPage === 1 ? 'link' : undefined}\" aschild><a href=\"${currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}\"><ChevronLeftIcon class=\"-ms-1 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Previous\n            </a></Button></PaginationItem><PaginationItem><Button variant=\"outline\" class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" aria-disabled=\"${currentPage === totalPages ? true : undefined}\" role=\"${currentPage === totalPages ? 'link' : undefined}\" aschild><a href=\"${currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`}\">Next\n              <ChevronRightIcon class=\"-me-1 opacity-60\" size=\"${16}\" aria-hidden=\"true\" /></a></Button></PaginationItem></PaginationContent></Pagination>\n</template>"
        },
        {
          "path": "registry/default/components/pagination/pagination-01.wxml",
          "target": "components/ui/pagination-01/pagination-01.wxml",
          "type": "registry:component",
          "content": "<view>\n  <pagination><paginationcontent class=\"w-full justify-between gap-3\"><paginationitem><button variant=\"outline\" class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" aria-disabled=\"{{currentPage === 1 ? true : undefined}}\" role=\"{{currentPage === 1 ? 'link' : undefined}}\" aschild><a href=\"{{currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}}\"><chevronlefticon class=\"-ms-1 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Previous\n            </a></button></paginationitem><paginationitem><button variant=\"outline\" class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" aria-disabled=\"{{currentPage === totalPages ? true : undefined}}\" role=\"{{currentPage === totalPages ? 'link' : undefined}}\" aschild><a href=\"{{currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`}}\">Next\n              <chevronrighticon class=\"-me-1 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" /></a></button></paginationitem></paginationcontent></pagination>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "pagination"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "pagination-01",
          "group": "pagination",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "pagination-01",
              "path": "registry/default/components/pagination/pagination-01.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "pagination-01",
              "path": "registry/default/components/pagination/pagination-01.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "pagination-01",
              "path": "registry/default/components/pagination/pagination-01.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "pagination-01",
              "path": "registry/default/components/pagination/pagination-01.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "paginations",
        "title": "Pagination · Disabled State"
      },
      "categories": [
        "paginations",
        "pagination"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "pagination-02",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/pagination.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/pagination/pagination-02.tsx",
          "type": "registry:component",
          "target": "components/ui/pagination-02.tsx",
          "content": "import { Button, Pagination, PaginationContent, PaginationItem } from '@timui/react'\nimport { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react'\n\ntype PaginationProps = {\n  currentPage: number\n  totalPages: number\n}\n\nexport default function Component({ currentPage, totalPages }: PaginationProps) {\n  return (\n    <Pagination>\n      <PaginationContent className=\"w-full justify-between gap-3\">\n        <PaginationItem>\n          <Button\n            variant=\"ghost\"\n            className=\"group aria-disabled:pointer-events-none aria-disabled:opacity-50\"\n            aria-disabled={currentPage === 1 ? true : undefined}\n            role={currentPage === 1 ? 'link' : undefined}\n          >\n            <ArrowLeftIcon\n              className=\"-ms-1 opacity-60 transition-transform group-hover:-translate-x-0.5\"\n              size={16}\n              aria-hidden=\"true\"\n            />\n            Previous\n          </Button>\n        </PaginationItem>\n        <PaginationItem>\n          <Button\n            variant=\"ghost\"\n            className=\"group aria-disabled:pointer-events-none aria-disabled:opacity-50\"\n            aria-disabled={currentPage === totalPages ? true : undefined}\n            role={currentPage === totalPages ? 'link' : undefined}\n          >\n            Next\n            <ArrowRightIcon\n              className=\"-me-1 opacity-60 transition-transform group-hover:translate-x-0.5\"\n              size={16}\n              aria-hidden=\"true\"\n            />\n          </Button>\n        </PaginationItem>\n      </PaginationContent>\n    </Pagination>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/pagination/pagination-02.vue",
          "target": "components/ui/pagination-02.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ArrowLeftIcon, ArrowRightIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { Pagination, PaginationContent, PaginationItem } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Pagination><PaginationContent class=\"w-full justify-between gap-3\"><PaginationItem><Button variant=\"ghost\" class=\"group aria-disabled:pointer-events-none aria-disabled:opacity-50\" :aria-disabled=\"currentPage === 1 ? true : undefined\" :role=\"currentPage === 1 ? 'link' : undefined\"><ArrowLeftIcon class=\"-ms-1 opacity-60 transition-transform group-hover:-translate-x-0.5\" :size=\"16\" aria-hidden=\"true\" />Previous\n          </Button></PaginationItem><PaginationItem><Button variant=\"ghost\" class=\"group aria-disabled:pointer-events-none aria-disabled:opacity-50\" :aria-disabled=\"currentPage === totalPages ? true : undefined\" :role=\"currentPage === totalPages ? 'link' : undefined\">Next\n            <ArrowRightIcon class=\"-me-1 opacity-60 transition-transform group-hover:translate-x-0.5\" :size=\"16\" aria-hidden=\"true\" /></Button></PaginationItem></PaginationContent></Pagination>\n</template>\n"
        },
        {
          "path": "registry/default/components/pagination/pagination-02.html",
          "target": "components/ui/pagination-02.html",
          "type": "registry:component",
          "content": "<template>\n  <Pagination><PaginationContent class=\"w-full justify-between gap-3\"><PaginationItem><Button variant=\"ghost\" class=\"group aria-disabled:pointer-events-none aria-disabled:opacity-50\" aria-disabled=\"${currentPage === 1 ? true : undefined}\" role=\"${currentPage === 1 ? 'link' : undefined}\"><ArrowLeftIcon class=\"-ms-1 opacity-60 transition-transform group-hover:-translate-x-0.5\" size=\"${16}\" aria-hidden=\"true\" />Previous\n          </Button></PaginationItem><PaginationItem><Button variant=\"ghost\" class=\"group aria-disabled:pointer-events-none aria-disabled:opacity-50\" aria-disabled=\"${currentPage === totalPages ? true : undefined}\" role=\"${currentPage === totalPages ? 'link' : undefined}\">Next\n            <ArrowRightIcon class=\"-me-1 opacity-60 transition-transform group-hover:translate-x-0.5\" size=\"${16}\" aria-hidden=\"true\" /></Button></PaginationItem></PaginationContent></Pagination>\n</template>"
        },
        {
          "path": "registry/default/components/pagination/pagination-02.wxml",
          "target": "components/ui/pagination-02/pagination-02.wxml",
          "type": "registry:component",
          "content": "<view>\n  <pagination><paginationcontent class=\"w-full justify-between gap-3\"><paginationitem><button variant=\"ghost\" class=\"group aria-disabled:pointer-events-none aria-disabled:opacity-50\" aria-disabled=\"{{currentPage === 1 ? true : undefined}}\" role=\"{{currentPage === 1 ? 'link' : undefined}}\"><arrowlefticon class=\"-ms-1 opacity-60 transition-transform group-hover:-translate-x-0.5\" size=\"{{16}}\" aria-hidden=\"true\" />Previous\n          </button></paginationitem><paginationitem><button variant=\"ghost\" class=\"group aria-disabled:pointer-events-none aria-disabled:opacity-50\" aria-disabled=\"{{currentPage === totalPages ? true : undefined}}\" role=\"{{currentPage === totalPages ? 'link' : undefined}}\">Next\n            <arrowrighticon class=\"-me-1 opacity-60 transition-transform group-hover:translate-x-0.5\" size=\"{{16}}\" aria-hidden=\"true\" /></button></paginationitem></paginationcontent></pagination>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "pagination"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "pagination-02",
          "group": "pagination",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "pagination-02",
              "path": "registry/default/components/pagination/pagination-02.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "pagination-02",
              "path": "registry/default/components/pagination/pagination-02.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "pagination-02",
              "path": "registry/default/components/pagination/pagination-02.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "pagination-02",
              "path": "registry/default/components/pagination/pagination-02.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "paginations",
        "title": "Pagination · Disabled State"
      },
      "categories": [
        "paginations",
        "pagination"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "pagination-03",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/pagination.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/pagination/pagination-03.tsx",
          "type": "registry:component",
          "target": "components/ui/pagination-03.tsx",
          "content": "import { cn } from '@timui/core'\nimport {\n  buttonVariants,\n  Pagination,\n  PaginationContent,\n  PaginationItem,\n  PaginationLink,\n} from '@timui/react'\nimport { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react'\n\ntype PaginationProps = {\n  currentPage: number\n  totalPages: number\n}\n\nexport default function Component({ currentPage, totalPages }: PaginationProps) {\n  return (\n    <Pagination>\n      <PaginationContent className=\"w-full justify-between\">\n        <PaginationItem>\n          <PaginationLink\n            className={cn(\n              'aria-disabled:pointer-events-none aria-disabled:opacity-50',\n              buttonVariants({\n                variant: 'outline',\n              })\n            )}\n            href={currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}\n            aria-label=\"Go to previous page\"\n            aria-disabled={currentPage === 1 ? true : undefined}\n            role={currentPage === 1 ? 'link' : undefined}\n          >\n            <ChevronLeftIcon size={16} aria-hidden=\"true\" />\n          </PaginationLink>\n        </PaginationItem>\n        <PaginationItem>\n          <p className=\"text-muted-foreground text-sm\" aria-live=\"polite\">\n            Page <span className=\"text-foreground\">{currentPage}</span> of{' '}\n            <span className=\"text-foreground\">{totalPages}</span>\n          </p>\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationLink\n            className={cn(\n              'aria-disabled:pointer-events-none aria-disabled:opacity-50',\n              buttonVariants({\n                variant: 'outline',\n              })\n            )}\n            href={currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`}\n            aria-label=\"Go to next page\"\n            aria-disabled={currentPage === totalPages ? true : undefined}\n            role={currentPage === totalPages ? 'link' : undefined}\n          >\n            <ChevronRightIcon size={16} aria-hidden=\"true\" />\n          </PaginationLink>\n        </PaginationItem>\n      </PaginationContent>\n    </Pagination>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/pagination/pagination-03.vue",
          "target": "components/ui/pagination-03.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn } from '@timui/core';\nimport { ChevronLeftIcon, ChevronRightIcon } from 'lucide-vue-next';\nimport { buttonVariants } from '@timui/vue';\nimport { Pagination, PaginationContent, PaginationItem, PaginationLink } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Pagination><PaginationContent class=\"w-full justify-between\"><PaginationItem><PaginationLink :class=\"cn(\n              'aria-disabled:pointer-events-none aria-disabled:opacity-50',\n              buttonVariants({\n                variant: 'outline',\n              })\n            )\" :href=\"currentPage === 1 ? undefined : `#/page/${currentPage - 1}`\" aria-label=\"Go to previous page\" :aria-disabled=\"currentPage === 1 ? true : undefined\" :role=\"currentPage === 1 ? 'link' : undefined\"><ChevronLeftIcon :size=\"16\" aria-hidden=\"true\" /></PaginationLink></PaginationItem><PaginationItem><p class=\"text-muted-foreground text-sm\" aria-live=\"polite\">Page <span class=\"text-foreground\">{{ currentPage }}</span>of{{ ' ' }}<span class=\"text-foreground\">{{ totalPages }}</span></p></PaginationItem><PaginationItem><PaginationLink :class=\"cn(\n              'aria-disabled:pointer-events-none aria-disabled:opacity-50',\n              buttonVariants({\n                variant: 'outline',\n              })\n            )\" :href=\"currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`\" aria-label=\"Go to next page\" :aria-disabled=\"currentPage === totalPages ? true : undefined\" :role=\"currentPage === totalPages ? 'link' : undefined\"><ChevronRightIcon :size=\"16\" aria-hidden=\"true\" /></PaginationLink></PaginationItem></PaginationContent></Pagination>\n</template>\n"
        },
        {
          "path": "registry/default/components/pagination/pagination-03.html",
          "target": "components/ui/pagination-03.html",
          "type": "registry:component",
          "content": "<template>\n  <Pagination><PaginationContent class=\"w-full justify-between\"><PaginationItem><PaginationLink class=\"${cn(\n              'aria-disabled:pointer-events-none aria-disabled:opacity-50',\n              buttonVariants({\n                variant: 'outline',\n              })\n            )}\" href=\"${currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}\" aria-label=\"Go to previous page\" aria-disabled=\"${currentPage === 1 ? true : undefined}\" role=\"${currentPage === 1 ? 'link' : undefined}\"><ChevronLeftIcon size=\"${16}\" aria-hidden=\"true\" /></PaginationLink></PaginationItem><PaginationItem><p class=\"text-muted-foreground text-sm\" aria-live=\"polite\">Page <span class=\"text-foreground\">${currentPage}</span>of${' '}<span class=\"text-foreground\">${totalPages}</span></p></PaginationItem><PaginationItem><PaginationLink class=\"${cn(\n              'aria-disabled:pointer-events-none aria-disabled:opacity-50',\n              buttonVariants({\n                variant: 'outline',\n              })\n            )}\" href=\"${currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`}\" aria-label=\"Go to next page\" aria-disabled=\"${currentPage === totalPages ? true : undefined}\" role=\"${currentPage === totalPages ? 'link' : undefined}\"><ChevronRightIcon size=\"${16}\" aria-hidden=\"true\" /></PaginationLink></PaginationItem></PaginationContent></Pagination>\n</template>"
        },
        {
          "path": "registry/default/components/pagination/pagination-03.wxml",
          "target": "components/ui/pagination-03/pagination-03.wxml",
          "type": "registry:component",
          "content": "<view>\n  <pagination><paginationcontent class=\"w-full justify-between\"><paginationitem><paginationlink class=\"{{cn(\n              'aria-disabled:pointer-events-none aria-disabled:opacity-50',\n              buttonVariants({\n                variant: 'outline',\n              })\n            )}}\" href=\"{{currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}}\" aria-label=\"Go to previous page\" aria-disabled=\"{{currentPage === 1 ? true : undefined}}\" role=\"{{currentPage === 1 ? 'link' : undefined}}\"><chevronlefticon size=\"{{16}}\" aria-hidden=\"true\" /></paginationlink></paginationitem><paginationitem><text class=\"text-muted-foreground text-sm\" aria-live=\"polite\">Page <text class=\"text-foreground\">{{ currentPage }}</text>of{{ ' ' }}<text class=\"text-foreground\">{{ totalPages }}</text></text></paginationitem><paginationitem><paginationlink class=\"{{cn(\n              'aria-disabled:pointer-events-none aria-disabled:opacity-50',\n              buttonVariants({\n                variant: 'outline',\n              })\n            )}}\" href=\"{{currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`}}\" aria-label=\"Go to next page\" aria-disabled=\"{{currentPage === totalPages ? true : undefined}}\" role=\"{{currentPage === totalPages ? 'link' : undefined}}\"><chevronrighticon size=\"{{16}}\" aria-hidden=\"true\" /></paginationlink></paginationitem></paginationcontent></pagination>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "pagination"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "pagination-03",
          "group": "pagination",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "pagination-03",
              "path": "registry/default/components/pagination/pagination-03.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "pagination-03",
              "path": "registry/default/components/pagination/pagination-03.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "pagination-03",
              "path": "registry/default/components/pagination/pagination-03.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "pagination-03",
              "path": "registry/default/components/pagination/pagination-03.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "paginations",
        "title": "Pagination · Go to previous page"
      },
      "categories": [
        "paginations",
        "pagination"
      ],
      "dependencies": [
        "@timui/core",
        "@timui/react"
      ]
    },
    {
      "name": "pagination-04",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/pagination.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/pagination/pagination-04.tsx",
          "type": "registry:component",
          "target": "components/ui/pagination-04.tsx",
          "content": "import { Pagination, PaginationContent, PaginationItem, PaginationLink } from '@timui/react'\nimport { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react'\n\ntype PaginationProps = {\n  currentPage: number\n  totalPages: number\n}\n\nexport default function Component({ currentPage, totalPages }: PaginationProps) {\n  return (\n    <Pagination>\n      <PaginationContent className=\"gap-3\">\n        <PaginationItem>\n          <PaginationLink\n            className=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\"\n            href={currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}\n            aria-label=\"Go to previous page\"\n            aria-disabled={currentPage === 1 ? true : undefined}\n            role={currentPage === 1 ? 'link' : undefined}\n          >\n            <ChevronLeftIcon size={16} aria-hidden=\"true\" />\n          </PaginationLink>\n        </PaginationItem>\n        <PaginationItem>\n          <p className=\"text-muted-foreground text-sm\" aria-live=\"polite\">\n            Page <span className=\"text-foreground\">{currentPage}</span> of{' '}\n            <span className=\"text-foreground\">{totalPages}</span>\n          </p>\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationLink\n            className=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\"\n            href={currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`}\n            aria-label=\"Go to next page\"\n            aria-disabled={currentPage === totalPages ? true : undefined}\n            role={currentPage === totalPages ? 'link' : undefined}\n          >\n            <ChevronRightIcon size={16} aria-hidden=\"true\" />\n          </PaginationLink>\n        </PaginationItem>\n      </PaginationContent>\n    </Pagination>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/pagination/pagination-04.vue",
          "target": "components/ui/pagination-04.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ChevronLeftIcon, ChevronRightIcon } from 'lucide-vue-next';\nimport { Pagination, PaginationContent, PaginationItem, PaginationLink } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Pagination><PaginationContent class=\"gap-3\"><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" :href=\"currentPage === 1 ? undefined : `#/page/${currentPage - 1}`\" aria-label=\"Go to previous page\" :aria-disabled=\"currentPage === 1 ? true : undefined\" :role=\"currentPage === 1 ? 'link' : undefined\"><ChevronLeftIcon :size=\"16\" aria-hidden=\"true\" /></PaginationLink></PaginationItem><PaginationItem><p class=\"text-muted-foreground text-sm\" aria-live=\"polite\">Page <span class=\"text-foreground\">{{ currentPage }}</span>of{{ ' ' }}<span class=\"text-foreground\">{{ totalPages }}</span></p></PaginationItem><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" :href=\"currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`\" aria-label=\"Go to next page\" :aria-disabled=\"currentPage === totalPages ? true : undefined\" :role=\"currentPage === totalPages ? 'link' : undefined\"><ChevronRightIcon :size=\"16\" aria-hidden=\"true\" /></PaginationLink></PaginationItem></PaginationContent></Pagination>\n</template>\n"
        },
        {
          "path": "registry/default/components/pagination/pagination-04.html",
          "target": "components/ui/pagination-04.html",
          "type": "registry:component",
          "content": "<template>\n  <Pagination><PaginationContent class=\"gap-3\"><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"${currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}\" aria-label=\"Go to previous page\" aria-disabled=\"${currentPage === 1 ? true : undefined}\" role=\"${currentPage === 1 ? 'link' : undefined}\"><ChevronLeftIcon size=\"${16}\" aria-hidden=\"true\" /></PaginationLink></PaginationItem><PaginationItem><p class=\"text-muted-foreground text-sm\" aria-live=\"polite\">Page <span class=\"text-foreground\">${currentPage}</span>of${' '}<span class=\"text-foreground\">${totalPages}</span></p></PaginationItem><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"${currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`}\" aria-label=\"Go to next page\" aria-disabled=\"${currentPage === totalPages ? true : undefined}\" role=\"${currentPage === totalPages ? 'link' : undefined}\"><ChevronRightIcon size=\"${16}\" aria-hidden=\"true\" /></PaginationLink></PaginationItem></PaginationContent></Pagination>\n</template>"
        },
        {
          "path": "registry/default/components/pagination/pagination-04.wxml",
          "target": "components/ui/pagination-04/pagination-04.wxml",
          "type": "registry:component",
          "content": "<view>\n  <pagination><paginationcontent class=\"gap-3\"><paginationitem><paginationlink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"{{currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}}\" aria-label=\"Go to previous page\" aria-disabled=\"{{currentPage === 1 ? true : undefined}}\" role=\"{{currentPage === 1 ? 'link' : undefined}}\"><chevronlefticon size=\"{{16}}\" aria-hidden=\"true\" /></paginationlink></paginationitem><paginationitem><text class=\"text-muted-foreground text-sm\" aria-live=\"polite\">Page <text class=\"text-foreground\">{{ currentPage }}</text>of{{ ' ' }}<text class=\"text-foreground\">{{ totalPages }}</text></text></paginationitem><paginationitem><paginationlink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"{{currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`}}\" aria-label=\"Go to next page\" aria-disabled=\"{{currentPage === totalPages ? true : undefined}}\" role=\"{{currentPage === totalPages ? 'link' : undefined}}\"><chevronrighticon size=\"{{16}}\" aria-hidden=\"true\" /></paginationlink></paginationitem></paginationcontent></pagination>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "pagination"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "pagination-04",
          "group": "pagination",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "pagination-04",
              "path": "registry/default/components/pagination/pagination-04.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "pagination-04",
              "path": "registry/default/components/pagination/pagination-04.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "pagination-04",
              "path": "registry/default/components/pagination/pagination-04.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "pagination-04",
              "path": "registry/default/components/pagination/pagination-04.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "paginations",
        "title": "Pagination · Go to previous page"
      },
      "categories": [
        "paginations",
        "pagination"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "pagination-05",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/pagination.json"
      ],
      "files": [
        {
          "path": "registry/default/components/pagination/pagination-05.tsx",
          "type": "registry:component",
          "target": "components/ui/pagination-05.tsx",
          "content": "import { Button, Pagination, PaginationContent, PaginationItem } from '@timui/react'\n\ntype PaginationProps = {\n  currentPage: number\n  totalPages: number\n}\n\nexport default function Component({ currentPage, totalPages }: PaginationProps) {\n  return (\n    <div className=\"flex items-center justify-between gap-3\">\n      <p className=\"text-muted-foreground grow text-sm\" aria-live=\"polite\">\n        Page <span className=\"text-foreground\">{currentPage}</span> of{' '}\n        <span className=\"text-foreground\">{totalPages}</span>\n      </p>\n      <Pagination className=\"w-auto\">\n        <PaginationContent className=\"gap-3\">\n          <PaginationItem>\n            <Button\n              variant=\"outline\"\n              className=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\"\n              aria-disabled={currentPage === 1 ? true : undefined}\n              role={currentPage === 1 ? 'link' : undefined}\n              asChild\n            >\n              <a href={currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}>Previous</a>\n            </Button>\n          </PaginationItem>\n          <PaginationItem>\n            <Button\n              variant=\"outline\"\n              className=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\"\n              aria-disabled={currentPage === totalPages ? true : undefined}\n              role={currentPage === totalPages ? 'link' : undefined}\n              asChild\n            >\n              <a href={currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`}>\n                Next\n              </a>\n            </Button>\n          </PaginationItem>\n        </PaginationContent>\n      </Pagination>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/pagination/pagination-05.vue",
          "target": "components/ui/pagination-05.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\nimport { Pagination, PaginationContent, PaginationItem } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"flex items-center justify-between gap-3\"><p class=\"text-muted-foreground grow text-sm\" aria-live=\"polite\">Page <span class=\"text-foreground\">{{ currentPage }}</span>of{{ ' ' }}<span class=\"text-foreground\">{{ totalPages }}</span></p><Pagination class=\"w-auto\"><PaginationContent class=\"gap-3\"><PaginationItem><Button variant=\"outline\" class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" :aria-disabled=\"currentPage === 1 ? true : undefined\" :role=\"currentPage === 1 ? 'link' : undefined\" as-child><a :href=\"currentPage === 1 ? undefined : `#/page/${currentPage - 1}`\">Previous</a></Button></PaginationItem><PaginationItem><Button variant=\"outline\" class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" :aria-disabled=\"currentPage === totalPages ? true : undefined\" :role=\"currentPage === totalPages ? 'link' : undefined\" as-child><a :href=\"currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`\">Next\n              </a></Button></PaginationItem></PaginationContent></Pagination></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/pagination/pagination-05.html",
          "target": "components/ui/pagination-05.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex items-center justify-between gap-3\"><p class=\"text-muted-foreground grow text-sm\" aria-live=\"polite\">Page <span class=\"text-foreground\">${currentPage}</span>of${' '}<span class=\"text-foreground\">${totalPages}</span></p><Pagination class=\"w-auto\"><PaginationContent class=\"gap-3\"><PaginationItem><Button variant=\"outline\" class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" aria-disabled=\"${currentPage === 1 ? true : undefined}\" role=\"${currentPage === 1 ? 'link' : undefined}\" aschild><a href=\"${currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}\">Previous</a></Button></PaginationItem><PaginationItem><Button variant=\"outline\" class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" aria-disabled=\"${currentPage === totalPages ? true : undefined}\" role=\"${currentPage === totalPages ? 'link' : undefined}\" aschild><a href=\"${currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`}\">Next\n              </a></Button></PaginationItem></PaginationContent></Pagination></div>\n</template>"
        },
        {
          "path": "registry/default/components/pagination/pagination-05.wxml",
          "target": "components/ui/pagination-05/pagination-05.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex items-center justify-between gap-3\"><text class=\"text-muted-foreground grow text-sm\" aria-live=\"polite\">Page <text class=\"text-foreground\">{{ currentPage }}</text>of{{ ' ' }}<text class=\"text-foreground\">{{ totalPages }}</text></text><pagination class=\"w-auto\"><paginationcontent class=\"gap-3\"><paginationitem><button variant=\"outline\" class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" aria-disabled=\"{{currentPage === 1 ? true : undefined}}\" role=\"{{currentPage === 1 ? 'link' : undefined}}\" aschild><a href=\"{{currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}}\">Previous</a></button></paginationitem><paginationitem><button variant=\"outline\" class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" aria-disabled=\"{{currentPage === totalPages ? true : undefined}}\" role=\"{{currentPage === totalPages ? 'link' : undefined}}\" aschild><a href=\"{{currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`}}\">Next\n              </a></button></paginationitem></paginationcontent></pagination></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "pagination"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "pagination-05",
          "group": "pagination",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "pagination-05",
              "path": "registry/default/components/pagination/pagination-05.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "pagination-05",
              "path": "registry/default/components/pagination/pagination-05.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "pagination-05",
              "path": "registry/default/components/pagination/pagination-05.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "pagination-05",
              "path": "registry/default/components/pagination/pagination-05.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "paginations",
        "title": "Pagination · Disabled State"
      },
      "categories": [
        "paginations",
        "pagination"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "pagination-06",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/pagination.json"
      ],
      "files": [
        {
          "path": "registry/default/components/pagination/pagination-06.tsx",
          "type": "registry:component",
          "target": "components/ui/pagination-06.tsx",
          "content": "import {\n  Pagination,\n  PaginationContent,\n  PaginationEllipsis,\n  PaginationItem,\n  PaginationLink,\n  PaginationNext,\n  PaginationPrevious,\n} from '@timui/react'\n\nimport { usePagination } from '@/registry/default/hooks/use-pagination'\n\ntype PaginationProps = {\n  currentPage: number\n  totalPages: number\n  paginationItemsToDisplay?: number\n}\n\nexport default function Component({\n  currentPage,\n  totalPages,\n  paginationItemsToDisplay = 5,\n}: PaginationProps) {\n  const { pages, showLeftEllipsis, showRightEllipsis } = usePagination({\n    currentPage,\n    totalPages,\n    paginationItemsToDisplay,\n  })\n\n  return (\n    <Pagination>\n      <PaginationContent>\n        {/* Previous page button */}\n        <PaginationItem>\n          <PaginationPrevious\n            className=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\"\n            href={currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}\n            aria-disabled={currentPage === 1 ? true : undefined}\n            role={currentPage === 1 ? 'link' : undefined}\n          />\n        </PaginationItem>\n\n        {/* Left ellipsis (...) */}\n        {showLeftEllipsis && (\n          <PaginationItem>\n            <PaginationEllipsis />\n          </PaginationItem>\n        )}\n\n        {/* Page number links */}\n        {pages.map((page) => (\n          <PaginationItem key={page}>\n            <PaginationLink href={`#/page/${page}`} isActive={page === currentPage}>\n              {page}\n            </PaginationLink>\n          </PaginationItem>\n        ))}\n\n        {/* Right ellipsis (...) */}\n        {showRightEllipsis && (\n          <PaginationItem>\n            <PaginationEllipsis />\n          </PaginationItem>\n        )}\n\n        {/* Next page button */}\n        <PaginationItem>\n          <PaginationNext\n            className=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\"\n            href={currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`}\n            aria-disabled={currentPage === totalPages ? true : undefined}\n            role={currentPage === totalPages ? 'link' : undefined}\n          />\n        </PaginationItem>\n      </PaginationContent>\n    </Pagination>\n  )\n}\n"
        },
        {
          "path": "registry/default/hooks/use-pagination.ts",
          "type": "registry:hook",
          "target": "components/ui/pagination-06/use-pagination.ts",
          "content": "type UsePaginationProps = {\n  currentPage: number\n  totalPages: number\n  paginationItemsToDisplay: number\n}\n\ntype UsePaginationReturn = {\n  pages: number[]\n  showLeftEllipsis: boolean\n  showRightEllipsis: boolean\n}\n\nexport function usePagination({\n  currentPage,\n  totalPages,\n  paginationItemsToDisplay,\n}: UsePaginationProps): UsePaginationReturn {\n  const showLeftEllipsis = currentPage - 1 > paginationItemsToDisplay / 2\n  const showRightEllipsis = totalPages - currentPage + 1 > paginationItemsToDisplay / 2\n\n  function calculatePaginationRange(): number[] {\n    if (totalPages <= paginationItemsToDisplay) {\n      return Array.from({ length: totalPages }, (_, i) => i + 1)\n    }\n\n    const halfDisplay = Math.floor(paginationItemsToDisplay / 2)\n    const initialRange = {\n      start: currentPage - halfDisplay,\n      end: currentPage + halfDisplay,\n    }\n\n    const adjustedRange = {\n      start: Math.max(1, initialRange.start),\n      end: Math.min(totalPages, initialRange.end),\n    }\n\n    if (adjustedRange.start === 1) {\n      adjustedRange.end = paginationItemsToDisplay\n    }\n    if (adjustedRange.end === totalPages) {\n      adjustedRange.start = totalPages - paginationItemsToDisplay + 1\n    }\n\n    if (showLeftEllipsis) adjustedRange.start++\n    if (showRightEllipsis) adjustedRange.end--\n\n    return Array.from(\n      { length: adjustedRange.end - adjustedRange.start + 1 },\n      (_, i) => adjustedRange.start + i\n    )\n  }\n\n  const pages = calculatePaginationRange()\n\n  return {\n    pages,\n    showLeftEllipsis,\n    showRightEllipsis,\n  }\n}\n"
        },
        {
          "path": "registry/default/components/pagination/pagination-06.vue",
          "target": "components/ui/pagination-06.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious } from '@timui/vue';\nimport { usePagination } from '@/registry/default/hooks/use-pagination';\n\nconst currentPage = 1;\nconst totalPages = 10;\nconst paginationItemsToDisplay = 5;\nconst { pages, showLeftEllipsis, showRightEllipsis } = usePagination({\n  currentPage,\n  totalPages,\n  paginationItemsToDisplay,\n});\n</script>\n\n<template>\n  <Pagination><PaginationContent><PaginationItem><PaginationPrevious class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" :href=\"currentPage === 1 ? undefined : `#/page/${currentPage - 1}`\" :aria-disabled=\"currentPage === 1 ? true : undefined\" :role=\"currentPage === 1 ? 'link' : undefined\" /></PaginationItem><PaginationItem v-if=\"showLeftEllipsis\"><PaginationEllipsis /></PaginationItem><PaginationItem v-for=\"(page, index) in pages\" :key=\"page\"><PaginationLink :href=\"`#/page/${page}`\" :isActive=\"page === currentPage\">{{ page }}</PaginationLink></PaginationItem><PaginationItem v-if=\"showRightEllipsis\"><PaginationEllipsis /></PaginationItem><PaginationItem><PaginationNext class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" :href=\"currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`\" :aria-disabled=\"currentPage === totalPages ? true : undefined\" :role=\"currentPage === totalPages ? 'link' : undefined\" /></PaginationItem></PaginationContent></Pagination>\n</template>\n"
        },
        {
          "path": "registry/default/components/pagination/pagination-06.html",
          "target": "components/ui/pagination-06.html",
          "type": "registry:component",
          "content": "<template>\n  <Pagination><PaginationContent><PaginationItem><PaginationPrevious class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"${currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}\" aria-disabled=\"${currentPage === 1 ? true : undefined}\" role=\"${currentPage === 1 ? 'link' : undefined}\" /></PaginationItem><!-- if showLeftEllipsis -->\n<PaginationItem><PaginationEllipsis /></PaginationItem>\n<!-- endif --><!-- Loop pages -->\n<PaginationItem key=\"${page}\"><PaginationLink href=\"${`#/page/${page}`}\" isactive=\"${page === currentPage}\">${page}</PaginationLink></PaginationItem>\n<!-- End Loop --><!-- if showRightEllipsis -->\n<PaginationItem><PaginationEllipsis /></PaginationItem>\n<!-- endif --><PaginationItem><PaginationNext class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"${currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`}\" aria-disabled=\"${currentPage === totalPages ? true : undefined}\" role=\"${currentPage === totalPages ? 'link' : undefined}\" /></PaginationItem></PaginationContent></Pagination>\n</template>"
        },
        {
          "path": "registry/default/components/pagination/pagination-06.wxml",
          "target": "components/ui/pagination-06/pagination-06.wxml",
          "type": "registry:component",
          "content": "<view>\n  <pagination><paginationcontent><paginationitem><paginationprevious class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"{{currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}}\" aria-disabled=\"{{currentPage === 1 ? true : undefined}}\" role=\"{{currentPage === 1 ? 'link' : undefined}}\" /></paginationitem><paginationitem wx:if=\"{{showLeftEllipsis}}\"><paginationellipsis /></paginationitem><paginationitem wx:for=\"{{pages}}\" wx:for-item=\"page\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{page}}\"><paginationlink href=\"{{`#/page/${page}`}}\" isactive=\"{{page === currentPage}}\">{{ page }}</paginationlink></paginationitem><paginationitem wx:if=\"{{showRightEllipsis}}\"><paginationellipsis /></paginationitem><paginationitem><paginationnext class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"{{currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`}}\" aria-disabled=\"{{currentPage === totalPages ? true : undefined}}\" role=\"{{currentPage === totalPages ? 'link' : undefined}}\" /></paginationitem></paginationcontent></pagination>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "pagination"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "pagination-06",
          "group": "pagination",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "pagination-06",
              "path": "registry/default/components/pagination/pagination-06.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "pagination-06",
              "path": "registry/default/components/pagination/pagination-06.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "pagination-06",
              "path": "registry/default/components/pagination/pagination-06.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "pagination-06",
              "path": "registry/default/components/pagination/pagination-06.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "paginations",
        "title": "Pagination · Disabled State"
      },
      "categories": [
        "paginations",
        "pagination"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "pagination-07",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/pagination.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/pagination/pagination-07.tsx",
          "type": "registry:component",
          "target": "components/ui/pagination-07.tsx",
          "content": "import {\n  Pagination,\n  PaginationContent,\n  PaginationEllipsis,\n  PaginationItem,\n  PaginationLink,\n} from '@timui/react'\nimport { ChevronFirstIcon, ChevronLastIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react'\n\nimport { usePagination } from '@/registry/default/hooks/use-pagination'\n\ntype PaginationProps = {\n  currentPage: number\n  totalPages: number\n  paginationItemsToDisplay?: number\n}\n\nexport default function Component({\n  currentPage,\n  totalPages,\n  paginationItemsToDisplay = 5,\n}: PaginationProps) {\n  const { pages, showLeftEllipsis, showRightEllipsis } = usePagination({\n    currentPage,\n    totalPages,\n    paginationItemsToDisplay,\n  })\n\n  return (\n    <Pagination>\n      <PaginationContent>\n        {/* First page button */}\n        <PaginationItem>\n          <PaginationLink\n            className=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\"\n            href={currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}\n            aria-label=\"Go to first page\"\n            aria-disabled={currentPage === 1 ? true : undefined}\n            role={currentPage === 1 ? 'link' : undefined}\n          >\n            <ChevronFirstIcon size={16} aria-hidden=\"true\" />\n          </PaginationLink>\n        </PaginationItem>\n\n        {/* Previous page button */}\n        <PaginationItem>\n          <PaginationLink\n            className=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\"\n            href={currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}\n            aria-label=\"Go to previous page\"\n            aria-disabled={currentPage === 1 ? true : undefined}\n            role={currentPage === 1 ? 'link' : undefined}\n          >\n            <ChevronLeftIcon size={16} aria-hidden=\"true\" />\n          </PaginationLink>\n        </PaginationItem>\n\n        {/* Left ellipsis (...) */}\n        {showLeftEllipsis && (\n          <PaginationItem>\n            <PaginationEllipsis />\n          </PaginationItem>\n        )}\n\n        {/* Page number links */}\n        {pages.map((page) => (\n          <PaginationItem key={page}>\n            <PaginationLink href={`#/page/${page}`} isActive={page === currentPage}>\n              {page}\n            </PaginationLink>\n          </PaginationItem>\n        ))}\n\n        {/* Right ellipsis (...) */}\n        {showRightEllipsis && (\n          <PaginationItem>\n            <PaginationEllipsis />\n          </PaginationItem>\n        )}\n\n        {/* Next page button */}\n        <PaginationItem>\n          <PaginationLink\n            className=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\"\n            href={currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`}\n            aria-label=\"Go to next page\"\n            aria-disabled={currentPage === totalPages ? true : undefined}\n            role={currentPage === totalPages ? 'link' : undefined}\n          >\n            <ChevronRightIcon size={16} aria-hidden=\"true\" />\n          </PaginationLink>\n        </PaginationItem>\n\n        {/* Last page button */}\n        <PaginationItem>\n          <PaginationLink\n            className=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\"\n            href={currentPage === totalPages ? undefined : `#/page/${totalPages}`}\n            aria-label=\"Go to last page\"\n            aria-disabled={currentPage === totalPages ? true : undefined}\n            role={currentPage === totalPages ? 'link' : undefined}\n          >\n            <ChevronLastIcon size={16} aria-hidden=\"true\" />\n          </PaginationLink>\n        </PaginationItem>\n      </PaginationContent>\n    </Pagination>\n  )\n}\n"
        },
        {
          "path": "registry/default/hooks/use-pagination.ts",
          "type": "registry:hook",
          "target": "components/ui/pagination-07/use-pagination.ts",
          "content": "type UsePaginationProps = {\n  currentPage: number\n  totalPages: number\n  paginationItemsToDisplay: number\n}\n\ntype UsePaginationReturn = {\n  pages: number[]\n  showLeftEllipsis: boolean\n  showRightEllipsis: boolean\n}\n\nexport function usePagination({\n  currentPage,\n  totalPages,\n  paginationItemsToDisplay,\n}: UsePaginationProps): UsePaginationReturn {\n  const showLeftEllipsis = currentPage - 1 > paginationItemsToDisplay / 2\n  const showRightEllipsis = totalPages - currentPage + 1 > paginationItemsToDisplay / 2\n\n  function calculatePaginationRange(): number[] {\n    if (totalPages <= paginationItemsToDisplay) {\n      return Array.from({ length: totalPages }, (_, i) => i + 1)\n    }\n\n    const halfDisplay = Math.floor(paginationItemsToDisplay / 2)\n    const initialRange = {\n      start: currentPage - halfDisplay,\n      end: currentPage + halfDisplay,\n    }\n\n    const adjustedRange = {\n      start: Math.max(1, initialRange.start),\n      end: Math.min(totalPages, initialRange.end),\n    }\n\n    if (adjustedRange.start === 1) {\n      adjustedRange.end = paginationItemsToDisplay\n    }\n    if (adjustedRange.end === totalPages) {\n      adjustedRange.start = totalPages - paginationItemsToDisplay + 1\n    }\n\n    if (showLeftEllipsis) adjustedRange.start++\n    if (showRightEllipsis) adjustedRange.end--\n\n    return Array.from(\n      { length: adjustedRange.end - adjustedRange.start + 1 },\n      (_, i) => adjustedRange.start + i\n    )\n  }\n\n  const pages = calculatePaginationRange()\n\n  return {\n    pages,\n    showLeftEllipsis,\n    showRightEllipsis,\n  }\n}\n"
        },
        {
          "path": "registry/default/components/pagination/pagination-07.vue",
          "target": "components/ui/pagination-07.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ChevronFirstIcon, ChevronLastIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-vue-next';\nimport { Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink } from '@timui/vue';\nimport { usePagination } from '@/registry/default/hooks/use-pagination';\n\nconst currentPage = 1;\nconst totalPages = 10;\nconst paginationItemsToDisplay = 5;\nconst { pages, showLeftEllipsis, showRightEllipsis } = usePagination({\n  currentPage,\n  totalPages,\n  paginationItemsToDisplay,\n});\n</script>\n\n<template>\n  <Pagination><PaginationContent><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" :href=\"currentPage === 1 ? undefined : `#/page/${currentPage - 1}`\" aria-label=\"Go to first page\" :aria-disabled=\"currentPage === 1 ? true : undefined\" :role=\"currentPage === 1 ? 'link' : undefined\"><ChevronFirstIcon :size=\"16\" aria-hidden=\"true\" /></PaginationLink></PaginationItem><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" :href=\"currentPage === 1 ? undefined : `#/page/${currentPage - 1}`\" aria-label=\"Go to previous page\" :aria-disabled=\"currentPage === 1 ? true : undefined\" :role=\"currentPage === 1 ? 'link' : undefined\"><ChevronLeftIcon :size=\"16\" aria-hidden=\"true\" /></PaginationLink></PaginationItem><PaginationItem v-if=\"showLeftEllipsis\"><PaginationEllipsis /></PaginationItem><PaginationItem v-for=\"(page, index) in pages\" :key=\"page\"><PaginationLink :href=\"`#/page/${page}`\" :isActive=\"page === currentPage\">{{ page }}</PaginationLink></PaginationItem><PaginationItem v-if=\"showRightEllipsis\"><PaginationEllipsis /></PaginationItem><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" :href=\"currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`\" aria-label=\"Go to next page\" :aria-disabled=\"currentPage === totalPages ? true : undefined\" :role=\"currentPage === totalPages ? 'link' : undefined\"><ChevronRightIcon :size=\"16\" aria-hidden=\"true\" /></PaginationLink></PaginationItem><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" :href=\"currentPage === totalPages ? undefined : `#/page/${totalPages}`\" aria-label=\"Go to last page\" :aria-disabled=\"currentPage === totalPages ? true : undefined\" :role=\"currentPage === totalPages ? 'link' : undefined\"><ChevronLastIcon :size=\"16\" aria-hidden=\"true\" /></PaginationLink></PaginationItem></PaginationContent></Pagination>\n</template>\n"
        },
        {
          "path": "registry/default/components/pagination/pagination-07.html",
          "target": "components/ui/pagination-07.html",
          "type": "registry:component",
          "content": "<template>\n  <Pagination><PaginationContent><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"${currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}\" aria-label=\"Go to first page\" aria-disabled=\"${currentPage === 1 ? true : undefined}\" role=\"${currentPage === 1 ? 'link' : undefined}\"><ChevronFirstIcon size=\"${16}\" aria-hidden=\"true\" /></PaginationLink></PaginationItem><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"${currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}\" aria-label=\"Go to previous page\" aria-disabled=\"${currentPage === 1 ? true : undefined}\" role=\"${currentPage === 1 ? 'link' : undefined}\"><ChevronLeftIcon size=\"${16}\" aria-hidden=\"true\" /></PaginationLink></PaginationItem><!-- if showLeftEllipsis -->\n<PaginationItem><PaginationEllipsis /></PaginationItem>\n<!-- endif --><!-- Loop pages -->\n<PaginationItem key=\"${page}\"><PaginationLink href=\"${`#/page/${page}`}\" isactive=\"${page === currentPage}\">${page}</PaginationLink></PaginationItem>\n<!-- End Loop --><!-- if showRightEllipsis -->\n<PaginationItem><PaginationEllipsis /></PaginationItem>\n<!-- endif --><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"${currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`}\" aria-label=\"Go to next page\" aria-disabled=\"${currentPage === totalPages ? true : undefined}\" role=\"${currentPage === totalPages ? 'link' : undefined}\"><ChevronRightIcon size=\"${16}\" aria-hidden=\"true\" /></PaginationLink></PaginationItem><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"${currentPage === totalPages ? undefined : `#/page/${totalPages}`}\" aria-label=\"Go to last page\" aria-disabled=\"${currentPage === totalPages ? true : undefined}\" role=\"${currentPage === totalPages ? 'link' : undefined}\"><ChevronLastIcon size=\"${16}\" aria-hidden=\"true\" /></PaginationLink></PaginationItem></PaginationContent></Pagination>\n</template>"
        },
        {
          "path": "registry/default/components/pagination/pagination-07.wxml",
          "target": "components/ui/pagination-07/pagination-07.wxml",
          "type": "registry:component",
          "content": "<view>\n  <pagination><paginationcontent><paginationitem><paginationlink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"{{currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}}\" aria-label=\"Go to first page\" aria-disabled=\"{{currentPage === 1 ? true : undefined}}\" role=\"{{currentPage === 1 ? 'link' : undefined}}\"><chevronfirsticon size=\"{{16}}\" aria-hidden=\"true\" /></paginationlink></paginationitem><paginationitem><paginationlink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"{{currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}}\" aria-label=\"Go to previous page\" aria-disabled=\"{{currentPage === 1 ? true : undefined}}\" role=\"{{currentPage === 1 ? 'link' : undefined}}\"><chevronlefticon size=\"{{16}}\" aria-hidden=\"true\" /></paginationlink></paginationitem><paginationitem wx:if=\"{{showLeftEllipsis}}\"><paginationellipsis /></paginationitem><paginationitem wx:for=\"{{pages}}\" wx:for-item=\"page\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{page}}\"><paginationlink href=\"{{`#/page/${page}`}}\" isactive=\"{{page === currentPage}}\">{{ page }}</paginationlink></paginationitem><paginationitem wx:if=\"{{showRightEllipsis}}\"><paginationellipsis /></paginationitem><paginationitem><paginationlink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"{{currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`}}\" aria-label=\"Go to next page\" aria-disabled=\"{{currentPage === totalPages ? true : undefined}}\" role=\"{{currentPage === totalPages ? 'link' : undefined}}\"><chevronrighticon size=\"{{16}}\" aria-hidden=\"true\" /></paginationlink></paginationitem><paginationitem><paginationlink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"{{currentPage === totalPages ? undefined : `#/page/${totalPages}`}}\" aria-label=\"Go to last page\" aria-disabled=\"{{currentPage === totalPages ? true : undefined}}\" role=\"{{currentPage === totalPages ? 'link' : undefined}}\"><chevronlasticon size=\"{{16}}\" aria-hidden=\"true\" /></paginationlink></paginationitem></paginationcontent></pagination>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "pagination"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "pagination-07",
          "group": "pagination",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "pagination-07",
              "path": "registry/default/components/pagination/pagination-07.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "pagination-07",
              "path": "registry/default/components/pagination/pagination-07.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "pagination-07",
              "path": "registry/default/components/pagination/pagination-07.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "pagination-07",
              "path": "registry/default/components/pagination/pagination-07.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "paginations",
        "title": "Pagination · Go to first page"
      },
      "categories": [
        "paginations",
        "pagination"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "pagination-08",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/pagination.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/pagination/pagination-08.tsx",
          "type": "registry:component",
          "target": "components/ui/pagination-08.tsx",
          "content": "import { cn } from '@timui/core'\nimport {\n  buttonVariants,\n  Pagination,\n  PaginationContent,\n  PaginationEllipsis,\n  PaginationItem,\n  PaginationLink,\n} from '@timui/react'\nimport { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react'\n\nimport { usePagination } from '@/registry/default/hooks/use-pagination'\n\ntype PaginationProps = {\n  currentPage: number\n  totalPages: number\n  paginationItemsToDisplay?: number\n}\n\nexport default function Component({\n  currentPage,\n  totalPages,\n  paginationItemsToDisplay = 5,\n}: PaginationProps) {\n  const { pages, showLeftEllipsis, showRightEllipsis } = usePagination({\n    currentPage,\n    totalPages,\n    paginationItemsToDisplay,\n  })\n\n  return (\n    <Pagination>\n      <PaginationContent className=\"inline-flex gap-0 -space-x-px rounded-md shadow-xs rtl:space-x-reverse\">\n        {/* Previous page button */}\n        <PaginationItem className=\"[&:first-child>a]:rounded-s-md [&:last-child>a]:rounded-e-md\">\n          <PaginationLink\n            className={cn(\n              buttonVariants({\n                variant: 'outline',\n              }),\n              'rounded-none shadow-none focus-visible:z-10 aria-disabled:pointer-events-none [&[aria-disabled]>svg]:opacity-50'\n            )}\n            href={currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}\n            aria-label=\"Go to previous page\"\n            aria-disabled={currentPage === 1 ? true : undefined}\n            role={currentPage === 1 ? 'link' : undefined}\n          >\n            <ChevronLeftIcon size={16} aria-hidden=\"true\" />\n          </PaginationLink>\n        </PaginationItem>\n\n        {/* Left ellipsis (...) */}\n        {showLeftEllipsis && (\n          <PaginationItem className=\"[&:first-child>a]:rounded-s-md [&:last-child>a]:rounded-e-md\">\n            <PaginationEllipsis />\n          </PaginationItem>\n        )}\n\n        {/* Page number links */}\n        {pages.map((page) => (\n          <PaginationItem key={page}>\n            <PaginationLink\n              className={cn(\n                buttonVariants({\n                  variant: 'outline',\n                }),\n                'rounded-none shadow-none focus-visible:z-10',\n                page === currentPage && 'bg-accent'\n              )}\n              href={`#/page/${page}`}\n              isActive={page === currentPage}\n            >\n              {page}\n            </PaginationLink>\n          </PaginationItem>\n        ))}\n\n        {/* Right ellipsis (...) */}\n        {showRightEllipsis && (\n          <PaginationItem className=\"[&:first-child>a]:rounded-s-md [&:last-child>a]:rounded-e-md\">\n            <PaginationEllipsis\n              className={cn(\n                buttonVariants({\n                  variant: 'outline',\n                }),\n                'pointer-events-none rounded-none shadow-none'\n              )}\n            />\n          </PaginationItem>\n        )}\n\n        {/* Next page button */}\n        <PaginationItem className=\"[&:first-child>a]:rounded-s-md [&:last-child>a]:rounded-e-md\">\n          <PaginationLink\n            className={cn(\n              buttonVariants({\n                variant: 'outline',\n              }),\n              'rounded-none shadow-none focus-visible:z-10 aria-disabled:pointer-events-none [&[aria-disabled]>svg]:opacity-50'\n            )}\n            href={currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`}\n            aria-label=\"Go to next page\"\n            aria-disabled={currentPage === totalPages ? true : undefined}\n            role={currentPage === totalPages ? 'link' : undefined}\n          >\n            <ChevronRightIcon size={16} aria-hidden=\"true\" />\n          </PaginationLink>\n        </PaginationItem>\n      </PaginationContent>\n    </Pagination>\n  )\n}\n"
        },
        {
          "path": "registry/default/hooks/use-pagination.ts",
          "type": "registry:hook",
          "target": "components/ui/pagination-08/use-pagination.ts",
          "content": "type UsePaginationProps = {\n  currentPage: number\n  totalPages: number\n  paginationItemsToDisplay: number\n}\n\ntype UsePaginationReturn = {\n  pages: number[]\n  showLeftEllipsis: boolean\n  showRightEllipsis: boolean\n}\n\nexport function usePagination({\n  currentPage,\n  totalPages,\n  paginationItemsToDisplay,\n}: UsePaginationProps): UsePaginationReturn {\n  const showLeftEllipsis = currentPage - 1 > paginationItemsToDisplay / 2\n  const showRightEllipsis = totalPages - currentPage + 1 > paginationItemsToDisplay / 2\n\n  function calculatePaginationRange(): number[] {\n    if (totalPages <= paginationItemsToDisplay) {\n      return Array.from({ length: totalPages }, (_, i) => i + 1)\n    }\n\n    const halfDisplay = Math.floor(paginationItemsToDisplay / 2)\n    const initialRange = {\n      start: currentPage - halfDisplay,\n      end: currentPage + halfDisplay,\n    }\n\n    const adjustedRange = {\n      start: Math.max(1, initialRange.start),\n      end: Math.min(totalPages, initialRange.end),\n    }\n\n    if (adjustedRange.start === 1) {\n      adjustedRange.end = paginationItemsToDisplay\n    }\n    if (adjustedRange.end === totalPages) {\n      adjustedRange.start = totalPages - paginationItemsToDisplay + 1\n    }\n\n    if (showLeftEllipsis) adjustedRange.start++\n    if (showRightEllipsis) adjustedRange.end--\n\n    return Array.from(\n      { length: adjustedRange.end - adjustedRange.start + 1 },\n      (_, i) => adjustedRange.start + i\n    )\n  }\n\n  const pages = calculatePaginationRange()\n\n  return {\n    pages,\n    showLeftEllipsis,\n    showRightEllipsis,\n  }\n}\n"
        },
        {
          "path": "registry/default/components/pagination/pagination-08.vue",
          "target": "components/ui/pagination-08.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn } from '@timui/core';\nimport { ChevronLeftIcon, ChevronRightIcon } from 'lucide-vue-next';\nimport { buttonVariants } from '@timui/vue';\nimport { Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink } from '@timui/vue';\nimport { usePagination } from '@/registry/default/hooks/use-pagination';\n\nconst currentPage = 1;\nconst totalPages = 10;\nconst paginationItemsToDisplay = 5;\nconst { pages, showLeftEllipsis, showRightEllipsis } = usePagination({\n  currentPage,\n  totalPages,\n  paginationItemsToDisplay,\n});\n</script>\n\n<template>\n  <Pagination><PaginationContent class=\"inline-flex gap-0 -space-x-px rounded-md shadow-xs rtl:space-x-reverse\"><PaginationItem class=\"[&:first-child>a]:rounded-s-md [&:last-child>a]:rounded-e-md\"><PaginationLink :class=\"cn(\n              buttonVariants({\n                variant: 'outline',\n              }),\n              'rounded-none shadow-none focus-visible:z-10 aria-disabled:pointer-events-none [&[aria-disabled]>svg]:opacity-50'\n            )\" :href=\"currentPage === 1 ? undefined : `#/page/${currentPage - 1}`\" aria-label=\"Go to previous page\" :aria-disabled=\"currentPage === 1 ? true : undefined\" :role=\"currentPage === 1 ? 'link' : undefined\"><ChevronLeftIcon :size=\"16\" aria-hidden=\"true\" /></PaginationLink></PaginationItem><PaginationItem v-if=\"showLeftEllipsis\" class=\"[&:first-child>a]:rounded-s-md [&:last-child>a]:rounded-e-md\"><PaginationEllipsis /></PaginationItem><PaginationItem v-for=\"(page, index) in pages\" :key=\"page\"><PaginationLink :class=\"cn(\n                buttonVariants({\n                  variant: 'outline',\n                }),\n                'rounded-none shadow-none focus-visible:z-10',\n                page === currentPage && 'bg-accent'\n              )\" :href=\"`#/page/${page}`\" :isActive=\"page === currentPage\">{{ page }}</PaginationLink></PaginationItem><PaginationItem v-if=\"showRightEllipsis\" class=\"[&:first-child>a]:rounded-s-md [&:last-child>a]:rounded-e-md\"><PaginationEllipsis :class=\"cn(\n                buttonVariants({\n                  variant: 'outline',\n                }),\n                'pointer-events-none rounded-none shadow-none'\n              )\" /></PaginationItem><PaginationItem class=\"[&:first-child>a]:rounded-s-md [&:last-child>a]:rounded-e-md\"><PaginationLink :class=\"cn(\n              buttonVariants({\n                variant: 'outline',\n              }),\n              'rounded-none shadow-none focus-visible:z-10 aria-disabled:pointer-events-none [&[aria-disabled]>svg]:opacity-50'\n            )\" :href=\"currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`\" aria-label=\"Go to next page\" :aria-disabled=\"currentPage === totalPages ? true : undefined\" :role=\"currentPage === totalPages ? 'link' : undefined\"><ChevronRightIcon :size=\"16\" aria-hidden=\"true\" /></PaginationLink></PaginationItem></PaginationContent></Pagination>\n</template>\n"
        },
        {
          "path": "registry/default/components/pagination/pagination-08.html",
          "target": "components/ui/pagination-08.html",
          "type": "registry:component",
          "content": "<template>\n  <Pagination><PaginationContent class=\"inline-flex gap-0 -space-x-px rounded-md shadow-xs rtl:space-x-reverse\"><PaginationItem class=\"[&:first-child>a]:rounded-s-md [&:last-child>a]:rounded-e-md\"><PaginationLink class=\"${cn(\n              buttonVariants({\n                variant: 'outline',\n              }),\n              'rounded-none shadow-none focus-visible:z-10 aria-disabled:pointer-events-none [&[aria-disabled]>svg]:opacity-50'\n            )}\" href=\"${currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}\" aria-label=\"Go to previous page\" aria-disabled=\"${currentPage === 1 ? true : undefined}\" role=\"${currentPage === 1 ? 'link' : undefined}\"><ChevronLeftIcon size=\"${16}\" aria-hidden=\"true\" /></PaginationLink></PaginationItem><!-- if showLeftEllipsis -->\n<PaginationItem class=\"[&:first-child>a]:rounded-s-md [&:last-child>a]:rounded-e-md\"><PaginationEllipsis /></PaginationItem>\n<!-- endif --><!-- Loop pages -->\n<PaginationItem key=\"${page}\"><PaginationLink class=\"${cn(\n                buttonVariants({\n                  variant: 'outline',\n                }),\n                'rounded-none shadow-none focus-visible:z-10',\n                page === currentPage && 'bg-accent'\n              )}\" href=\"${`#/page/${page}`}\" isactive=\"${page === currentPage}\">${page}</PaginationLink></PaginationItem>\n<!-- End Loop --><!-- if showRightEllipsis -->\n<PaginationItem class=\"[&:first-child>a]:rounded-s-md [&:last-child>a]:rounded-e-md\"><PaginationEllipsis class=\"${cn(\n                buttonVariants({\n                  variant: 'outline',\n                }),\n                'pointer-events-none rounded-none shadow-none'\n              )}\" /></PaginationItem>\n<!-- endif --><PaginationItem class=\"[&:first-child>a]:rounded-s-md [&:last-child>a]:rounded-e-md\"><PaginationLink class=\"${cn(\n              buttonVariants({\n                variant: 'outline',\n              }),\n              'rounded-none shadow-none focus-visible:z-10 aria-disabled:pointer-events-none [&[aria-disabled]>svg]:opacity-50'\n            )}\" href=\"${currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`}\" aria-label=\"Go to next page\" aria-disabled=\"${currentPage === totalPages ? true : undefined}\" role=\"${currentPage === totalPages ? 'link' : undefined}\"><ChevronRightIcon size=\"${16}\" aria-hidden=\"true\" /></PaginationLink></PaginationItem></PaginationContent></Pagination>\n</template>"
        },
        {
          "path": "registry/default/components/pagination/pagination-08.wxml",
          "target": "components/ui/pagination-08/pagination-08.wxml",
          "type": "registry:component",
          "content": "<view>\n  <pagination><paginationcontent class=\"inline-flex gap-0 -space-x-px rounded-md shadow-xs rtl:space-x-reverse\"><paginationitem class=\"[&:first-child>a]:rounded-s-md [&:last-child>a]:rounded-e-md\"><paginationlink class=\"{{cn(\n              buttonVariants({\n                variant: 'outline',\n              }),\n              'rounded-none shadow-none focus-visible:z-10 aria-disabled:pointer-events-none [&[aria-disabled]>svg]:opacity-50'\n            )}}\" href=\"{{currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}}\" aria-label=\"Go to previous page\" aria-disabled=\"{{currentPage === 1 ? true : undefined}}\" role=\"{{currentPage === 1 ? 'link' : undefined}}\"><chevronlefticon size=\"{{16}}\" aria-hidden=\"true\" /></paginationlink></paginationitem><paginationitem wx:if=\"{{showLeftEllipsis}}\" class=\"[&:first-child>a]:rounded-s-md [&:last-child>a]:rounded-e-md\"><paginationellipsis /></paginationitem><paginationitem wx:for=\"{{pages}}\" wx:for-item=\"page\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{page}}\"><paginationlink class=\"{{cn(\n                buttonVariants({\n                  variant: 'outline',\n                }),\n                'rounded-none shadow-none focus-visible:z-10',\n                page === currentPage && 'bg-accent'\n              )}}\" href=\"{{`#/page/${page}`}}\" isactive=\"{{page === currentPage}}\">{{ page }}</paginationlink></paginationitem><paginationitem wx:if=\"{{showRightEllipsis}}\" class=\"[&:first-child>a]:rounded-s-md [&:last-child>a]:rounded-e-md\"><paginationellipsis class=\"{{cn(\n                buttonVariants({\n                  variant: 'outline',\n                }),\n                'pointer-events-none rounded-none shadow-none'\n              )}}\" /></paginationitem><paginationitem class=\"[&:first-child>a]:rounded-s-md [&:last-child>a]:rounded-e-md\"><paginationlink class=\"{{cn(\n              buttonVariants({\n                variant: 'outline',\n              }),\n              'rounded-none shadow-none focus-visible:z-10 aria-disabled:pointer-events-none [&[aria-disabled]>svg]:opacity-50'\n            )}}\" href=\"{{currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`}}\" aria-label=\"Go to next page\" aria-disabled=\"{{currentPage === totalPages ? true : undefined}}\" role=\"{{currentPage === totalPages ? 'link' : undefined}}\"><chevronrighticon size=\"{{16}}\" aria-hidden=\"true\" /></paginationlink></paginationitem></paginationcontent></pagination>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "pagination"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "pagination-08",
          "group": "pagination",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "pagination-08",
              "path": "registry/default/components/pagination/pagination-08.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "pagination-08",
              "path": "registry/default/components/pagination/pagination-08.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "pagination-08",
              "path": "registry/default/components/pagination/pagination-08.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "pagination-08",
              "path": "registry/default/components/pagination/pagination-08.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "paginations",
        "title": "Pagination · Go to previous page"
      },
      "categories": [
        "paginations",
        "pagination"
      ],
      "dependencies": [
        "@timui/core",
        "@timui/react"
      ]
    },
    {
      "name": "pagination-09",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/pagination.json",
        "https://ui.timkit.cn/r/select.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/pagination/pagination-09.tsx",
          "type": "registry:component",
          "target": "components/ui/pagination-09.tsx",
          "content": "import {\n  Pagination,\n  PaginationContent,\n  PaginationEllipsis,\n  PaginationItem,\n  PaginationLink,\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from '@timui/react'\nimport { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react'\n\nimport { usePagination } from '@/registry/default/hooks/use-pagination'\n\ntype PaginationProps = {\n  currentPage: number\n  totalPages: number\n  paginationItemsToDisplay?: number\n}\n\nexport default function Component({\n  currentPage,\n  totalPages,\n  paginationItemsToDisplay = 5,\n}: PaginationProps) {\n  const { pages, showLeftEllipsis, showRightEllipsis } = usePagination({\n    currentPage,\n    totalPages,\n    paginationItemsToDisplay,\n  })\n\n  return (\n    <div className=\"flex items-center justify-between gap-3\">\n      {/* Page number information */}\n      <p className=\"text-muted-foreground flex-1 text-sm whitespace-nowrap\" aria-live=\"polite\">\n        Page <span className=\"text-foreground\">{currentPage}</span> of{' '}\n        <span className=\"text-foreground\">{totalPages}</span>\n      </p>\n\n      {/* Pagination */}\n      <div className=\"grow\">\n        <Pagination>\n          <PaginationContent>\n            {/* Previous page button */}\n            <PaginationItem>\n              <PaginationLink\n                className=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\"\n                href={currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}\n                aria-label=\"Go to previous page\"\n                aria-disabled={currentPage === 1 ? true : undefined}\n                role={currentPage === 1 ? 'link' : undefined}\n              >\n                <ChevronLeftIcon size={16} aria-hidden=\"true\" />\n              </PaginationLink>\n            </PaginationItem>\n\n            {/* Left ellipsis (...) */}\n            {showLeftEllipsis && (\n              <PaginationItem>\n                <PaginationEllipsis />\n              </PaginationItem>\n            )}\n\n            {/* Page number links */}\n            {pages.map((page) => (\n              <PaginationItem key={page}>\n                <PaginationLink href={`#/page/${page}`} isActive={page === currentPage}>\n                  {page}\n                </PaginationLink>\n              </PaginationItem>\n            ))}\n\n            {/* Right ellipsis (...) */}\n            {showRightEllipsis && (\n              <PaginationItem>\n                <PaginationEllipsis />\n              </PaginationItem>\n            )}\n\n            {/* Next page button */}\n            <PaginationItem>\n              <PaginationLink\n                className=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\"\n                href={currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`}\n                aria-label=\"Go to next page\"\n                aria-disabled={currentPage === totalPages ? true : undefined}\n                role={currentPage === totalPages ? 'link' : undefined}\n              >\n                <ChevronRightIcon size={16} aria-hidden=\"true\" />\n              </PaginationLink>\n            </PaginationItem>\n          </PaginationContent>\n        </Pagination>\n      </div>\n\n      {/* Results per page */}\n      <div className=\"flex flex-1 justify-end\">\n        <Select defaultValue=\"10\" aria-label=\"Results per page\">\n          <SelectTrigger id=\"results-per-page\" className=\"w-fit whitespace-nowrap\">\n            <SelectValue placeholder=\"Select number of results\" />\n          </SelectTrigger>\n          <SelectContent>\n            <SelectItem value=\"10\">10 / page</SelectItem>\n            <SelectItem value=\"20\">20 / page</SelectItem>\n            <SelectItem value=\"50\">50 / page</SelectItem>\n            <SelectItem value=\"100\">100 / page</SelectItem>\n          </SelectContent>\n        </Select>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/hooks/use-pagination.ts",
          "type": "registry:hook",
          "target": "components/ui/pagination-09/use-pagination.ts",
          "content": "type UsePaginationProps = {\n  currentPage: number\n  totalPages: number\n  paginationItemsToDisplay: number\n}\n\ntype UsePaginationReturn = {\n  pages: number[]\n  showLeftEllipsis: boolean\n  showRightEllipsis: boolean\n}\n\nexport function usePagination({\n  currentPage,\n  totalPages,\n  paginationItemsToDisplay,\n}: UsePaginationProps): UsePaginationReturn {\n  const showLeftEllipsis = currentPage - 1 > paginationItemsToDisplay / 2\n  const showRightEllipsis = totalPages - currentPage + 1 > paginationItemsToDisplay / 2\n\n  function calculatePaginationRange(): number[] {\n    if (totalPages <= paginationItemsToDisplay) {\n      return Array.from({ length: totalPages }, (_, i) => i + 1)\n    }\n\n    const halfDisplay = Math.floor(paginationItemsToDisplay / 2)\n    const initialRange = {\n      start: currentPage - halfDisplay,\n      end: currentPage + halfDisplay,\n    }\n\n    const adjustedRange = {\n      start: Math.max(1, initialRange.start),\n      end: Math.min(totalPages, initialRange.end),\n    }\n\n    if (adjustedRange.start === 1) {\n      adjustedRange.end = paginationItemsToDisplay\n    }\n    if (adjustedRange.end === totalPages) {\n      adjustedRange.start = totalPages - paginationItemsToDisplay + 1\n    }\n\n    if (showLeftEllipsis) adjustedRange.start++\n    if (showRightEllipsis) adjustedRange.end--\n\n    return Array.from(\n      { length: adjustedRange.end - adjustedRange.start + 1 },\n      (_, i) => adjustedRange.start + i\n    )\n  }\n\n  const pages = calculatePaginationRange()\n\n  return {\n    pages,\n    showLeftEllipsis,\n    showRightEllipsis,\n  }\n}\n"
        },
        {
          "path": "registry/default/components/pagination/pagination-09.vue",
          "target": "components/ui/pagination-09.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ChevronLeftIcon, ChevronRightIcon } from 'lucide-vue-next';\nimport { Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink } from '@timui/vue';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/vue';\nimport { usePagination } from '@/registry/default/hooks/use-pagination';\n\nconst currentPage = 1;\nconst totalPages = 10;\nconst paginationItemsToDisplay = 5;\nconst { pages, showLeftEllipsis, showRightEllipsis } = usePagination({\n  currentPage,\n  totalPages,\n  paginationItemsToDisplay,\n});\n</script>\n\n<template>\n  <div class=\"flex items-center justify-between gap-3\"><p class=\"text-muted-foreground flex-1 text-sm whitespace-nowrap\" aria-live=\"polite\">Page <span class=\"text-foreground\">{{ currentPage }}</span>of{{ ' ' }}<span class=\"text-foreground\">{{ totalPages }}</span></p><div class=\"grow\"><Pagination><PaginationContent><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" :href=\"currentPage === 1 ? undefined : `#/page/${currentPage - 1}`\" aria-label=\"Go to previous page\" :aria-disabled=\"currentPage === 1 ? true : undefined\" :role=\"currentPage === 1 ? 'link' : undefined\"><ChevronLeftIcon :size=\"16\" aria-hidden=\"true\" /></PaginationLink></PaginationItem><PaginationItem v-if=\"showLeftEllipsis\"><PaginationEllipsis /></PaginationItem><PaginationItem v-for=\"(page, index) in pages\" :key=\"page\"><PaginationLink :href=\"`#/page/${page}`\" :isActive=\"page === currentPage\">{{ page }}</PaginationLink></PaginationItem><PaginationItem v-if=\"showRightEllipsis\"><PaginationEllipsis /></PaginationItem><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" :href=\"currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`\" aria-label=\"Go to next page\" :aria-disabled=\"currentPage === totalPages ? true : undefined\" :role=\"currentPage === totalPages ? 'link' : undefined\"><ChevronRightIcon :size=\"16\" aria-hidden=\"true\" /></PaginationLink></PaginationItem></PaginationContent></Pagination></div><div class=\"flex flex-1 justify-end\"><Select default-value=\"10\" aria-label=\"Results per page\"><SelectTrigger id=\"results-per-page\" class=\"w-fit whitespace-nowrap\"><SelectValue placeholder=\"Select number of results\" /></SelectTrigger><SelectContent><SelectItem value=\"10\">10 / page</SelectItem><SelectItem value=\"20\">20 / page</SelectItem><SelectItem value=\"50\">50 / page</SelectItem><SelectItem value=\"100\">100 / page</SelectItem></SelectContent></Select></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/pagination/pagination-09.html",
          "target": "components/ui/pagination-09.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex items-center justify-between gap-3\"><p class=\"text-muted-foreground flex-1 text-sm whitespace-nowrap\" aria-live=\"polite\">Page <span class=\"text-foreground\">${currentPage}</span>of${' '}<span class=\"text-foreground\">${totalPages}</span></p><div class=\"grow\"><Pagination><PaginationContent><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"${currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}\" aria-label=\"Go to previous page\" aria-disabled=\"${currentPage === 1 ? true : undefined}\" role=\"${currentPage === 1 ? 'link' : undefined}\"><ChevronLeftIcon size=\"${16}\" aria-hidden=\"true\" /></PaginationLink></PaginationItem><!-- if showLeftEllipsis -->\n<PaginationItem><PaginationEllipsis /></PaginationItem>\n<!-- endif --><!-- Loop pages -->\n<PaginationItem key=\"${page}\"><PaginationLink href=\"${`#/page/${page}`}\" isactive=\"${page === currentPage}\">${page}</PaginationLink></PaginationItem>\n<!-- End Loop --><!-- if showRightEllipsis -->\n<PaginationItem><PaginationEllipsis /></PaginationItem>\n<!-- endif --><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"${currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`}\" aria-label=\"Go to next page\" aria-disabled=\"${currentPage === totalPages ? true : undefined}\" role=\"${currentPage === totalPages ? 'link' : undefined}\"><ChevronRightIcon size=\"${16}\" aria-hidden=\"true\" /></PaginationLink></PaginationItem></PaginationContent></Pagination></div><div class=\"flex flex-1 justify-end\"><Select default-value=\"10\" aria-label=\"Results per page\"><SelectTrigger id=\"results-per-page\" class=\"w-fit whitespace-nowrap\"><SelectValue placeholder=\"Select number of results\" /></SelectTrigger><SelectContent><SelectItem value=\"10\">10 / page</SelectItem><SelectItem value=\"20\">20 / page</SelectItem><SelectItem value=\"50\">50 / page</SelectItem><SelectItem value=\"100\">100 / page</SelectItem></SelectContent></Select></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/pagination/pagination-09.wxml",
          "target": "components/ui/pagination-09/pagination-09.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex items-center justify-between gap-3\"><text class=\"text-muted-foreground flex-1 text-sm whitespace-nowrap\" aria-live=\"polite\">Page <text class=\"text-foreground\">{{ currentPage }}</text>of{{ ' ' }}<text class=\"text-foreground\">{{ totalPages }}</text></text><view class=\"grow\"><pagination><paginationcontent><paginationitem><paginationlink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"{{currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}}\" aria-label=\"Go to previous page\" aria-disabled=\"{{currentPage === 1 ? true : undefined}}\" role=\"{{currentPage === 1 ? 'link' : undefined}}\"><chevronlefticon size=\"{{16}}\" aria-hidden=\"true\" /></paginationlink></paginationitem><paginationitem wx:if=\"{{showLeftEllipsis}}\"><paginationellipsis /></paginationitem><paginationitem wx:for=\"{{pages}}\" wx:for-item=\"page\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{page}}\"><paginationlink href=\"{{`#/page/${page}`}}\" isactive=\"{{page === currentPage}}\">{{ page }}</paginationlink></paginationitem><paginationitem wx:if=\"{{showRightEllipsis}}\"><paginationellipsis /></paginationitem><paginationitem><paginationlink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"{{currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`}}\" aria-label=\"Go to next page\" aria-disabled=\"{{currentPage === totalPages ? true : undefined}}\" role=\"{{currentPage === totalPages ? 'link' : undefined}}\"><chevronrighticon size=\"{{16}}\" aria-hidden=\"true\" /></paginationlink></paginationitem></paginationcontent></pagination></view><view class=\"flex flex-1 justify-end\"><select default-value=\"10\" aria-label=\"Results per page\"><selecttrigger id=\"results-per-page\" class=\"w-fit whitespace-nowrap\"><selectvalue placeholder=\"Select number of results\" /></selecttrigger><selectcontent><selectitem value=\"10\">10 / page</selectitem><selectitem value=\"20\">20 / page</selectitem><selectitem value=\"50\">50 / page</selectitem><selectitem value=\"100\">100 / page</selectitem></selectcontent></select></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "pagination"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "pagination-09",
          "group": "pagination",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "pagination-09",
              "path": "registry/default/components/pagination/pagination-09.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "pagination-09",
              "path": "registry/default/components/pagination/pagination-09.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "pagination-09",
              "path": "registry/default/components/pagination/pagination-09.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "pagination-09",
              "path": "registry/default/components/pagination/pagination-09.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "paginations",
        "title": "Pagination · Go to previous page"
      },
      "categories": [
        "paginations",
        "pagination"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "pagination-10",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/pagination.json",
        "https://ui.timkit.cn/r/select.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/pagination/pagination-10.tsx",
          "type": "registry:component",
          "target": "components/ui/pagination-10.tsx",
          "content": "import { useId } from 'react'\nimport {\n  Label,\n  Pagination,\n  PaginationContent,\n  PaginationItem,\n  PaginationLink,\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from '@timui/react'\nimport { ChevronFirstIcon, ChevronLastIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react'\n\ntype PaginationProps = {\n  currentPage: number\n  totalPages: number\n}\n\nexport default function Component({ currentPage, totalPages }: PaginationProps) {\n  const id = useId()\n  return (\n    <div className=\"flex items-center justify-between gap-8\">\n      {/* Results per page */}\n      <div className=\"flex items-center gap-3\">\n        <Label htmlFor={id}>Rows per page</Label>\n        <Select defaultValue=\"25\">\n          <SelectTrigger id={id} className=\"w-fit whitespace-nowrap\">\n            <SelectValue placeholder=\"Select number of results\" />\n          </SelectTrigger>\n          <SelectContent className=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\">\n            <SelectItem value=\"10\">10</SelectItem>\n            <SelectItem value=\"25\">25</SelectItem>\n            <SelectItem value=\"50\">50</SelectItem>\n            <SelectItem value=\"100\">100</SelectItem>\n          </SelectContent>\n        </Select>\n      </div>\n\n      {/* Page number information */}\n      <div className=\"text-muted-foreground flex grow justify-end text-sm whitespace-nowrap\">\n        <p className=\"text-muted-foreground text-sm whitespace-nowrap\" aria-live=\"polite\">\n          <span className=\"text-foreground\">1-25</span> of{' '}\n          <span className=\"text-foreground\">100</span>\n        </p>\n      </div>\n\n      {/* Pagination */}\n      <div>\n        <Pagination>\n          <PaginationContent>\n            {/* First page button */}\n            <PaginationItem>\n              <PaginationLink\n                className=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\"\n                href={currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}\n                aria-label=\"Go to first page\"\n                aria-disabled={currentPage === 1 ? true : undefined}\n                role={currentPage === 1 ? 'link' : undefined}\n              >\n                <ChevronFirstIcon size={16} aria-hidden=\"true\" />\n              </PaginationLink>\n            </PaginationItem>\n\n            {/* Previous page button */}\n            <PaginationItem>\n              <PaginationLink\n                className=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\"\n                href={currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}\n                aria-label=\"Go to previous page\"\n                aria-disabled={currentPage === 1 ? true : undefined}\n                role={currentPage === 1 ? 'link' : undefined}\n              >\n                <ChevronLeftIcon size={16} aria-hidden=\"true\" />\n              </PaginationLink>\n            </PaginationItem>\n\n            {/* Next page button */}\n            <PaginationItem>\n              <PaginationLink\n                className=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\"\n                href={currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`}\n                aria-label=\"Go to next page\"\n                aria-disabled={currentPage === totalPages ? true : undefined}\n                role={currentPage === totalPages ? 'link' : undefined}\n              >\n                <ChevronRightIcon size={16} aria-hidden=\"true\" />\n              </PaginationLink>\n            </PaginationItem>\n\n            {/* Last page button */}\n            <PaginationItem>\n              <PaginationLink\n                className=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\"\n                href={currentPage === totalPages ? undefined : `#/page/${totalPages}`}\n                aria-label=\"Go to last page\"\n                aria-disabled={currentPage === totalPages ? true : undefined}\n                role={currentPage === totalPages ? 'link' : undefined}\n              >\n                <ChevronLastIcon size={16} aria-hidden=\"true\" />\n              </PaginationLink>\n            </PaginationItem>\n          </PaginationContent>\n        </Pagination>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/hooks/use-pagination.ts",
          "type": "registry:hook",
          "target": "components/ui/pagination-10/use-pagination.ts",
          "content": "type UsePaginationProps = {\n  currentPage: number\n  totalPages: number\n  paginationItemsToDisplay: number\n}\n\ntype UsePaginationReturn = {\n  pages: number[]\n  showLeftEllipsis: boolean\n  showRightEllipsis: boolean\n}\n\nexport function usePagination({\n  currentPage,\n  totalPages,\n  paginationItemsToDisplay,\n}: UsePaginationProps): UsePaginationReturn {\n  const showLeftEllipsis = currentPage - 1 > paginationItemsToDisplay / 2\n  const showRightEllipsis = totalPages - currentPage + 1 > paginationItemsToDisplay / 2\n\n  function calculatePaginationRange(): number[] {\n    if (totalPages <= paginationItemsToDisplay) {\n      return Array.from({ length: totalPages }, (_, i) => i + 1)\n    }\n\n    const halfDisplay = Math.floor(paginationItemsToDisplay / 2)\n    const initialRange = {\n      start: currentPage - halfDisplay,\n      end: currentPage + halfDisplay,\n    }\n\n    const adjustedRange = {\n      start: Math.max(1, initialRange.start),\n      end: Math.min(totalPages, initialRange.end),\n    }\n\n    if (adjustedRange.start === 1) {\n      adjustedRange.end = paginationItemsToDisplay\n    }\n    if (adjustedRange.end === totalPages) {\n      adjustedRange.start = totalPages - paginationItemsToDisplay + 1\n    }\n\n    if (showLeftEllipsis) adjustedRange.start++\n    if (showRightEllipsis) adjustedRange.end--\n\n    return Array.from(\n      { length: adjustedRange.end - adjustedRange.start + 1 },\n      (_, i) => adjustedRange.start + i\n    )\n  }\n\n  const pages = calculatePaginationRange()\n\n  return {\n    pages,\n    showLeftEllipsis,\n    showRightEllipsis,\n  }\n}\n"
        },
        {
          "path": "registry/default/components/pagination/pagination-10.vue",
          "target": "components/ui/pagination-10.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ChevronFirstIcon, ChevronLastIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-vue-next';\nimport { Label } from '@timui/vue';\nimport { Pagination, PaginationContent, PaginationItem, PaginationLink } from '@timui/vue';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/vue';\n\n\n\n\n\nconst id = 'pagination-10';\n\n</script>\n\n<template>\n  <div class=\"flex items-center justify-between gap-8\"><div class=\"flex items-center gap-3\"><Label :htmlFor=\"id\">Rows per page</Label><Select default-value=\"25\"><SelectTrigger :id=\"id\" class=\"w-fit whitespace-nowrap\"><SelectValue placeholder=\"Select number of results\" /></SelectTrigger><SelectContent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\"><SelectItem value=\"10\">10</SelectItem><SelectItem value=\"25\">25</SelectItem><SelectItem value=\"50\">50</SelectItem><SelectItem value=\"100\">100</SelectItem></SelectContent></Select></div><div class=\"text-muted-foreground flex grow justify-end text-sm whitespace-nowrap\"><p class=\"text-muted-foreground text-sm whitespace-nowrap\" aria-live=\"polite\"><span class=\"text-foreground\">1-25</span>of{{ ' ' }}<span class=\"text-foreground\">100</span></p></div><div><Pagination><PaginationContent><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" :href=\"currentPage === 1 ? undefined : `#/page/${currentPage - 1}`\" aria-label=\"Go to first page\" :aria-disabled=\"currentPage === 1 ? true : undefined\" :role=\"currentPage === 1 ? 'link' : undefined\"><ChevronFirstIcon :size=\"16\" aria-hidden=\"true\" /></PaginationLink></PaginationItem><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" :href=\"currentPage === 1 ? undefined : `#/page/${currentPage - 1}`\" aria-label=\"Go to previous page\" :aria-disabled=\"currentPage === 1 ? true : undefined\" :role=\"currentPage === 1 ? 'link' : undefined\"><ChevronLeftIcon :size=\"16\" aria-hidden=\"true\" /></PaginationLink></PaginationItem><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" :href=\"currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`\" aria-label=\"Go to next page\" :aria-disabled=\"currentPage === totalPages ? true : undefined\" :role=\"currentPage === totalPages ? 'link' : undefined\"><ChevronRightIcon :size=\"16\" aria-hidden=\"true\" /></PaginationLink></PaginationItem><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" :href=\"currentPage === totalPages ? undefined : `#/page/${totalPages}`\" aria-label=\"Go to last page\" :aria-disabled=\"currentPage === totalPages ? true : undefined\" :role=\"currentPage === totalPages ? 'link' : undefined\"><ChevronLastIcon :size=\"16\" aria-hidden=\"true\" /></PaginationLink></PaginationItem></PaginationContent></Pagination></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/pagination/pagination-10.html",
          "target": "components/ui/pagination-10.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex items-center justify-between gap-8\"><div class=\"flex items-center gap-3\"><Label htmlfor=\"${id}\">Rows per page</Label><Select default-value=\"25\"><SelectTrigger id=\"${id}\" class=\"w-fit whitespace-nowrap\"><SelectValue placeholder=\"Select number of results\" /></SelectTrigger><SelectContent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\"><SelectItem value=\"10\">10</SelectItem><SelectItem value=\"25\">25</SelectItem><SelectItem value=\"50\">50</SelectItem><SelectItem value=\"100\">100</SelectItem></SelectContent></Select></div><div class=\"text-muted-foreground flex grow justify-end text-sm whitespace-nowrap\"><p class=\"text-muted-foreground text-sm whitespace-nowrap\" aria-live=\"polite\"><span class=\"text-foreground\">1-25</span>of${' '}<span class=\"text-foreground\">100</span></p></div><div><Pagination><PaginationContent><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"${currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}\" aria-label=\"Go to first page\" aria-disabled=\"${currentPage === 1 ? true : undefined}\" role=\"${currentPage === 1 ? 'link' : undefined}\"><ChevronFirstIcon size=\"${16}\" aria-hidden=\"true\" /></PaginationLink></PaginationItem><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"${currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}\" aria-label=\"Go to previous page\" aria-disabled=\"${currentPage === 1 ? true : undefined}\" role=\"${currentPage === 1 ? 'link' : undefined}\"><ChevronLeftIcon size=\"${16}\" aria-hidden=\"true\" /></PaginationLink></PaginationItem><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"${currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`}\" aria-label=\"Go to next page\" aria-disabled=\"${currentPage === totalPages ? true : undefined}\" role=\"${currentPage === totalPages ? 'link' : undefined}\"><ChevronRightIcon size=\"${16}\" aria-hidden=\"true\" /></PaginationLink></PaginationItem><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"${currentPage === totalPages ? undefined : `#/page/${totalPages}`}\" aria-label=\"Go to last page\" aria-disabled=\"${currentPage === totalPages ? true : undefined}\" role=\"${currentPage === totalPages ? 'link' : undefined}\"><ChevronLastIcon size=\"${16}\" aria-hidden=\"true\" /></PaginationLink></PaginationItem></PaginationContent></Pagination></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/pagination/pagination-10.wxml",
          "target": "components/ui/pagination-10/pagination-10.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex items-center justify-between gap-8\"><view class=\"flex items-center gap-3\"><label htmlfor=\"{{id}}\">Rows per page</label><select default-value=\"25\"><selecttrigger id=\"{{id}}\" class=\"w-fit whitespace-nowrap\"><selectvalue placeholder=\"Select number of results\" /></selecttrigger><selectcontent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\"><selectitem value=\"10\">10</selectitem><selectitem value=\"25\">25</selectitem><selectitem value=\"50\">50</selectitem><selectitem value=\"100\">100</selectitem></selectcontent></select></view><view class=\"text-muted-foreground flex grow justify-end text-sm whitespace-nowrap\"><text class=\"text-muted-foreground text-sm whitespace-nowrap\" aria-live=\"polite\"><text class=\"text-foreground\">1-25</text>of{{ ' ' }}<text class=\"text-foreground\">100</text></text></view><view><pagination><paginationcontent><paginationitem><paginationlink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"{{currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}}\" aria-label=\"Go to first page\" aria-disabled=\"{{currentPage === 1 ? true : undefined}}\" role=\"{{currentPage === 1 ? 'link' : undefined}}\"><chevronfirsticon size=\"{{16}}\" aria-hidden=\"true\" /></paginationlink></paginationitem><paginationitem><paginationlink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"{{currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}}\" aria-label=\"Go to previous page\" aria-disabled=\"{{currentPage === 1 ? true : undefined}}\" role=\"{{currentPage === 1 ? 'link' : undefined}}\"><chevronlefticon size=\"{{16}}\" aria-hidden=\"true\" /></paginationlink></paginationitem><paginationitem><paginationlink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"{{currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`}}\" aria-label=\"Go to next page\" aria-disabled=\"{{currentPage === totalPages ? true : undefined}}\" role=\"{{currentPage === totalPages ? 'link' : undefined}}\"><chevronrighticon size=\"{{16}}\" aria-hidden=\"true\" /></paginationlink></paginationitem><paginationitem><paginationlink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"{{currentPage === totalPages ? undefined : `#/page/${totalPages}`}}\" aria-label=\"Go to last page\" aria-disabled=\"{{currentPage === totalPages ? true : undefined}}\" role=\"{{currentPage === totalPages ? 'link' : undefined}}\"><chevronlasticon size=\"{{16}}\" aria-hidden=\"true\" /></paginationlink></paginationitem></paginationcontent></pagination></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "pagination",
          "select",
          "radix"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "pagination-10",
          "group": "pagination",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "pagination-10",
              "path": "registry/default/components/pagination/pagination-10.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "pagination-10",
              "path": "registry/default/components/pagination/pagination-10.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "pagination-10",
              "path": "registry/default/components/pagination/pagination-10.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "pagination-10",
              "path": "registry/default/components/pagination/pagination-10.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "paginations",
        "title": "Pagination · Rows per page"
      },
      "categories": [
        "paginations",
        "pagination"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "pagination-11",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/pagination.json",
        "https://ui.timkit.cn/r/select.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/pagination/pagination-11.tsx",
          "type": "registry:component",
          "target": "components/ui/pagination-11.tsx",
          "content": "import {\n  Pagination,\n  PaginationContent,\n  PaginationItem,\n  PaginationLink,\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from '@timui/react'\nimport { ChevronFirstIcon, ChevronLastIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react'\n\ntype PaginationProps = {\n  currentPage: number\n  totalPages: number\n  paginationItemsToDisplay?: number\n}\n\nexport default function Component({ currentPage, totalPages }: PaginationProps) {\n  return (\n    <Pagination>\n      <PaginationContent>\n        {/* First page button */}\n        <PaginationItem>\n          <PaginationLink\n            className=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\"\n            href={currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}\n            aria-label=\"Go to first page\"\n            aria-disabled={currentPage === 1 ? true : undefined}\n            role={currentPage === 1 ? 'link' : undefined}\n          >\n            <ChevronFirstIcon size={16} aria-hidden=\"true\" />\n          </PaginationLink>\n        </PaginationItem>\n\n        {/* Previous page button */}\n        <PaginationItem>\n          <PaginationLink\n            className=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\"\n            href={currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}\n            aria-label=\"Go to previous page\"\n            aria-disabled={currentPage === 1 ? true : undefined}\n            role={currentPage === 1 ? 'link' : undefined}\n          >\n            <ChevronLeftIcon size={16} aria-hidden=\"true\" />\n          </PaginationLink>\n        </PaginationItem>\n\n        {/* Page number select */}\n        <PaginationItem>\n          <Select defaultValue={String(currentPage)} aria-label=\"Select page\">\n            <SelectTrigger id=\"select-page\" className=\"w-fit whitespace-nowrap\">\n              <SelectValue placeholder=\"Select page\" />\n            </SelectTrigger>\n            <SelectContent>\n              {Array.from({ length: totalPages }, (_, i) => i + 1).map((page) => (\n                <SelectItem key={page} value={String(page)}>\n                  Page {page}\n                </SelectItem>\n              ))}\n            </SelectContent>\n          </Select>\n        </PaginationItem>\n\n        {/* Next page button */}\n        <PaginationItem>\n          <PaginationLink\n            className=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\"\n            href={currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`}\n            aria-label=\"Go to next page\"\n            aria-disabled={currentPage === totalPages ? true : undefined}\n            role={currentPage === totalPages ? 'link' : undefined}\n          >\n            <ChevronRightIcon size={16} aria-hidden=\"true\" />\n          </PaginationLink>\n        </PaginationItem>\n\n        {/* Last page button */}\n        <PaginationItem>\n          <PaginationLink\n            className=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\"\n            href={currentPage === totalPages ? undefined : `#/page/${totalPages}`}\n            aria-label=\"Go to last page\"\n            aria-disabled={currentPage === totalPages ? true : undefined}\n            role={currentPage === totalPages ? 'link' : undefined}\n          >\n            <ChevronLastIcon size={16} aria-hidden=\"true\" />\n          </PaginationLink>\n        </PaginationItem>\n      </PaginationContent>\n    </Pagination>\n  )\n}\n"
        },
        {
          "path": "registry/default/hooks/use-pagination.ts",
          "type": "registry:hook",
          "target": "components/ui/pagination-11/use-pagination.ts",
          "content": "type UsePaginationProps = {\n  currentPage: number\n  totalPages: number\n  paginationItemsToDisplay: number\n}\n\ntype UsePaginationReturn = {\n  pages: number[]\n  showLeftEllipsis: boolean\n  showRightEllipsis: boolean\n}\n\nexport function usePagination({\n  currentPage,\n  totalPages,\n  paginationItemsToDisplay,\n}: UsePaginationProps): UsePaginationReturn {\n  const showLeftEllipsis = currentPage - 1 > paginationItemsToDisplay / 2\n  const showRightEllipsis = totalPages - currentPage + 1 > paginationItemsToDisplay / 2\n\n  function calculatePaginationRange(): number[] {\n    if (totalPages <= paginationItemsToDisplay) {\n      return Array.from({ length: totalPages }, (_, i) => i + 1)\n    }\n\n    const halfDisplay = Math.floor(paginationItemsToDisplay / 2)\n    const initialRange = {\n      start: currentPage - halfDisplay,\n      end: currentPage + halfDisplay,\n    }\n\n    const adjustedRange = {\n      start: Math.max(1, initialRange.start),\n      end: Math.min(totalPages, initialRange.end),\n    }\n\n    if (adjustedRange.start === 1) {\n      adjustedRange.end = paginationItemsToDisplay\n    }\n    if (adjustedRange.end === totalPages) {\n      adjustedRange.start = totalPages - paginationItemsToDisplay + 1\n    }\n\n    if (showLeftEllipsis) adjustedRange.start++\n    if (showRightEllipsis) adjustedRange.end--\n\n    return Array.from(\n      { length: adjustedRange.end - adjustedRange.start + 1 },\n      (_, i) => adjustedRange.start + i\n    )\n  }\n\n  const pages = calculatePaginationRange()\n\n  return {\n    pages,\n    showLeftEllipsis,\n    showRightEllipsis,\n  }\n}\n"
        },
        {
          "path": "registry/default/components/pagination/pagination-11.vue",
          "target": "components/ui/pagination-11.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ChevronFirstIcon, ChevronLastIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-vue-next';\nimport { Pagination, PaginationContent, PaginationItem, PaginationLink } from '@timui/vue';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <Pagination><PaginationContent><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" :href=\"currentPage === 1 ? undefined : `#/page/${currentPage - 1}`\" aria-label=\"Go to first page\" :aria-disabled=\"currentPage === 1 ? true : undefined\" :role=\"currentPage === 1 ? 'link' : undefined\"><ChevronFirstIcon :size=\"16\" aria-hidden=\"true\" /></PaginationLink></PaginationItem><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" :href=\"currentPage === 1 ? undefined : `#/page/${currentPage - 1}`\" aria-label=\"Go to previous page\" :aria-disabled=\"currentPage === 1 ? true : undefined\" :role=\"currentPage === 1 ? 'link' : undefined\"><ChevronLeftIcon :size=\"16\" aria-hidden=\"true\" /></PaginationLink></PaginationItem><PaginationItem><Select :default-value=\"String(currentPage)\" aria-label=\"Select page\"><SelectTrigger id=\"select-page\" class=\"w-fit whitespace-nowrap\"><SelectValue placeholder=\"Select page\" /></SelectTrigger><SelectContent><SelectItem v-for=\"(page, index) in Array.from({ length: totalPages }, (_, i) => i + 1)\" :key=\"page\" :value=\"String(page)\">Page {{ page }}</SelectItem></SelectContent></Select></PaginationItem><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" :href=\"currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`\" aria-label=\"Go to next page\" :aria-disabled=\"currentPage === totalPages ? true : undefined\" :role=\"currentPage === totalPages ? 'link' : undefined\"><ChevronRightIcon :size=\"16\" aria-hidden=\"true\" /></PaginationLink></PaginationItem><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" :href=\"currentPage === totalPages ? undefined : `#/page/${totalPages}`\" aria-label=\"Go to last page\" :aria-disabled=\"currentPage === totalPages ? true : undefined\" :role=\"currentPage === totalPages ? 'link' : undefined\"><ChevronLastIcon :size=\"16\" aria-hidden=\"true\" /></PaginationLink></PaginationItem></PaginationContent></Pagination>\n</template>\n"
        },
        {
          "path": "registry/default/components/pagination/pagination-11.html",
          "target": "components/ui/pagination-11.html",
          "type": "registry:component",
          "content": "<template>\n  <Pagination><PaginationContent><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"${currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}\" aria-label=\"Go to first page\" aria-disabled=\"${currentPage === 1 ? true : undefined}\" role=\"${currentPage === 1 ? 'link' : undefined}\"><ChevronFirstIcon size=\"${16}\" aria-hidden=\"true\" /></PaginationLink></PaginationItem><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"${currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}\" aria-label=\"Go to previous page\" aria-disabled=\"${currentPage === 1 ? true : undefined}\" role=\"${currentPage === 1 ? 'link' : undefined}\"><ChevronLeftIcon size=\"${16}\" aria-hidden=\"true\" /></PaginationLink></PaginationItem><PaginationItem><Select default-value=\"${String(currentPage)}\" aria-label=\"Select page\"><SelectTrigger id=\"select-page\" class=\"w-fit whitespace-nowrap\"><SelectValue placeholder=\"Select page\" /></SelectTrigger><SelectContent><!-- Loop Array.from({ length: totalPages }, (_, i) => i + 1) -->\n<SelectItem key=\"${page}\" value=\"${String(page)}\">Page ${page}</SelectItem>\n<!-- End Loop --></SelectContent></Select></PaginationItem><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"${currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`}\" aria-label=\"Go to next page\" aria-disabled=\"${currentPage === totalPages ? true : undefined}\" role=\"${currentPage === totalPages ? 'link' : undefined}\"><ChevronRightIcon size=\"${16}\" aria-hidden=\"true\" /></PaginationLink></PaginationItem><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"${currentPage === totalPages ? undefined : `#/page/${totalPages}`}\" aria-label=\"Go to last page\" aria-disabled=\"${currentPage === totalPages ? true : undefined}\" role=\"${currentPage === totalPages ? 'link' : undefined}\"><ChevronLastIcon size=\"${16}\" aria-hidden=\"true\" /></PaginationLink></PaginationItem></PaginationContent></Pagination>\n</template>"
        },
        {
          "path": "registry/default/components/pagination/pagination-11.wxml",
          "target": "components/ui/pagination-11/pagination-11.wxml",
          "type": "registry:component",
          "content": "<view>\n  <pagination><paginationcontent><paginationitem><paginationlink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"{{currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}}\" aria-label=\"Go to first page\" aria-disabled=\"{{currentPage === 1 ? true : undefined}}\" role=\"{{currentPage === 1 ? 'link' : undefined}}\"><chevronfirsticon size=\"{{16}}\" aria-hidden=\"true\" /></paginationlink></paginationitem><paginationitem><paginationlink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"{{currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}}\" aria-label=\"Go to previous page\" aria-disabled=\"{{currentPage === 1 ? true : undefined}}\" role=\"{{currentPage === 1 ? 'link' : undefined}}\"><chevronlefticon size=\"{{16}}\" aria-hidden=\"true\" /></paginationlink></paginationitem><paginationitem><select default-value=\"{{String(currentPage)}}\" aria-label=\"Select page\"><selecttrigger id=\"select-page\" class=\"w-fit whitespace-nowrap\"><selectvalue placeholder=\"Select page\" /></selecttrigger><selectcontent><selectitem wx:for=\"{{Array.from({ length: totalPages }, (_, i) => i + 1)}}\" wx:for-item=\"page\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{page}}\" value=\"{{String(page)}}\">Page {{ page }}</selectitem></selectcontent></select></paginationitem><paginationitem><paginationlink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"{{currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`}}\" aria-label=\"Go to next page\" aria-disabled=\"{{currentPage === totalPages ? true : undefined}}\" role=\"{{currentPage === totalPages ? 'link' : undefined}}\"><chevronrighticon size=\"{{16}}\" aria-hidden=\"true\" /></paginationlink></paginationitem><paginationitem><paginationlink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"{{currentPage === totalPages ? undefined : `#/page/${totalPages}`}}\" aria-label=\"Go to last page\" aria-disabled=\"{{currentPage === totalPages ? true : undefined}}\" role=\"{{currentPage === totalPages ? 'link' : undefined}}\"><chevronlasticon size=\"{{16}}\" aria-hidden=\"true\" /></paginationlink></paginationitem></paginationcontent></pagination>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "pagination",
          "select",
          "radix"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "pagination-11",
          "group": "pagination",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "pagination-11",
              "path": "registry/default/components/pagination/pagination-11.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "pagination-11",
              "path": "registry/default/components/pagination/pagination-11.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "pagination-11",
              "path": "registry/default/components/pagination/pagination-11.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "pagination-11",
              "path": "registry/default/components/pagination/pagination-11.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "paginations",
        "title": "Pagination · Go to first page"
      },
      "categories": [
        "paginations",
        "pagination"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "pagination-12",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/pagination.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/pagination/pagination-12.tsx",
          "type": "registry:component",
          "target": "components/ui/pagination-12.tsx",
          "content": "import { useId } from 'react'\nimport {\n  Input,\n  Label,\n  Pagination,\n  PaginationContent,\n  PaginationEllipsis,\n  PaginationItem,\n  PaginationLink,\n} from '@timui/react'\nimport { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react'\n\nimport { usePagination } from '@/registry/default/hooks/use-pagination'\n\ntype PaginationProps = {\n  currentPage: number\n  totalPages: number\n  paginationItemsToDisplay?: number\n}\n\nexport default function Component({\n  currentPage,\n  totalPages,\n  paginationItemsToDisplay = 5,\n}: PaginationProps) {\n  const id = useId()\n\n  const { pages, showLeftEllipsis, showRightEllipsis } = usePagination({\n    currentPage,\n    totalPages,\n    paginationItemsToDisplay,\n  })\n\n  return (\n    <div className=\"flex items-center justify-between gap-4\">\n      {/* Pagination */}\n      <div>\n        <Pagination>\n          <PaginationContent>\n            {/* Previous page button */}\n            <PaginationItem>\n              <PaginationLink\n                className=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\"\n                href={currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}\n                aria-label=\"Go to previous page\"\n                aria-disabled={currentPage === 1 ? true : undefined}\n                role={currentPage === 1 ? 'link' : undefined}\n              >\n                <ChevronLeftIcon size={16} aria-hidden=\"true\" />\n              </PaginationLink>\n            </PaginationItem>\n\n            {/* Left ellipsis (...) */}\n            {showLeftEllipsis && (\n              <PaginationItem>\n                <PaginationEllipsis />\n              </PaginationItem>\n            )}\n\n            {/* Page number links */}\n            {pages.map((page) => (\n              <PaginationItem key={page}>\n                <PaginationLink href={`#/page/${page}`} isActive={page === currentPage}>\n                  {page}\n                </PaginationLink>\n              </PaginationItem>\n            ))}\n\n            {/* Right ellipsis (...) */}\n            {showRightEllipsis && (\n              <PaginationItem>\n                <PaginationEllipsis />\n              </PaginationItem>\n            )}\n\n            {/* Next page button */}\n            <PaginationItem>\n              <PaginationLink\n                className=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\"\n                href={currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`}\n                aria-label=\"Go to next page\"\n                aria-disabled={currentPage === totalPages ? true : undefined}\n                role={currentPage === totalPages ? 'link' : undefined}\n              >\n                <ChevronRightIcon size={16} aria-hidden=\"true\" />\n              </PaginationLink>\n            </PaginationItem>\n          </PaginationContent>\n        </Pagination>\n      </div>\n\n      {/* Go to page input */}\n      <div className=\"flex items-center gap-3\">\n        <Label htmlFor={id} className=\"whitespace-nowrap\">\n          Go to page\n        </Label>\n        <Input id={id} type=\"text\" className=\"w-14\" defaultValue={String(currentPage)} />\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/hooks/use-pagination.ts",
          "type": "registry:hook",
          "target": "components/ui/pagination-12/use-pagination.ts",
          "content": "type UsePaginationProps = {\n  currentPage: number\n  totalPages: number\n  paginationItemsToDisplay: number\n}\n\ntype UsePaginationReturn = {\n  pages: number[]\n  showLeftEllipsis: boolean\n  showRightEllipsis: boolean\n}\n\nexport function usePagination({\n  currentPage,\n  totalPages,\n  paginationItemsToDisplay,\n}: UsePaginationProps): UsePaginationReturn {\n  const showLeftEllipsis = currentPage - 1 > paginationItemsToDisplay / 2\n  const showRightEllipsis = totalPages - currentPage + 1 > paginationItemsToDisplay / 2\n\n  function calculatePaginationRange(): number[] {\n    if (totalPages <= paginationItemsToDisplay) {\n      return Array.from({ length: totalPages }, (_, i) => i + 1)\n    }\n\n    const halfDisplay = Math.floor(paginationItemsToDisplay / 2)\n    const initialRange = {\n      start: currentPage - halfDisplay,\n      end: currentPage + halfDisplay,\n    }\n\n    const adjustedRange = {\n      start: Math.max(1, initialRange.start),\n      end: Math.min(totalPages, initialRange.end),\n    }\n\n    if (adjustedRange.start === 1) {\n      adjustedRange.end = paginationItemsToDisplay\n    }\n    if (adjustedRange.end === totalPages) {\n      adjustedRange.start = totalPages - paginationItemsToDisplay + 1\n    }\n\n    if (showLeftEllipsis) adjustedRange.start++\n    if (showRightEllipsis) adjustedRange.end--\n\n    return Array.from(\n      { length: adjustedRange.end - adjustedRange.start + 1 },\n      (_, i) => adjustedRange.start + i\n    )\n  }\n\n  const pages = calculatePaginationRange()\n\n  return {\n    pages,\n    showLeftEllipsis,\n    showRightEllipsis,\n  }\n}\n"
        },
        {
          "path": "registry/default/components/pagination/pagination-12.vue",
          "target": "components/ui/pagination-12.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ChevronLeftIcon, ChevronRightIcon } from 'lucide-vue-next';\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\nimport { Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink } from '@timui/vue';\nimport { usePagination } from '@/registry/default/hooks/use-pagination';\n\nconst id = 'pagination-12';\nconst currentPage = 1;\nconst totalPages = 10;\nconst paginationItemsToDisplay = 5;\nconst { pages, showLeftEllipsis, showRightEllipsis } = usePagination({\n  currentPage,\n  totalPages,\n  paginationItemsToDisplay,\n});\n\n</script>\n\n<template>\n  <div class=\"flex items-center justify-between gap-4\"><div><Pagination><PaginationContent><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" :href=\"currentPage === 1 ? undefined : `#/page/${currentPage - 1}`\" aria-label=\"Go to previous page\" :aria-disabled=\"currentPage === 1 ? true : undefined\" :role=\"currentPage === 1 ? 'link' : undefined\"><ChevronLeftIcon :size=\"16\" aria-hidden=\"true\" /></PaginationLink></PaginationItem><PaginationItem v-if=\"showLeftEllipsis\"><PaginationEllipsis /></PaginationItem><PaginationItem v-for=\"(page, index) in pages\" :key=\"page\"><PaginationLink :href=\"`#/page/${page}`\" :isActive=\"page === currentPage\">{{ page }}</PaginationLink></PaginationItem><PaginationItem v-if=\"showRightEllipsis\"><PaginationEllipsis /></PaginationItem><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" :href=\"currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`\" aria-label=\"Go to next page\" :aria-disabled=\"currentPage === totalPages ? true : undefined\" :role=\"currentPage === totalPages ? 'link' : undefined\"><ChevronRightIcon :size=\"16\" aria-hidden=\"true\" /></PaginationLink></PaginationItem></PaginationContent></Pagination></div><div class=\"flex items-center gap-3\"><Label :htmlFor=\"id\" class=\"whitespace-nowrap\">Go to page\n        </Label><Input :id=\"id\" type=\"text\" class=\"w-14\" :default-value=\"String(currentPage)\" /></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/pagination/pagination-12.html",
          "target": "components/ui/pagination-12.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex items-center justify-between gap-4\"><div><Pagination><PaginationContent><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"${currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}\" aria-label=\"Go to previous page\" aria-disabled=\"${currentPage === 1 ? true : undefined}\" role=\"${currentPage === 1 ? 'link' : undefined}\"><ChevronLeftIcon size=\"${16}\" aria-hidden=\"true\" /></PaginationLink></PaginationItem><!-- if showLeftEllipsis -->\n<PaginationItem><PaginationEllipsis /></PaginationItem>\n<!-- endif --><!-- Loop pages -->\n<PaginationItem key=\"${page}\"><PaginationLink href=\"${`#/page/${page}`}\" isactive=\"${page === currentPage}\">${page}</PaginationLink></PaginationItem>\n<!-- End Loop --><!-- if showRightEllipsis -->\n<PaginationItem><PaginationEllipsis /></PaginationItem>\n<!-- endif --><PaginationItem><PaginationLink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"${currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`}\" aria-label=\"Go to next page\" aria-disabled=\"${currentPage === totalPages ? true : undefined}\" role=\"${currentPage === totalPages ? 'link' : undefined}\"><ChevronRightIcon size=\"${16}\" aria-hidden=\"true\" /></PaginationLink></PaginationItem></PaginationContent></Pagination></div><div class=\"flex items-center gap-3\"><Label htmlfor=\"${id}\" class=\"whitespace-nowrap\">Go to page\n        </Label><Input id=\"${id}\" type=\"text\" class=\"w-14\" default-value=\"${String(currentPage)}\" /></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/pagination/pagination-12.wxml",
          "target": "components/ui/pagination-12/pagination-12.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex items-center justify-between gap-4\"><view><pagination><paginationcontent><paginationitem><paginationlink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"{{currentPage === 1 ? undefined : `#/page/${currentPage - 1}`}}\" aria-label=\"Go to previous page\" aria-disabled=\"{{currentPage === 1 ? true : undefined}}\" role=\"{{currentPage === 1 ? 'link' : undefined}}\"><chevronlefticon size=\"{{16}}\" aria-hidden=\"true\" /></paginationlink></paginationitem><paginationitem wx:if=\"{{showLeftEllipsis}}\"><paginationellipsis /></paginationitem><paginationitem wx:for=\"{{pages}}\" wx:for-item=\"page\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{page}}\"><paginationlink href=\"{{`#/page/${page}`}}\" isactive=\"{{page === currentPage}}\">{{ page }}</paginationlink></paginationitem><paginationitem wx:if=\"{{showRightEllipsis}}\"><paginationellipsis /></paginationitem><paginationitem><paginationlink class=\"aria-disabled:pointer-events-none aria-disabled:opacity-50\" href=\"{{currentPage === totalPages ? undefined : `#/page/${currentPage + 1}`}}\" aria-label=\"Go to next page\" aria-disabled=\"{{currentPage === totalPages ? true : undefined}}\" role=\"{{currentPage === totalPages ? 'link' : undefined}}\"><chevronrighticon size=\"{{16}}\" aria-hidden=\"true\" /></paginationlink></paginationitem></paginationcontent></pagination></view><view class=\"flex items-center gap-3\"><label htmlfor=\"{{id}}\" class=\"whitespace-nowrap\">Go to page\n        </label><input id=\"{{id}}\" type=\"text\" class=\"w-14\" default-value=\"{{String(currentPage)}}\" /></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "pagination",
          "input"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "pagination-12",
          "group": "pagination",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "pagination-12",
              "path": "registry/default/components/pagination/pagination-12.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "pagination-12",
              "path": "registry/default/components/pagination/pagination-12.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "pagination-12",
              "path": "registry/default/components/pagination/pagination-12.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "pagination-12",
              "path": "registry/default/components/pagination/pagination-12.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "paginations",
        "title": "Pagination · Go to page"
      },
      "categories": [
        "paginations",
        "pagination"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "table-01",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/table.json"
      ],
      "files": [
        {
          "path": "registry/default/components/table/table-01.tsx",
          "type": "registry:component",
          "target": "components/ui/table-01.tsx",
          "content": "import {\n  Table,\n  TableBody,\n  TableCell,\n  TableFooter,\n  TableHead,\n  TableHeader,\n  TableRow,\n} from '@timui/react'\n\nconst items = [\n  {\n    id: '1',\n    name: 'Alex Thompson',\n    email: 'alex.t@company.com',\n    location: 'San Francisco, US',\n    status: 'Active',\n    balance: '$1,250.00',\n  },\n  {\n    id: '2',\n    name: 'Sarah Chen',\n    email: 'sarah.c@company.com',\n    location: 'Singapore',\n    status: 'Active',\n    balance: '$600.00',\n  },\n  {\n    id: '3',\n    name: 'James Wilson',\n    email: 'j.wilson@company.com',\n    location: 'London, UK',\n    status: 'Inactive',\n    balance: '$650.00',\n  },\n  {\n    id: '4',\n    name: 'Maria Garcia',\n    email: 'm.garcia@company.com',\n    location: 'Madrid, Spain',\n    status: 'Active',\n    balance: '$0.00',\n  },\n  {\n    id: '5',\n    name: 'David Kim',\n    email: 'd.kim@company.com',\n    location: 'Seoul, KR',\n    status: 'Active',\n    balance: '-$1,000.00',\n  },\n]\n\nexport default function Component() {\n  return (\n    <div>\n      <Table>\n        <TableHeader>\n          <TableRow className=\"hover:bg-transparent\">\n            <TableHead>Name</TableHead>\n            <TableHead>Email</TableHead>\n            <TableHead>Location</TableHead>\n            <TableHead>Status</TableHead>\n            <TableHead className=\"text-right\">Balance</TableHead>\n          </TableRow>\n        </TableHeader>\n        <TableBody>\n          {items.map((item) => (\n            <TableRow key={item.id}>\n              <TableCell className=\"font-medium\">{item.name}</TableCell>\n              <TableCell>{item.email}</TableCell>\n              <TableCell>{item.location}</TableCell>\n              <TableCell>{item.status}</TableCell>\n              <TableCell className=\"text-right\">{item.balance}</TableCell>\n            </TableRow>\n          ))}\n        </TableBody>\n        <TableFooter className=\"bg-transparent\">\n          <TableRow className=\"hover:bg-transparent\">\n            <TableCell colSpan={4}>Total</TableCell>\n            <TableCell className=\"text-right\">$2,500.00</TableCell>\n          </TableRow>\n        </TableFooter>\n      </Table>\n      <p className=\"text-muted-foreground mt-4 text-center text-sm\">Basic table</p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/table/table-01.vue",
          "target": "components/ui/table-01.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Table } from '@timui/vue';\nimport { TableBody } from '@timui/vue';\nimport { TableCell } from '@timui/vue';\nimport { TableFooter } from '@timui/vue';\nimport { TableHead } from '@timui/vue';\nimport { TableHeader } from '@timui/vue';\nimport { TableRow } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: '1',\n    name: 'Alex Thompson',\n    email: 'alex.t@company.com',\n    location: 'San Francisco, US',\n    status: 'Active',\n    balance: '$1,250.00',\n  },\n  {\n    id: '2',\n    name: 'Sarah Chen',\n    email: 'sarah.c@company.com',\n    location: 'Singapore',\n    status: 'Active',\n    balance: '$600.00',\n  },\n  {\n    id: '3',\n    name: 'James Wilson',\n    email: 'j.wilson@company.com',\n    location: 'London, UK',\n    status: 'Inactive',\n    balance: '$650.00',\n  },\n  {\n    id: '4',\n    name: 'Maria Garcia',\n    email: 'm.garcia@company.com',\n    location: 'Madrid, Spain',\n    status: 'Active',\n    balance: '$0.00',\n  },\n  {\n    id: '5',\n    name: 'David Kim',\n    email: 'd.kim@company.com',\n    location: 'Seoul, KR',\n    status: 'Active',\n    balance: '-$1,000.00',\n  },\n]\n\n</script>\n\n<template>\n  <div><Table><TableHeader><TableRow class=\"hover:bg-transparent\"><TableHead>Name</TableHead><TableHead>Email</TableHead><TableHead>Location</TableHead><TableHead>Status</TableHead><TableHead class=\"text-right\">Balance</TableHead></TableRow></TableHeader><TableBody><TableRow v-for=\"(item, index) in items\" :key=\"item.id\"><TableCell class=\"font-medium\">{{ item.name }}</TableCell><TableCell>{{ item.email }}</TableCell><TableCell>{{ item.location }}</TableCell><TableCell>{{ item.status }}</TableCell><TableCell class=\"text-right\">{{ item.balance }}</TableCell></TableRow></TableBody><TableFooter class=\"bg-transparent\"><TableRow class=\"hover:bg-transparent\"><TableCell :colSpan=\"4\">Total</TableCell><TableCell class=\"text-right\">$2,500.00</TableCell></TableRow></TableFooter></Table><p class=\"text-muted-foreground mt-4 text-center text-sm\">Basic table</p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/table/table-01.html",
          "target": "components/ui/table-01.html",
          "type": "registry:component",
          "content": "<template>\n  <div><Table><TableHeader><TableRow class=\"hover:bg-transparent\"><TableHead>Name</TableHead><TableHead>Email</TableHead><TableHead>Location</TableHead><TableHead>Status</TableHead><TableHead class=\"text-right\">Balance</TableHead></TableRow></TableHeader><TableBody><!-- Loop items -->\n<TableRow key=\"${item.id}\"><TableCell class=\"font-medium\">${item.name}</TableCell><TableCell>${item.email}</TableCell><TableCell>${item.location}</TableCell><TableCell>${item.status}</TableCell><TableCell class=\"text-right\">${item.balance}</TableCell></TableRow>\n<!-- End Loop --></TableBody><TableFooter class=\"bg-transparent\"><TableRow class=\"hover:bg-transparent\"><TableCell colspan=\"${4}\">Total</TableCell><TableCell class=\"text-right\">$2,500.00</TableCell></TableRow></TableFooter></Table><p class=\"text-muted-foreground mt-4 text-center text-sm\">Basic table</p></div>\n</template>"
        },
        {
          "path": "registry/default/components/table/table-01.wxml",
          "target": "components/ui/table-01/table-01.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><table><tableheader><tablerow class=\"hover:bg-transparent\"><tablehead>Name</tablehead><tablehead>Email</tablehead><tablehead>Location</tablehead><tablehead>Status</tablehead><tablehead class=\"text-right\">Balance</tablehead></tablerow></tableheader><tablebody><tablerow wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{item.id}}\"><tablecell class=\"font-medium\">{{ item.name }}</tablecell><tablecell>{{ item.email }}</tablecell><tablecell>{{ item.location }}</tablecell><tablecell>{{ item.status }}</tablecell><tablecell class=\"text-right\">{{ item.balance }}</tablecell></tablerow></tablebody><tablefooter class=\"bg-transparent\"><tablerow class=\"hover:bg-transparent\"><tablecell colspan=\"{{4}}\">Total</tablecell><tablecell class=\"text-right\">$2,500.00</tablecell></tablerow></tablefooter></table><text class=\"text-muted-foreground mt-4 text-center text-sm\">Basic table</text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "table"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "table-01",
          "group": "table",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "table-01",
              "path": "registry/default/components/table/table-01.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "table-01",
              "path": "registry/default/components/table/table-01.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "table-01",
              "path": "registry/default/components/table/table-01.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "table-01",
              "path": "registry/default/components/table/table-01.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tables",
        "title": "Table · Interactive State"
      },
      "categories": [
        "tables",
        "table"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "table-02",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/table.json"
      ],
      "files": [
        {
          "path": "registry/default/components/table/table-02.tsx",
          "type": "registry:component",
          "target": "components/ui/table-02.tsx",
          "content": "import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@timui/react'\n\nconst items = [\n  {\n    id: '1',\n    name: 'Alex Thompson',\n    username: '@alexthompson',\n    image:\n      'https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/exp1/avatar-40-02_upqrxi.jpg',\n    email: 'alex.t@company.com',\n    location: 'San Francisco, US',\n    status: 'Active',\n    balance: '$1,250.00',\n  },\n  {\n    id: '2',\n    name: 'Sarah Chen',\n    username: '@sarahchen',\n    image:\n      'https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/exp1/avatar-40-01_ij9v7j.jpg',\n    email: 'sarah.c@company.com',\n    location: 'Singapore',\n    status: 'Active',\n    balance: '$600.00',\n  },\n  {\n    id: '4',\n    name: 'Maria Garcia',\n    username: '@mariagarcia',\n    image:\n      'https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/exp1/avatar-40-03_dkeufx.jpg',\n    email: 'm.garcia@company.com',\n    location: 'Madrid, Spain',\n    status: 'Active',\n    balance: '$0.00',\n  },\n  {\n    id: '5',\n    name: 'David Kim',\n    username: '@davidkim',\n    image:\n      'https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/exp1/avatar-40-05_cmz0mg.jpg',\n    email: 'd.kim@company.com',\n    location: 'Seoul, KR',\n    status: 'Active',\n    balance: '-$1,000.00',\n  },\n]\n\nexport default function Component() {\n  return (\n    <div>\n      <Table>\n        <TableHeader>\n          <TableRow className=\"hover:bg-transparent\">\n            <TableHead>Name</TableHead>\n            <TableHead>Email</TableHead>\n            <TableHead>Location</TableHead>\n            <TableHead>Status</TableHead>\n            <TableHead className=\"text-right\">Balance</TableHead>\n          </TableRow>\n        </TableHeader>\n        <TableBody>\n          {items.map((item) => (\n            <TableRow key={item.id}>\n              <TableCell>\n                <div className=\"flex items-center gap-3\">\n                  <img\n                    className=\"rounded-full\"\n                    src={item.image}\n                    width={40}\n                    height={40}\n                    alt={item.name}\n                  />\n                  <div>\n                    <div className=\"font-medium\">{item.name}</div>\n                    <span className=\"text-muted-foreground mt-0.5 text-xs\">{item.username}</span>\n                  </div>\n                </div>\n              </TableCell>\n              <TableCell>{item.email}</TableCell>\n              <TableCell>{item.location}</TableCell>\n              <TableCell>{item.status}</TableCell>\n              <TableCell className=\"text-right\">{item.balance}</TableCell>\n            </TableRow>\n          ))}\n        </TableBody>\n      </Table>\n      <p className=\"text-muted-foreground mt-4 text-center text-sm\">Table with images</p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/table/table-02.vue",
          "target": "components/ui/table-02.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Table } from '@timui/vue';\nimport { TableBody } from '@timui/vue';\nimport { TableCell } from '@timui/vue';\nimport { TableHead } from '@timui/vue';\nimport { TableHeader } from '@timui/vue';\nimport { TableRow } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: '1',\n    name: 'Alex Thompson',\n    username: '@alexthompson',\n    image:\n      'https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/exp1/avatar-40-02_upqrxi.jpg',\n    email: 'alex.t@company.com',\n    location: 'San Francisco, US',\n    status: 'Active',\n    balance: '$1,250.00',\n  },\n  {\n    id: '2',\n    name: 'Sarah Chen',\n    username: '@sarahchen',\n    image:\n      'https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/exp1/avatar-40-01_ij9v7j.jpg',\n    email: 'sarah.c@company.com',\n    location: 'Singapore',\n    status: 'Active',\n    balance: '$600.00',\n  },\n  {\n    id: '4',\n    name: 'Maria Garcia',\n    username: '@mariagarcia',\n    image:\n      'https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/exp1/avatar-40-03_dkeufx.jpg',\n    email: 'm.garcia@company.com',\n    location: 'Madrid, Spain',\n    status: 'Active',\n    balance: '$0.00',\n  },\n  {\n    id: '5',\n    name: 'David Kim',\n    username: '@davidkim',\n    image:\n      'https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/exp1/avatar-40-05_cmz0mg.jpg',\n    email: 'd.kim@company.com',\n    location: 'Seoul, KR',\n    status: 'Active',\n    balance: '-$1,000.00',\n  },\n]\n\n</script>\n\n<template>\n  <div><Table><TableHeader><TableRow class=\"hover:bg-transparent\"><TableHead>Name</TableHead><TableHead>Email</TableHead><TableHead>Location</TableHead><TableHead>Status</TableHead><TableHead class=\"text-right\">Balance</TableHead></TableRow></TableHeader><TableBody><TableRow v-for=\"(item, index) in items\" :key=\"item.id\"><TableCell><div class=\"flex items-center gap-3\"><img class=\"rounded-full\" :src=\"item.image\" :width=\"40\" :height=\"40\" :alt=\"item.name\" /><div><div class=\"font-medium\">{{ item.name }}</div><span class=\"text-muted-foreground mt-0.5 text-xs\">{{ item.username }}</span></div></div></TableCell><TableCell>{{ item.email }}</TableCell><TableCell>{{ item.location }}</TableCell><TableCell>{{ item.status }}</TableCell><TableCell class=\"text-right\">{{ item.balance }}</TableCell></TableRow></TableBody></Table><p class=\"text-muted-foreground mt-4 text-center text-sm\">Table with images</p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/table/table-02.html",
          "target": "components/ui/table-02.html",
          "type": "registry:component",
          "content": "<template>\n  <div><Table><TableHeader><TableRow class=\"hover:bg-transparent\"><TableHead>Name</TableHead><TableHead>Email</TableHead><TableHead>Location</TableHead><TableHead>Status</TableHead><TableHead class=\"text-right\">Balance</TableHead></TableRow></TableHeader><TableBody><!-- Loop items -->\n<TableRow key=\"${item.id}\"><TableCell><div class=\"flex items-center gap-3\"><img class=\"rounded-full\" src=\"${item.image}\" width=\"${40}\" height=\"${40}\" alt=\"${item.name}\" /><div><div class=\"font-medium\">${item.name}</div><span class=\"text-muted-foreground mt-0.5 text-xs\">${item.username}</span></div></div></TableCell><TableCell>${item.email}</TableCell><TableCell>${item.location}</TableCell><TableCell>${item.status}</TableCell><TableCell class=\"text-right\">${item.balance}</TableCell></TableRow>\n<!-- End Loop --></TableBody></Table><p class=\"text-muted-foreground mt-4 text-center text-sm\">Table with images</p></div>\n</template>"
        },
        {
          "path": "registry/default/components/table/table-02.wxml",
          "target": "components/ui/table-02/table-02.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><table><tableheader><tablerow class=\"hover:bg-transparent\"><tablehead>Name</tablehead><tablehead>Email</tablehead><tablehead>Location</tablehead><tablehead>Status</tablehead><tablehead class=\"text-right\">Balance</tablehead></tablerow></tableheader><tablebody><tablerow wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{item.id}}\"><tablecell><view class=\"flex items-center gap-3\"><image class=\"rounded-full\" src=\"{{item.image}}\" width=\"{{40}}\" height=\"{{40}}\" alt=\"{{item.name}}\" /><view><view class=\"font-medium\">{{ item.name }}</view><text class=\"text-muted-foreground mt-0.5 text-xs\">{{ item.username }}</text></view></view></tablecell><tablecell>{{ item.email }}</tablecell><tablecell>{{ item.location }}</tablecell><tablecell>{{ item.status }}</tablecell><tablecell class=\"text-right\">{{ item.balance }}</tablecell></tablerow></tablebody></table><text class=\"text-muted-foreground mt-4 text-center text-sm\">Table with images</text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "table",
          "user",
          "avatar"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "table-02",
          "group": "table",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "table-02",
              "path": "registry/default/components/table/table-02.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "table-02",
              "path": "registry/default/components/table/table-02.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "table-02",
              "path": "registry/default/components/table/table-02.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "table-02",
              "path": "registry/default/components/table/table-02.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tables",
        "title": "Table · Interactive State"
      },
      "categories": [
        "tables",
        "table"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "table-03",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/table.json"
      ],
      "files": [
        {
          "path": "registry/default/components/table/table-03.tsx",
          "type": "registry:component",
          "target": "components/ui/table-03.tsx",
          "content": "import {\n  Table,\n  TableBody,\n  TableCell,\n  TableFooter,\n  TableHead,\n  TableHeader,\n  TableRow,\n} from '@timui/react'\n\nconst items = [\n  {\n    id: '1',\n    name: 'Alex Thompson',\n    email: 'alex.t@company.com',\n    location: 'San Francisco, US',\n    status: 'Active',\n    balance: '$1,250.00',\n  },\n  {\n    id: '2',\n    name: 'Sarah Chen',\n    email: 'sarah.c@company.com',\n    location: 'Singapore',\n    status: 'Active',\n    balance: '$600.00',\n  },\n  {\n    id: '3',\n    name: 'James Wilson',\n    email: 'j.wilson@company.com',\n    location: 'London, UK',\n    status: 'Inactive',\n    balance: '$650.00',\n  },\n  {\n    id: '4',\n    name: 'Maria Garcia',\n    email: 'm.garcia@company.com',\n    location: 'Madrid, Spain',\n    status: 'Active',\n    balance: '$0.00',\n  },\n  {\n    id: '5',\n    name: 'David Kim',\n    email: 'd.kim@company.com',\n    location: 'Seoul, KR',\n    status: 'Active',\n    balance: '-$1,000.00',\n  },\n]\n\nexport default function Component() {\n  return (\n    <div>\n      <Table>\n        <TableHeader>\n          <TableRow className=\"hover:bg-transparent\">\n            <TableHead>Name</TableHead>\n            <TableHead>Email</TableHead>\n            <TableHead>Location</TableHead>\n            <TableHead>Status</TableHead>\n            <TableHead className=\"text-right\">Balance</TableHead>\n          </TableRow>\n        </TableHeader>\n        <tbody aria-hidden=\"true\" className=\"table-row h-2\"></tbody>\n        <TableBody className=\"[&_td:first-child]:rounded-l-lg [&_td:last-child]:rounded-r-lg\">\n          {items.map((item) => (\n            <TableRow key={item.id} className=\"border-none\">\n              <TableCell className=\"py-2.5 font-medium\">{item.name}</TableCell>\n              <TableCell className=\"py-2.5\">{item.email}</TableCell>\n              <TableCell className=\"py-2.5\">{item.location}</TableCell>\n              <TableCell className=\"py-2.5\">{item.status}</TableCell>\n              <TableCell className=\"py-2.5 text-right\">{item.balance}</TableCell>\n            </TableRow>\n          ))}\n        </TableBody>\n        <tbody aria-hidden=\"true\" className=\"table-row h-2\"></tbody>\n        <TableFooter className=\"bg-transparent\">\n          <TableRow className=\"hover:bg-transparent\">\n            <TableCell colSpan={4}>Total</TableCell>\n            <TableCell className=\"text-right\">$2,500.00</TableCell>\n          </TableRow>\n        </TableFooter>\n      </Table>\n      <p className=\"text-muted-foreground mt-4 text-center text-sm\">\n        Table without horizontal dividers\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/table/table-03.vue",
          "target": "components/ui/table-03.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Table } from '@timui/vue';\nimport { TableBody } from '@timui/vue';\nimport { TableCell } from '@timui/vue';\nimport { TableFooter } from '@timui/vue';\nimport { TableHead } from '@timui/vue';\nimport { TableHeader } from '@timui/vue';\nimport { TableRow } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: '1',\n    name: 'Alex Thompson',\n    email: 'alex.t@company.com',\n    location: 'San Francisco, US',\n    status: 'Active',\n    balance: '$1,250.00',\n  },\n  {\n    id: '2',\n    name: 'Sarah Chen',\n    email: 'sarah.c@company.com',\n    location: 'Singapore',\n    status: 'Active',\n    balance: '$600.00',\n  },\n  {\n    id: '3',\n    name: 'James Wilson',\n    email: 'j.wilson@company.com',\n    location: 'London, UK',\n    status: 'Inactive',\n    balance: '$650.00',\n  },\n  {\n    id: '4',\n    name: 'Maria Garcia',\n    email: 'm.garcia@company.com',\n    location: 'Madrid, Spain',\n    status: 'Active',\n    balance: '$0.00',\n  },\n  {\n    id: '5',\n    name: 'David Kim',\n    email: 'd.kim@company.com',\n    location: 'Seoul, KR',\n    status: 'Active',\n    balance: '-$1,000.00',\n  },\n]\n\n</script>\n\n<template>\n  <div><Table><TableHeader><TableRow class=\"hover:bg-transparent\"><TableHead>Name</TableHead><TableHead>Email</TableHead><TableHead>Location</TableHead><TableHead>Status</TableHead><TableHead class=\"text-right\">Balance</TableHead></TableRow></TableHeader><tbody aria-hidden=\"true\" class=\"table-row h-2\"></tbody><TableBody class=\"[&_td:first-child]:rounded-l-lg [&_td:last-child]:rounded-r-lg\"><TableRow v-for=\"(item, index) in items\" :key=\"item.id\" class=\"border-none\"><TableCell class=\"py-2.5 font-medium\">{{ item.name }}</TableCell><TableCell class=\"py-2.5\">{{ item.email }}</TableCell><TableCell class=\"py-2.5\">{{ item.location }}</TableCell><TableCell class=\"py-2.5\">{{ item.status }}</TableCell><TableCell class=\"py-2.5 text-right\">{{ item.balance }}</TableCell></TableRow></TableBody><tbody aria-hidden=\"true\" class=\"table-row h-2\"></tbody><TableFooter class=\"bg-transparent\"><TableRow class=\"hover:bg-transparent\"><TableCell :colSpan=\"4\">Total</TableCell><TableCell class=\"text-right\">$2,500.00</TableCell></TableRow></TableFooter></Table><p class=\"text-muted-foreground mt-4 text-center text-sm\">Table without horizontal dividers\n      </p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/table/table-03.html",
          "target": "components/ui/table-03.html",
          "type": "registry:component",
          "content": "<template>\n  <div><Table><TableHeader><TableRow class=\"hover:bg-transparent\"><TableHead>Name</TableHead><TableHead>Email</TableHead><TableHead>Location</TableHead><TableHead>Status</TableHead><TableHead class=\"text-right\">Balance</TableHead></TableRow></TableHeader><tbody aria-hidden=\"true\" class=\"table-row h-2\"></tbody><TableBody class=\"[&_td:first-child]:rounded-l-lg [&_td:last-child]:rounded-r-lg\"><!-- Loop items -->\n<TableRow key=\"${item.id}\" class=\"border-none\"><TableCell class=\"py-2.5 font-medium\">${item.name}</TableCell><TableCell class=\"py-2.5\">${item.email}</TableCell><TableCell class=\"py-2.5\">${item.location}</TableCell><TableCell class=\"py-2.5\">${item.status}</TableCell><TableCell class=\"py-2.5 text-right\">${item.balance}</TableCell></TableRow>\n<!-- End Loop --></TableBody><tbody aria-hidden=\"true\" class=\"table-row h-2\"></tbody><TableFooter class=\"bg-transparent\"><TableRow class=\"hover:bg-transparent\"><TableCell colspan=\"${4}\">Total</TableCell><TableCell class=\"text-right\">$2,500.00</TableCell></TableRow></TableFooter></Table><p class=\"text-muted-foreground mt-4 text-center text-sm\">Table without horizontal dividers\n      </p></div>\n</template>"
        },
        {
          "path": "registry/default/components/table/table-03.wxml",
          "target": "components/ui/table-03/table-03.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><table><tableheader><tablerow class=\"hover:bg-transparent\"><tablehead>Name</tablehead><tablehead>Email</tablehead><tablehead>Location</tablehead><tablehead>Status</tablehead><tablehead class=\"text-right\">Balance</tablehead></tablerow></tableheader><tbody aria-hidden=\"true\" class=\"table-row h-2\"></tbody><tablebody class=\"[&_td:first-child]:rounded-l-lg [&_td:last-child]:rounded-r-lg\"><tablerow wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{item.id}}\" class=\"border-none\"><tablecell class=\"py-2.5 font-medium\">{{ item.name }}</tablecell><tablecell class=\"py-2.5\">{{ item.email }}</tablecell><tablecell class=\"py-2.5\">{{ item.location }}</tablecell><tablecell class=\"py-2.5\">{{ item.status }}</tablecell><tablecell class=\"py-2.5 text-right\">{{ item.balance }}</tablecell></tablerow></tablebody><tbody aria-hidden=\"true\" class=\"table-row h-2\"></tbody><tablefooter class=\"bg-transparent\"><tablerow class=\"hover:bg-transparent\"><tablecell colspan=\"{{4}}\">Total</tablecell><tablecell class=\"text-right\">$2,500.00</tablecell></tablerow></tablefooter></table><text class=\"text-muted-foreground mt-4 text-center text-sm\">Table without horizontal dividers\n      </text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "table"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "table-03",
          "group": "table",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "table-03",
              "path": "registry/default/components/table/table-03.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "table-03",
              "path": "registry/default/components/table/table-03.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "table-03",
              "path": "registry/default/components/table/table-03.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "table-03",
              "path": "registry/default/components/table/table-03.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tables",
        "title": "Table · Interactive State"
      },
      "categories": [
        "tables",
        "table"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "table-04",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/table.json"
      ],
      "files": [
        {
          "path": "registry/default/components/table/table-04.tsx",
          "type": "registry:component",
          "target": "components/ui/table-04.tsx",
          "content": "import {\n  Table,\n  TableBody,\n  TableCell,\n  TableFooter,\n  TableHead,\n  TableHeader,\n  TableRow,\n} from '@timui/react'\n\nconst items = [\n  {\n    id: '1',\n    name: 'Alex Thompson',\n    email: 'alex.t@company.com',\n    location: 'San Francisco, US',\n    status: 'Active',\n    balance: '$1,250.00',\n  },\n  {\n    id: '2',\n    name: 'Sarah Chen',\n    email: 'sarah.c@company.com',\n    location: 'Singapore',\n    status: 'Active',\n    balance: '$600.00',\n  },\n  {\n    id: '3',\n    name: 'James Wilson',\n    email: 'j.wilson@company.com',\n    location: 'London, UK',\n    status: 'Inactive',\n    balance: '$650.00',\n  },\n  {\n    id: '4',\n    name: 'Maria Garcia',\n    email: 'm.garcia@company.com',\n    location: 'Madrid, Spain',\n    status: 'Active',\n    balance: '$0.00',\n  },\n  {\n    id: '5',\n    name: 'David Kim',\n    email: 'd.kim@company.com',\n    location: 'Seoul, KR',\n    status: 'Active',\n    balance: '-$1,000.00',\n  },\n]\n\nexport default function Component() {\n  return (\n    <div>\n      <Table>\n        <TableHeader className=\"bg-transparent\">\n          <TableRow className=\"hover:bg-transparent\">\n            <TableHead>Name</TableHead>\n            <TableHead>Email</TableHead>\n            <TableHead>Location</TableHead>\n            <TableHead>Status</TableHead>\n            <TableHead className=\"text-right\">Balance</TableHead>\n          </TableRow>\n        </TableHeader>\n        <tbody aria-hidden=\"true\" className=\"table-row h-2\"></tbody>\n        <TableBody className=\"[&_td:first-child]:rounded-l-lg [&_td:last-child]:rounded-r-lg\">\n          {items.map((item) => (\n            <TableRow\n              key={item.id}\n              className=\"odd:bg-muted/50 odd:hover:bg-muted/50 border-none hover:bg-transparent\"\n            >\n              <TableCell className=\"py-2.5 font-medium\">{item.name}</TableCell>\n              <TableCell className=\"py-2.5\">{item.email}</TableCell>\n              <TableCell className=\"py-2.5\">{item.location}</TableCell>\n              <TableCell className=\"py-2.5\">{item.status}</TableCell>\n              <TableCell className=\"py-2.5 text-right\">{item.balance}</TableCell>\n            </TableRow>\n          ))}\n        </TableBody>\n        <tbody aria-hidden=\"true\" className=\"table-row h-2\"></tbody>\n        <TableFooter className=\"bg-transparent\">\n          <TableRow className=\"hover:bg-transparent\">\n            <TableCell colSpan={4}>Total</TableCell>\n            <TableCell className=\"text-right\">$2,500.00</TableCell>\n          </TableRow>\n        </TableFooter>\n      </Table>\n      <p className=\"text-muted-foreground mt-4 text-center text-sm\">Striped table</p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/table/table-04.vue",
          "target": "components/ui/table-04.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Table } from '@timui/vue';\nimport { TableBody } from '@timui/vue';\nimport { TableCell } from '@timui/vue';\nimport { TableFooter } from '@timui/vue';\nimport { TableHead } from '@timui/vue';\nimport { TableHeader } from '@timui/vue';\nimport { TableRow } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: '1',\n    name: 'Alex Thompson',\n    email: 'alex.t@company.com',\n    location: 'San Francisco, US',\n    status: 'Active',\n    balance: '$1,250.00',\n  },\n  {\n    id: '2',\n    name: 'Sarah Chen',\n    email: 'sarah.c@company.com',\n    location: 'Singapore',\n    status: 'Active',\n    balance: '$600.00',\n  },\n  {\n    id: '3',\n    name: 'James Wilson',\n    email: 'j.wilson@company.com',\n    location: 'London, UK',\n    status: 'Inactive',\n    balance: '$650.00',\n  },\n  {\n    id: '4',\n    name: 'Maria Garcia',\n    email: 'm.garcia@company.com',\n    location: 'Madrid, Spain',\n    status: 'Active',\n    balance: '$0.00',\n  },\n  {\n    id: '5',\n    name: 'David Kim',\n    email: 'd.kim@company.com',\n    location: 'Seoul, KR',\n    status: 'Active',\n    balance: '-$1,000.00',\n  },\n]\n\n</script>\n\n<template>\n  <div><Table><TableHeader class=\"bg-transparent\"><TableRow class=\"hover:bg-transparent\"><TableHead>Name</TableHead><TableHead>Email</TableHead><TableHead>Location</TableHead><TableHead>Status</TableHead><TableHead class=\"text-right\">Balance</TableHead></TableRow></TableHeader><tbody aria-hidden=\"true\" class=\"table-row h-2\"></tbody><TableBody class=\"[&_td:first-child]:rounded-l-lg [&_td:last-child]:rounded-r-lg\"><TableRow v-for=\"(item, index) in items\" :key=\"item.id\" class=\"odd:bg-muted/50 odd:hover:bg-muted/50 border-none hover:bg-transparent\"><TableCell class=\"py-2.5 font-medium\">{{ item.name }}</TableCell><TableCell class=\"py-2.5\">{{ item.email }}</TableCell><TableCell class=\"py-2.5\">{{ item.location }}</TableCell><TableCell class=\"py-2.5\">{{ item.status }}</TableCell><TableCell class=\"py-2.5 text-right\">{{ item.balance }}</TableCell></TableRow></TableBody><tbody aria-hidden=\"true\" class=\"table-row h-2\"></tbody><TableFooter class=\"bg-transparent\"><TableRow class=\"hover:bg-transparent\"><TableCell :colSpan=\"4\">Total</TableCell><TableCell class=\"text-right\">$2,500.00</TableCell></TableRow></TableFooter></Table><p class=\"text-muted-foreground mt-4 text-center text-sm\">Striped table</p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/table/table-04.html",
          "target": "components/ui/table-04.html",
          "type": "registry:component",
          "content": "<template>\n  <div><Table><TableHeader class=\"bg-transparent\"><TableRow class=\"hover:bg-transparent\"><TableHead>Name</TableHead><TableHead>Email</TableHead><TableHead>Location</TableHead><TableHead>Status</TableHead><TableHead class=\"text-right\">Balance</TableHead></TableRow></TableHeader><tbody aria-hidden=\"true\" class=\"table-row h-2\"></tbody><TableBody class=\"[&_td:first-child]:rounded-l-lg [&_td:last-child]:rounded-r-lg\"><!-- Loop items -->\n<TableRow key=\"${item.id}\" class=\"odd:bg-muted/50 odd:hover:bg-muted/50 border-none hover:bg-transparent\"><TableCell class=\"py-2.5 font-medium\">${item.name}</TableCell><TableCell class=\"py-2.5\">${item.email}</TableCell><TableCell class=\"py-2.5\">${item.location}</TableCell><TableCell class=\"py-2.5\">${item.status}</TableCell><TableCell class=\"py-2.5 text-right\">${item.balance}</TableCell></TableRow>\n<!-- End Loop --></TableBody><tbody aria-hidden=\"true\" class=\"table-row h-2\"></tbody><TableFooter class=\"bg-transparent\"><TableRow class=\"hover:bg-transparent\"><TableCell colspan=\"${4}\">Total</TableCell><TableCell class=\"text-right\">$2,500.00</TableCell></TableRow></TableFooter></Table><p class=\"text-muted-foreground mt-4 text-center text-sm\">Striped table</p></div>\n</template>"
        },
        {
          "path": "registry/default/components/table/table-04.wxml",
          "target": "components/ui/table-04/table-04.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><table><tableheader class=\"bg-transparent\"><tablerow class=\"hover:bg-transparent\"><tablehead>Name</tablehead><tablehead>Email</tablehead><tablehead>Location</tablehead><tablehead>Status</tablehead><tablehead class=\"text-right\">Balance</tablehead></tablerow></tableheader><tbody aria-hidden=\"true\" class=\"table-row h-2\"></tbody><tablebody class=\"[&_td:first-child]:rounded-l-lg [&_td:last-child]:rounded-r-lg\"><tablerow wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{item.id}}\" class=\"odd:bg-muted/50 odd:hover:bg-muted/50 border-none hover:bg-transparent\"><tablecell class=\"py-2.5 font-medium\">{{ item.name }}</tablecell><tablecell class=\"py-2.5\">{{ item.email }}</tablecell><tablecell class=\"py-2.5\">{{ item.location }}</tablecell><tablecell class=\"py-2.5\">{{ item.status }}</tablecell><tablecell class=\"py-2.5 text-right\">{{ item.balance }}</tablecell></tablerow></tablebody><tbody aria-hidden=\"true\" class=\"table-row h-2\"></tbody><tablefooter class=\"bg-transparent\"><tablerow class=\"hover:bg-transparent\"><tablecell colspan=\"{{4}}\">Total</tablecell><tablecell class=\"text-right\">$2,500.00</tablecell></tablerow></tablefooter></table><text class=\"text-muted-foreground mt-4 text-center text-sm\">Striped table</text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "table"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "table-04",
          "group": "table",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "table-04",
              "path": "registry/default/components/table/table-04.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "table-04",
              "path": "registry/default/components/table/table-04.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "table-04",
              "path": "registry/default/components/table/table-04.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "table-04",
              "path": "registry/default/components/table/table-04.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tables",
        "title": "Table · Interactive State"
      },
      "categories": [
        "tables",
        "table"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "table-05",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/table.json"
      ],
      "files": [
        {
          "path": "registry/default/components/table/table-05.tsx",
          "type": "registry:component",
          "target": "components/ui/table-05.tsx",
          "content": "import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@timui/react'\n\nconst items = [\n  {\n    id: '1',\n    name: 'Alex Thompson',\n    email: 'alex.t@company.com',\n    location: 'San Francisco, US',\n    status: 'Active',\n    balance: '$1,250.00',\n  },\n  {\n    id: '2',\n    name: 'Sarah Chen',\n    email: 'sarah.c@company.com',\n    location: 'Singapore',\n    status: 'Active',\n    balance: '$600.00',\n  },\n  {\n    id: '3',\n    name: 'James Wilson',\n    email: 'j.wilson@company.com',\n    location: 'London, UK',\n    status: 'Inactive',\n    balance: '$650.00',\n  },\n  {\n    id: '4',\n    name: 'Maria Garcia',\n    email: 'm.garcia@company.com',\n    location: 'Madrid, Spain',\n    status: 'Active',\n    balance: '$0.00',\n  },\n  {\n    id: '5',\n    name: 'David Kim',\n    email: 'd.kim@company.com',\n    location: 'Seoul, KR',\n    status: 'Active',\n    balance: '-$1,000.00',\n  },\n]\n\nexport default function Component() {\n  return (\n    <div>\n      <Table>\n        <TableHeader className=\"bg-transparent\">\n          <TableRow className=\"*:border-border hover:bg-transparent [&>:not(:last-child)]:border-r\">\n            <TableHead>Name</TableHead>\n            <TableHead>Email</TableHead>\n            <TableHead>Location</TableHead>\n            <TableHead>Status</TableHead>\n            <TableHead className=\"text-right\">Balance</TableHead>\n          </TableRow>\n        </TableHeader>\n        <TableBody className=\"[&_td:first-child]:rounded-l-lg [&_td:last-child]:rounded-r-lg\">\n          {items.map((item) => (\n            <TableRow\n              key={item.id}\n              className=\"*:border-border hover:bg-transparent [&>:not(:last-child)]:border-r\"\n            >\n              <TableCell className=\"font-medium\">{item.name}</TableCell>\n              <TableCell>{item.email}</TableCell>\n              <TableCell>{item.location}</TableCell>\n              <TableCell>{item.status}</TableCell>\n              <TableCell className=\"text-right\">{item.balance}</TableCell>\n            </TableRow>\n          ))}\n        </TableBody>\n      </Table>\n      <p className=\"text-muted-foreground mt-4 text-center text-sm\">Table with vertical lines</p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/table/table-05.vue",
          "target": "components/ui/table-05.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Table } from '@timui/vue';\nimport { TableBody } from '@timui/vue';\nimport { TableCell } from '@timui/vue';\nimport { TableHead } from '@timui/vue';\nimport { TableHeader } from '@timui/vue';\nimport { TableRow } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: '1',\n    name: 'Alex Thompson',\n    email: 'alex.t@company.com',\n    location: 'San Francisco, US',\n    status: 'Active',\n    balance: '$1,250.00',\n  },\n  {\n    id: '2',\n    name: 'Sarah Chen',\n    email: 'sarah.c@company.com',\n    location: 'Singapore',\n    status: 'Active',\n    balance: '$600.00',\n  },\n  {\n    id: '3',\n    name: 'James Wilson',\n    email: 'j.wilson@company.com',\n    location: 'London, UK',\n    status: 'Inactive',\n    balance: '$650.00',\n  },\n  {\n    id: '4',\n    name: 'Maria Garcia',\n    email: 'm.garcia@company.com',\n    location: 'Madrid, Spain',\n    status: 'Active',\n    balance: '$0.00',\n  },\n  {\n    id: '5',\n    name: 'David Kim',\n    email: 'd.kim@company.com',\n    location: 'Seoul, KR',\n    status: 'Active',\n    balance: '-$1,000.00',\n  },\n]\n\n</script>\n\n<template>\n  <div><Table><TableHeader class=\"bg-transparent\"><TableRow class=\"*:border-border hover:bg-transparent [&>:not(:last-child)]:border-r\"><TableHead>Name</TableHead><TableHead>Email</TableHead><TableHead>Location</TableHead><TableHead>Status</TableHead><TableHead class=\"text-right\">Balance</TableHead></TableRow></TableHeader><TableBody class=\"[&_td:first-child]:rounded-l-lg [&_td:last-child]:rounded-r-lg\"><TableRow v-for=\"(item, index) in items\" :key=\"item.id\" class=\"*:border-border hover:bg-transparent [&>:not(:last-child)]:border-r\"><TableCell class=\"font-medium\">{{ item.name }}</TableCell><TableCell>{{ item.email }}</TableCell><TableCell>{{ item.location }}</TableCell><TableCell>{{ item.status }}</TableCell><TableCell class=\"text-right\">{{ item.balance }}</TableCell></TableRow></TableBody></Table><p class=\"text-muted-foreground mt-4 text-center text-sm\">Table with vertical lines</p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/table/table-05.html",
          "target": "components/ui/table-05.html",
          "type": "registry:component",
          "content": "<template>\n  <div><Table><TableHeader class=\"bg-transparent\"><TableRow class=\"*:border-border hover:bg-transparent [&>:not(:last-child)]:border-r\"><TableHead>Name</TableHead><TableHead>Email</TableHead><TableHead>Location</TableHead><TableHead>Status</TableHead><TableHead class=\"text-right\">Balance</TableHead></TableRow></TableHeader><TableBody class=\"[&_td:first-child]:rounded-l-lg [&_td:last-child]:rounded-r-lg\"><!-- Loop items -->\n<TableRow key=\"${item.id}\" class=\"*:border-border hover:bg-transparent [&>:not(:last-child)]:border-r\"><TableCell class=\"font-medium\">${item.name}</TableCell><TableCell>${item.email}</TableCell><TableCell>${item.location}</TableCell><TableCell>${item.status}</TableCell><TableCell class=\"text-right\">${item.balance}</TableCell></TableRow>\n<!-- End Loop --></TableBody></Table><p class=\"text-muted-foreground mt-4 text-center text-sm\">Table with vertical lines</p></div>\n</template>"
        },
        {
          "path": "registry/default/components/table/table-05.wxml",
          "target": "components/ui/table-05/table-05.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><table><tableheader class=\"bg-transparent\"><tablerow class=\"*:border-border hover:bg-transparent [&>:not(:last-child)]:border-r\"><tablehead>Name</tablehead><tablehead>Email</tablehead><tablehead>Location</tablehead><tablehead>Status</tablehead><tablehead class=\"text-right\">Balance</tablehead></tablerow></tableheader><tablebody class=\"[&_td:first-child]:rounded-l-lg [&_td:last-child]:rounded-r-lg\"><tablerow wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{item.id}}\" class=\"*:border-border hover:bg-transparent [&>:not(:last-child)]:border-r\"><tablecell class=\"font-medium\">{{ item.name }}</tablecell><tablecell>{{ item.email }}</tablecell><tablecell>{{ item.location }}</tablecell><tablecell>{{ item.status }}</tablecell><tablecell class=\"text-right\">{{ item.balance }}</tablecell></tablerow></tablebody></table><text class=\"text-muted-foreground mt-4 text-center text-sm\">Table with vertical lines</text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "table"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "table-05",
          "group": "table",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "table-05",
              "path": "registry/default/components/table/table-05.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "table-05",
              "path": "registry/default/components/table/table-05.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "table-05",
              "path": "registry/default/components/table/table-05.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "table-05",
              "path": "registry/default/components/table/table-05.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tables",
        "title": "Table · Interactive State"
      },
      "categories": [
        "tables",
        "table"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "table-06",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/table.json"
      ],
      "files": [
        {
          "path": "registry/default/components/table/table-06.tsx",
          "type": "registry:component",
          "target": "components/ui/table-06.tsx",
          "content": "import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@timui/react'\n\nconst programmingLanguages = [\n  {\n    id: '1',\n    name: 'JavaScript',\n    releaseYear: '1995',\n    developer: 'Brendan Eich',\n    typing: 'Dynamic',\n    paradigm: 'Multi-paradigm',\n    extension: '.js',\n    latestVersion: 'ES2021',\n    popularity: 'High',\n  },\n  {\n    id: '2',\n    name: 'Python',\n    releaseYear: '1991',\n    developer: 'Guido van Rossum',\n    typing: 'Dynamic',\n    paradigm: 'Multi-paradigm',\n    extension: '.py',\n    latestVersion: '3.10',\n    popularity: 'High',\n  },\n  {\n    id: '3',\n    name: 'Java',\n    releaseYear: '1995',\n    developer: 'James Gosling',\n    typing: 'Static',\n    paradigm: 'Object-oriented',\n    extension: '.java',\n    latestVersion: '17',\n    popularity: 'High',\n  },\n  {\n    id: '4',\n    name: 'C++',\n    releaseYear: '1985',\n    developer: 'Bjarne Stroustrup',\n    typing: 'Static',\n    paradigm: 'Multi-paradigm',\n    extension: '.cpp',\n    latestVersion: 'C++20',\n    popularity: 'High',\n  },\n  {\n    id: '5',\n    name: 'Ruby',\n    releaseYear: '1995',\n    developer: 'Yukihiro Matsumoto',\n    typing: 'Dynamic',\n    paradigm: 'Multi-paradigm',\n    extension: '.rb',\n    latestVersion: '3.0',\n    popularity: 'Low',\n  },\n]\n\nexport default function Component() {\n  return (\n    <div>\n      <div className=\"bg-background overflow-hidden rounded-md border\">\n        <Table>\n          <TableHeader>\n            <TableRow className=\"bg-muted/50\">\n              <TableHead className=\"h-9 py-2\">Name</TableHead>\n              <TableHead className=\"h-9 py-2\">Release Year</TableHead>\n              <TableHead className=\"h-9 py-2\">Developer</TableHead>\n              <TableHead className=\"h-9 py-2\">Typing</TableHead>\n              <TableHead className=\"h-9 py-2\">Paradigm</TableHead>\n              <TableHead className=\"h-9 py-2\">Extension</TableHead>\n              <TableHead className=\"h-9 py-2\">Latest Version</TableHead>\n              <TableHead className=\"h-9 py-2\">Popularity</TableHead>\n            </TableRow>\n          </TableHeader>\n          <TableBody>\n            {programmingLanguages.map((language) => (\n              <TableRow key={language.id}>\n                <TableCell className=\"py-2 font-medium\">{language.name}</TableCell>\n                <TableCell className=\"py-2\">{language.releaseYear}</TableCell>\n                <TableCell className=\"py-2\">{language.developer}</TableCell>\n                <TableCell className=\"py-2\">{language.typing}</TableCell>\n                <TableCell className=\"py-2\">{language.paradigm}</TableCell>\n                <TableCell className=\"py-2\">{language.extension}</TableCell>\n                <TableCell className=\"py-2\">{language.latestVersion}</TableCell>\n                <TableCell className=\"py-2\">{language.popularity}</TableCell>\n              </TableRow>\n            ))}\n          </TableBody>\n        </Table>\n      </div>\n      <p className=\"text-muted-foreground mt-4 text-center text-sm\">Dense table</p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/table/table-06.vue",
          "target": "components/ui/table-06.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Table } from '@timui/vue';\nimport { TableBody } from '@timui/vue';\nimport { TableCell } from '@timui/vue';\nimport { TableHead } from '@timui/vue';\nimport { TableHeader } from '@timui/vue';\nimport { TableRow } from '@timui/vue';\n\n\n\n\n\nconst programmingLanguages = [\n  {\n    id: '1',\n    name: 'JavaScript',\n    releaseYear: '1995',\n    developer: 'Brendan Eich',\n    typing: 'Dynamic',\n    paradigm: 'Multi-paradigm',\n    extension: '.js',\n    latestVersion: 'ES2021',\n    popularity: 'High',\n  },\n  {\n    id: '2',\n    name: 'Python',\n    releaseYear: '1991',\n    developer: 'Guido van Rossum',\n    typing: 'Dynamic',\n    paradigm: 'Multi-paradigm',\n    extension: '.py',\n    latestVersion: '3.10',\n    popularity: 'High',\n  },\n  {\n    id: '3',\n    name: 'Java',\n    releaseYear: '1995',\n    developer: 'James Gosling',\n    typing: 'Static',\n    paradigm: 'Object-oriented',\n    extension: '.java',\n    latestVersion: '17',\n    popularity: 'High',\n  },\n  {\n    id: '4',\n    name: 'C++',\n    releaseYear: '1985',\n    developer: 'Bjarne Stroustrup',\n    typing: 'Static',\n    paradigm: 'Multi-paradigm',\n    extension: '.cpp',\n    latestVersion: 'C++20',\n    popularity: 'High',\n  },\n  {\n    id: '5',\n    name: 'Ruby',\n    releaseYear: '1995',\n    developer: 'Yukihiro Matsumoto',\n    typing: 'Dynamic',\n    paradigm: 'Multi-paradigm',\n    extension: '.rb',\n    latestVersion: '3.0',\n    popularity: 'Low',\n  },\n]\n\n</script>\n\n<template>\n  <div><div class=\"bg-background overflow-hidden rounded-md border\"><Table><TableHeader><TableRow class=\"bg-muted/50\"><TableHead class=\"h-9 py-2\">Name</TableHead><TableHead class=\"h-9 py-2\">Release Year</TableHead><TableHead class=\"h-9 py-2\">Developer</TableHead><TableHead class=\"h-9 py-2\">Typing</TableHead><TableHead class=\"h-9 py-2\">Paradigm</TableHead><TableHead class=\"h-9 py-2\">Extension</TableHead><TableHead class=\"h-9 py-2\">Latest Version</TableHead><TableHead class=\"h-9 py-2\">Popularity</TableHead></TableRow></TableHeader><TableBody><TableRow v-for=\"(language, index) in programmingLanguages\" :key=\"language.id\"><TableCell class=\"py-2 font-medium\">{{ language.name }}</TableCell><TableCell class=\"py-2\">{{ language.releaseYear }}</TableCell><TableCell class=\"py-2\">{{ language.developer }}</TableCell><TableCell class=\"py-2\">{{ language.typing }}</TableCell><TableCell class=\"py-2\">{{ language.paradigm }}</TableCell><TableCell class=\"py-2\">{{ language.extension }}</TableCell><TableCell class=\"py-2\">{{ language.latestVersion }}</TableCell><TableCell class=\"py-2\">{{ language.popularity }}</TableCell></TableRow></TableBody></Table></div><p class=\"text-muted-foreground mt-4 text-center text-sm\">Dense table</p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/table/table-06.html",
          "target": "components/ui/table-06.html",
          "type": "registry:component",
          "content": "<template>\n  <div><div class=\"bg-background overflow-hidden rounded-md border\"><Table><TableHeader><TableRow class=\"bg-muted/50\"><TableHead class=\"h-9 py-2\">Name</TableHead><TableHead class=\"h-9 py-2\">Release Year</TableHead><TableHead class=\"h-9 py-2\">Developer</TableHead><TableHead class=\"h-9 py-2\">Typing</TableHead><TableHead class=\"h-9 py-2\">Paradigm</TableHead><TableHead class=\"h-9 py-2\">Extension</TableHead><TableHead class=\"h-9 py-2\">Latest Version</TableHead><TableHead class=\"h-9 py-2\">Popularity</TableHead></TableRow></TableHeader><TableBody><!-- Loop programmingLanguages -->\n<TableRow key=\"${language.id}\"><TableCell class=\"py-2 font-medium\">${language.name}</TableCell><TableCell class=\"py-2\">${language.releaseYear}</TableCell><TableCell class=\"py-2\">${language.developer}</TableCell><TableCell class=\"py-2\">${language.typing}</TableCell><TableCell class=\"py-2\">${language.paradigm}</TableCell><TableCell class=\"py-2\">${language.extension}</TableCell><TableCell class=\"py-2\">${language.latestVersion}</TableCell><TableCell class=\"py-2\">${language.popularity}</TableCell></TableRow>\n<!-- End Loop --></TableBody></Table></div><p class=\"text-muted-foreground mt-4 text-center text-sm\">Dense table</p></div>\n</template>"
        },
        {
          "path": "registry/default/components/table/table-06.wxml",
          "target": "components/ui/table-06/table-06.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><view class=\"bg-background overflow-hidden rounded-md border\"><table><tableheader><tablerow class=\"bg-muted/50\"><tablehead class=\"h-9 py-2\">Name</tablehead><tablehead class=\"h-9 py-2\">Release Year</tablehead><tablehead class=\"h-9 py-2\">Developer</tablehead><tablehead class=\"h-9 py-2\">Typing</tablehead><tablehead class=\"h-9 py-2\">Paradigm</tablehead><tablehead class=\"h-9 py-2\">Extension</tablehead><tablehead class=\"h-9 py-2\">Latest Version</tablehead><tablehead class=\"h-9 py-2\">Popularity</tablehead></tablerow></tableheader><tablebody><tablerow wx:for=\"{{programmingLanguages}}\" wx:for-item=\"language\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{language.id}}\"><tablecell class=\"py-2 font-medium\">{{ language.name }}</tablecell><tablecell class=\"py-2\">{{ language.releaseYear }}</tablecell><tablecell class=\"py-2\">{{ language.developer }}</tablecell><tablecell class=\"py-2\">{{ language.typing }}</tablecell><tablecell class=\"py-2\">{{ language.paradigm }}</tablecell><tablecell class=\"py-2\">{{ language.extension }}</tablecell><tablecell class=\"py-2\">{{ language.latestVersion }}</tablecell><tablecell class=\"py-2\">{{ language.popularity }}</tablecell></tablerow></tablebody></table></view><text class=\"text-muted-foreground mt-4 text-center text-sm\">Dense table</text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "table"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "table-06",
          "group": "table",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "table-06",
              "path": "registry/default/components/table/table-06.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "table-06",
              "path": "registry/default/components/table/table-06.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "table-06",
              "path": "registry/default/components/table/table-06.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "table-06",
              "path": "registry/default/components/table/table-06.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tables",
        "title": "Table · Outlined Style"
      },
      "categories": [
        "tables",
        "table"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "table-07",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/checkbox.json",
        "https://ui.timkit.cn/r/table.json"
      ],
      "files": [
        {
          "path": "registry/default/components/table/table-07.tsx",
          "type": "registry:component",
          "target": "components/ui/table-07.tsx",
          "content": "import { useState } from 'react'\nimport {\n  Checkbox,\n  Table,\n  TableBody,\n  TableCell,\n  TableFooter,\n  TableHead,\n  TableHeader,\n  TableRow,\n} from '@timui/react'\n\nconst items = [\n  {\n    id: '1',\n    name: 'Alex Thompson',\n    email: 'alex.t@company.com',\n    location: 'San Francisco, US',\n    status: 'Active',\n    balance: '$1,250.00',\n  },\n  {\n    id: '2',\n    name: 'Sarah Chen',\n    email: 'sarah.c@company.com',\n    location: 'Singapore',\n    status: 'Active',\n    balance: '$600.00',\n  },\n  {\n    id: '3',\n    name: 'James Wilson',\n    email: 'j.wilson@company.com',\n    location: 'London, UK',\n    status: 'Inactive',\n    balance: '$650.00',\n  },\n  {\n    id: '4',\n    name: 'Maria Garcia',\n    email: 'm.garcia@company.com',\n    location: 'Madrid, Spain',\n    status: 'Active',\n    balance: '$0.00',\n  },\n  {\n    id: '5',\n    name: 'David Kim',\n    email: 'd.kim@company.com',\n    location: 'Seoul, KR',\n    status: 'Active',\n    balance: '-$1,000.00',\n  },\n]\n\nexport default function Component() {\n  const [selectedRows, setSelectedRows] = useState<Record<string, boolean>>({})\n  const allSelected = items.length > 0 && items.every((item) => selectedRows[item.id])\n  const someSelected = items.some((item) => selectedRows[item.id]) && !allSelected\n\n  const toChecked = (value: unknown) =>\n    !!((value as { detail?: { checked?: boolean } })?.detail?.checked ?? value)\n  return (\n    <div>\n      <Table>\n        <TableHeader>\n          <TableRow className=\"hover:bg-transparent\">\n            <TableHead>\n              <Checkbox\n                checked={allSelected || (someSelected && 'indeterminate')}\n                onCheckedChange={(value) => {\n                  const checked = toChecked(value)\n                  setSelectedRows(Object.fromEntries(items.map((item) => [item.id, checked])))\n                }}\n                onClick={() => {\n                  const next = !allSelected\n                  setSelectedRows(Object.fromEntries(items.map((item) => [item.id, next])))\n                }}\n                aria-label=\"Select all rows\"\n              />\n            </TableHead>\n            <TableHead>Name</TableHead>\n            <TableHead>Email</TableHead>\n            <TableHead>Location</TableHead>\n            <TableHead>Status</TableHead>\n            <TableHead className=\"text-right\">Balance</TableHead>\n          </TableRow>\n        </TableHeader>\n        <TableBody>\n          {items.map((item) => (\n            <TableRow\n              key={item.id}\n              data-state={selectedRows[item.id] ? 'selected' : undefined}\n              className=\"has-data-[state=checked]:bg-muted/50\"\n            >\n              <TableCell>\n                <Checkbox\n                  id={`table-checkbox-${item.id}`}\n                  checked={!!selectedRows[item.id]}\n                  onCheckedChange={(value) => {\n                    const checked = toChecked(value)\n                    setSelectedRows((prev) => ({ ...prev, [item.id]: checked }))\n                  }}\n                  onClick={() => {\n                    setSelectedRows((prev) => ({ ...prev, [item.id]: !prev[item.id] }))\n                  }}\n                  aria-label={`Select ${item.name}`}\n                />\n              </TableCell>\n              <TableCell className=\"font-medium\">{item.name}</TableCell>\n              <TableCell>{item.email}</TableCell>\n              <TableCell>{item.location}</TableCell>\n              <TableCell>{item.status}</TableCell>\n              <TableCell className=\"text-right\">{item.balance}</TableCell>\n            </TableRow>\n          ))}\n        </TableBody>\n        <TableFooter className=\"bg-transparent\">\n          <TableRow className=\"hover:bg-transparent\">\n            <TableCell colSpan={5}>Total</TableCell>\n            <TableCell className=\"text-right\">$2,500.00</TableCell>\n          </TableRow>\n        </TableFooter>\n      </Table>\n      <p className=\"text-muted-foreground mt-4 text-center text-sm\">Table with row selection</p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/table/table-07.vue",
          "target": "components/ui/table-07.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport { Checkbox } from '@timui/vue'\nimport { Table } from '@timui/vue'\nimport { TableBody } from '@timui/vue'\nimport { TableCell } from '@timui/vue'\nimport { TableFooter } from '@timui/vue'\nimport { TableHead } from '@timui/vue'\nimport { TableHeader } from '@timui/vue'\nimport { TableRow } from '@timui/vue'\n\nconst selectedRows = ref<Record<string, boolean>>({})\n\nconst items = [\n  {\n    id: '1',\n    name: 'Alex Thompson',\n    email: 'alex.t@company.com',\n    location: 'San Francisco, US',\n    status: 'Active',\n    balance: '$1,250.00',\n  },\n  {\n    id: '2',\n    name: 'Sarah Chen',\n    email: 'sarah.c@company.com',\n    location: 'Singapore',\n    status: 'Active',\n    balance: '$600.00',\n  },\n  {\n    id: '3',\n    name: 'James Wilson',\n    email: 'j.wilson@company.com',\n    location: 'London, UK',\n    status: 'Inactive',\n    balance: '$650.00',\n  },\n  {\n    id: '4',\n    name: 'Maria Garcia',\n    email: 'm.garcia@company.com',\n    location: 'Madrid, Spain',\n    status: 'Active',\n    balance: '$0.00',\n  },\n  {\n    id: '5',\n    name: 'David Kim',\n    email: 'd.kim@company.com',\n    location: 'Seoul, KR',\n    status: 'Active',\n    balance: '-$1,000.00',\n  },\n]\n\nconst allSelected = computed(\n  () => items.length > 0 && items.every((item) => !!selectedRows.value[item.id])\n)\n\nconst someSelected = computed(\n  () => items.some((item) => !!selectedRows.value[item.id]) && !allSelected.value\n)\n\nconst toChecked = (value: boolean | 'indeterminate') => value === true\n\nconst setAllRows = (checked: boolean) => {\n  selectedRows.value = Object.fromEntries(items.map((item) => [item.id, checked]))\n}\n\nconst onHeaderCheckedChange = (value: boolean | 'indeterminate') => {\n  setAllRows(toChecked(value))\n}\n\nconst onHeaderClick = () => {\n  setAllRows(!allSelected.value)\n}\n\nconst onRowCheckedChange = (id: string, value: boolean | 'indeterminate') => {\n  selectedRows.value = {\n    ...selectedRows.value,\n    [id]: toChecked(value),\n  }\n}\n\nconst onRowClick = (id: string) => {\n  selectedRows.value = {\n    ...selectedRows.value,\n    [id]: !selectedRows.value[id],\n  }\n}\n</script>\n\n<template>\n  <div>\n    <Table>\n      <TableHeader>\n        <TableRow class=\"hover:bg-transparent\">\n          <TableHead>\n            <Checkbox\n              :checked=\"allSelected ? true : someSelected ? 'indeterminate' : false\"\n              aria-label=\"Select all rows\"\n              @update:checked=\"onHeaderCheckedChange\"\n              @click=\"onHeaderClick\"\n            />\n          </TableHead>\n          <TableHead>Name</TableHead>\n          <TableHead>Email</TableHead>\n          <TableHead>Location</TableHead>\n          <TableHead>Status</TableHead>\n          <TableHead class=\"text-right\">Balance</TableHead>\n        </TableRow>\n      </TableHeader>\n      <TableBody>\n        <TableRow\n          v-for=\"item in items\"\n          :key=\"item.id\"\n          :data-state=\"selectedRows[item.id] ? 'selected' : undefined\"\n          class=\"has-data-[state=checked]:bg-muted/50\"\n        >\n          <TableCell>\n            <Checkbox\n              :id=\"`table-checkbox-${item.id}`\"\n              :checked=\"!!selectedRows[item.id]\"\n              :aria-label=\"`Select ${item.name}`\"\n              @update:checked=\"onRowCheckedChange(item.id, $event)\"\n              @click=\"onRowClick(item.id)\"\n            />\n          </TableCell>\n          <TableCell class=\"font-medium\">{{ item.name }}</TableCell>\n          <TableCell>{{ item.email }}</TableCell>\n          <TableCell>{{ item.location }}</TableCell>\n          <TableCell>{{ item.status }}</TableCell>\n          <TableCell class=\"text-right\">{{ item.balance }}</TableCell>\n        </TableRow>\n      </TableBody>\n      <TableFooter class=\"bg-transparent\">\n        <TableRow class=\"hover:bg-transparent\">\n          <TableCell :colSpan=\"5\">Total</TableCell>\n          <TableCell class=\"text-right\">$2,500.00</TableCell>\n        </TableRow>\n      </TableFooter>\n    </Table>\n    <p class=\"text-muted-foreground mt-4 text-center text-sm\">Table with row selection</p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/table/table-07.html",
          "target": "components/ui/table-07.html",
          "type": "registry:component",
          "content": "<template>\n  <div><Table><TableHeader><TableRow class=\"hover:bg-transparent\"><TableHead><Checkbox checked=\"${allSelected || (someSelected && 'indeterminate')}\" oncheckedchange=\"${(value) => {\n                  const checked = toChecked(value)\n                  setSelectedRows(Object.fromEntries(items.map((item) => [item.id, checked])))\n                }}\" on-click=\"${() => {\n                  const next = !allSelected\n                  setSelectedRows(Object.fromEntries(items.map((item) => [item.id, next])))\n                }}\" aria-label=\"Select all rows\" /></TableHead><TableHead>Name</TableHead><TableHead>Email</TableHead><TableHead>Location</TableHead><TableHead>Status</TableHead><TableHead class=\"text-right\">Balance</TableHead></TableRow></TableHeader><TableBody><!-- Loop items -->\n<TableRow key=\"${item.id}\" data-state=\"${selectedRows[item.id] ? 'selected' : undefined}\" class=\"has-data-[state=checked]:bg-muted/50\"><TableCell><Checkbox id=\"${`table-checkbox-${item.id}`}\" checked=\"${!!selectedRows[item.id]}\" oncheckedchange=\"${(value) => {\n                    const checked = toChecked(value)\n                    setSelectedRows((prev) => ({ ...prev, [item.id]: checked }))\n                  }}\" on-click=\"${() => {\n                    setSelectedRows((prev) => ({ ...prev, [item.id]: !prev[item.id] }))\n                  }}\" aria-label=\"${`Select ${item.name}`}\" /></TableCell><TableCell class=\"font-medium\">${item.name}</TableCell><TableCell>${item.email}</TableCell><TableCell>${item.location}</TableCell><TableCell>${item.status}</TableCell><TableCell class=\"text-right\">${item.balance}</TableCell></TableRow>\n<!-- End Loop --></TableBody><TableFooter class=\"bg-transparent\"><TableRow class=\"hover:bg-transparent\"><TableCell colspan=\"${5}\">Total</TableCell><TableCell class=\"text-right\">$2,500.00</TableCell></TableRow></TableFooter></Table><p class=\"text-muted-foreground mt-4 text-center text-sm\">Table with row selection</p></div>\n</template>"
        },
        {
          "path": "registry/default/components/table/table-07.wxml",
          "target": "components/ui/table-07/table-07.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><table><tableheader><tablerow class=\"hover:bg-transparent\"><tablehead><checkbox checked=\"{{allSelected || (someSelected && 'indeterminate')}}\" oncheckedchange=\"{{(value) => {\n                  const checked = toChecked(value)\n                  setSelectedRows(Object.fromEntries(items.map((item) => [item.id, checked])))\n                }}}\" bindtap=\"{\n                  const next = !allSelected\n                  setSelectedRows(Object.fromEntries(items.map((item) => [item.id, next])))\n                }\" aria-label=\"Select all rows\" /></tablehead><tablehead>Name</tablehead><tablehead>Email</tablehead><tablehead>Location</tablehead><tablehead>Status</tablehead><tablehead class=\"text-right\">Balance</tablehead></tablerow></tableheader><tablebody><tablerow wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{item.id}}\" data-state=\"{{selectedRows[item.id] ? 'selected' : undefined}}\" class=\"has-data-[state=checked]:bg-muted/50\"><tablecell><checkbox id=\"{{`table-checkbox-${item.id}`}}\" checked=\"{{!!selectedRows[item.id]}}\" oncheckedchange=\"{{(value) => {\n                    const checked = toChecked(value)\n                    setSelectedRows((prev) => ({ ...prev, [item.id]: checked }))\n                  }}}\" bindtap=\"{\n                    setSelectedRows((prev) => ({ ...prev, [item.id]: !prev[item.id] }))\n                  }\" aria-label=\"{{`Select ${item.name}`}}\" /></tablecell><tablecell class=\"font-medium\">{{ item.name }}</tablecell><tablecell>{{ item.email }}</tablecell><tablecell>{{ item.location }}</tablecell><tablecell>{{ item.status }}</tablecell><tablecell class=\"text-right\">{{ item.balance }}</tablecell></tablerow></tablebody><tablefooter class=\"bg-transparent\"><tablerow class=\"hover:bg-transparent\"><tablecell colspan=\"{{5}}\">Total</tablecell><tablecell class=\"text-right\">$2,500.00</tablecell></tablerow></tablefooter></table><text class=\"text-muted-foreground mt-4 text-center text-sm\">Table with row selection</text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "table",
          "checkbox"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "table-07",
          "group": "table",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "table-07",
              "path": "registry/default/components/table/table-07.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "table-07",
              "path": "registry/default/components/table/table-07.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "table-07",
              "path": "registry/default/components/table/table-07.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "table-07",
              "path": "registry/default/components/table/table-07.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tables",
        "title": "Table · Select all rows"
      },
      "categories": [
        "tables",
        "table"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "table-08",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/checkbox.json",
        "https://ui.timkit.cn/r/table.json"
      ],
      "files": [
        {
          "path": "registry/default/components/table/table-08.tsx",
          "type": "registry:component",
          "target": "components/ui/table-08.tsx",
          "content": "import { useState } from 'react'\nimport {\n  Checkbox,\n  Table,\n  TableBody,\n  TableCell,\n  TableFooter,\n  TableHead,\n  TableHeader,\n  TableRow,\n} from '@timui/react'\n\nconst items = [\n  {\n    id: '1',\n    name: 'Alex Thompson',\n    email: 'alex.t@company.com',\n    location: 'San Francisco, US',\n    status: 'Active',\n    balance: '$1,250.00',\n  },\n  {\n    id: '2',\n    name: 'Sarah Chen',\n    email: 'sarah.c@company.com',\n    location: 'Singapore',\n    status: 'Active',\n    balance: '$600.00',\n  },\n  {\n    id: '3',\n    name: 'James Wilson',\n    email: 'j.wilson@company.com',\n    location: 'London, UK',\n    status: 'Inactive',\n    balance: '$650.00',\n  },\n  {\n    id: '4',\n    name: 'Maria Garcia',\n    email: 'm.garcia@company.com',\n    location: 'Madrid, Spain',\n    status: 'Active',\n    balance: '$0.00',\n  },\n  {\n    id: '5',\n    name: 'David Kim',\n    email: 'd.kim@company.com',\n    location: 'Seoul, KR',\n    status: 'Active',\n    balance: '-$1,000.00',\n  },\n]\n\nexport default function Component() {\n  const [selectedRows, setSelectedRows] = useState<Record<string, boolean>>({})\n  const allSelected = items.length > 0 && items.every((item) => selectedRows[item.id])\n  const someSelected = items.some((item) => selectedRows[item.id]) && !allSelected\n\n  const toChecked = (value: unknown) =>\n    !!((value as { detail?: { checked?: boolean } })?.detail?.checked ?? value)\n  return (\n    <div>\n      <div className=\"bg-background overflow-hidden rounded-md border\">\n        <Table>\n          <TableHeader>\n            <TableRow className=\"hover:bg-transparent\">\n              <TableHead className=\"h-11\">\n                <Checkbox\n                  checked={allSelected || (someSelected && 'indeterminate')}\n                  onCheckedChange={(value) => {\n                    const checked = toChecked(value)\n                    setSelectedRows(Object.fromEntries(items.map((item) => [item.id, checked])))\n                  }}\n                  onClick={() => {\n                    const next = !allSelected\n                    setSelectedRows(Object.fromEntries(items.map((item) => [item.id, next])))\n                  }}\n                  aria-label=\"Select all rows\"\n                />\n              </TableHead>\n              <TableHead className=\"h-11\">Name</TableHead>\n              <TableHead className=\"h-11\">Email</TableHead>\n              <TableHead className=\"h-11\">Location</TableHead>\n              <TableHead className=\"h-11\">Status</TableHead>\n              <TableHead className=\"h-11 text-right\">Balance</TableHead>\n            </TableRow>\n          </TableHeader>\n          <TableBody>\n            {items.map((item) => (\n              <TableRow key={item.id} data-state={selectedRows[item.id] ? 'selected' : undefined}>\n                <TableCell>\n                  <Checkbox\n                    id={`table-checkbox-${item.id}`}\n                    checked={!!selectedRows[item.id]}\n                    onCheckedChange={(value) => {\n                      const checked = toChecked(value)\n                      setSelectedRows((prev) => ({ ...prev, [item.id]: checked }))\n                    }}\n                    onClick={() => {\n                      setSelectedRows((prev) => ({ ...prev, [item.id]: !prev[item.id] }))\n                    }}\n                    aria-label={`Select ${item.name}`}\n                  />\n                </TableCell>\n                <TableCell className=\"font-medium\">{item.name}</TableCell>\n                <TableCell>{item.email}</TableCell>\n                <TableCell>{item.location}</TableCell>\n                <TableCell>{item.status}</TableCell>\n                <TableCell className=\"text-right\">{item.balance}</TableCell>\n              </TableRow>\n            ))}\n          </TableBody>\n          <TableFooter className=\"bg-transparent\">\n            <TableRow className=\"hover:bg-transparent\">\n              <TableCell colSpan={5}>Total</TableCell>\n              <TableCell className=\"text-right\">$2,500.00</TableCell>\n            </TableRow>\n          </TableFooter>\n        </Table>\n      </div>\n      <p className=\"text-muted-foreground mt-4 text-center text-sm\">Card Table</p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/table/table-08.vue",
          "target": "components/ui/table-08.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport { Checkbox } from '@timui/vue'\nimport { Table } from '@timui/vue'\nimport { TableBody } from '@timui/vue'\nimport { TableCell } from '@timui/vue'\nimport { TableFooter } from '@timui/vue'\nimport { TableHead } from '@timui/vue'\nimport { TableHeader } from '@timui/vue'\nimport { TableRow } from '@timui/vue'\n\nconst selectedRows = ref<Record<string, boolean>>({})\n\nconst items = [\n  {\n    id: '1',\n    name: 'Alex Thompson',\n    email: 'alex.t@company.com',\n    location: 'San Francisco, US',\n    status: 'Active',\n    balance: '$1,250.00',\n  },\n  {\n    id: '2',\n    name: 'Sarah Chen',\n    email: 'sarah.c@company.com',\n    location: 'Singapore',\n    status: 'Active',\n    balance: '$600.00',\n  },\n  {\n    id: '3',\n    name: 'James Wilson',\n    email: 'j.wilson@company.com',\n    location: 'London, UK',\n    status: 'Inactive',\n    balance: '$650.00',\n  },\n  {\n    id: '4',\n    name: 'Maria Garcia',\n    email: 'm.garcia@company.com',\n    location: 'Madrid, Spain',\n    status: 'Active',\n    balance: '$0.00',\n  },\n  {\n    id: '5',\n    name: 'David Kim',\n    email: 'd.kim@company.com',\n    location: 'Seoul, KR',\n    status: 'Active',\n    balance: '-$1,000.00',\n  },\n]\n\nconst allSelected = computed(\n  () => items.length > 0 && items.every((item) => !!selectedRows.value[item.id])\n)\n\nconst someSelected = computed(\n  () => items.some((item) => !!selectedRows.value[item.id]) && !allSelected.value\n)\n\nconst toChecked = (value: boolean | 'indeterminate') => value === true\n\nconst setAllRows = (checked: boolean) => {\n  selectedRows.value = Object.fromEntries(items.map((item) => [item.id, checked]))\n}\n\nconst onHeaderCheckedChange = (value: boolean | 'indeterminate') => {\n  setAllRows(toChecked(value))\n}\n\nconst onHeaderClick = () => {\n  setAllRows(!allSelected.value)\n}\n\nconst onRowCheckedChange = (id: string, value: boolean | 'indeterminate') => {\n  selectedRows.value = {\n    ...selectedRows.value,\n    [id]: toChecked(value),\n  }\n}\n\nconst onRowClick = (id: string) => {\n  selectedRows.value = {\n    ...selectedRows.value,\n    [id]: !selectedRows.value[id],\n  }\n}\n</script>\n\n<template>\n  <div>\n    <div class=\"bg-background overflow-hidden rounded-md border\">\n      <Table>\n        <TableHeader>\n          <TableRow class=\"hover:bg-transparent\">\n            <TableHead class=\"h-11\">\n              <Checkbox\n                :checked=\"allSelected ? true : someSelected ? 'indeterminate' : false\"\n                aria-label=\"Select all rows\"\n                @update:checked=\"onHeaderCheckedChange\"\n                @click=\"onHeaderClick\"\n              />\n            </TableHead>\n            <TableHead class=\"h-11\">Name</TableHead>\n            <TableHead class=\"h-11\">Email</TableHead>\n            <TableHead class=\"h-11\">Location</TableHead>\n            <TableHead class=\"h-11\">Status</TableHead>\n            <TableHead class=\"h-11 text-right\">Balance</TableHead>\n          </TableRow>\n        </TableHeader>\n        <TableBody>\n          <TableRow\n            v-for=\"item in items\"\n            :key=\"item.id\"\n            :data-state=\"selectedRows[item.id] ? 'selected' : undefined\"\n          >\n            <TableCell>\n              <Checkbox\n                :id=\"`table-checkbox-${item.id}`\"\n                :checked=\"!!selectedRows[item.id]\"\n                :aria-label=\"`Select ${item.name}`\"\n                @update:checked=\"onRowCheckedChange(item.id, $event)\"\n                @click=\"onRowClick(item.id)\"\n              />\n            </TableCell>\n            <TableCell class=\"font-medium\">{{ item.name }}</TableCell>\n            <TableCell>{{ item.email }}</TableCell>\n            <TableCell>{{ item.location }}</TableCell>\n            <TableCell>{{ item.status }}</TableCell>\n            <TableCell class=\"text-right\">{{ item.balance }}</TableCell>\n          </TableRow>\n        </TableBody>\n        <TableFooter class=\"bg-transparent\">\n          <TableRow class=\"hover:bg-transparent\">\n            <TableCell :colSpan=\"5\">Total</TableCell>\n            <TableCell class=\"text-right\">$2,500.00</TableCell>\n          </TableRow>\n        </TableFooter>\n      </Table>\n    </div>\n    <p class=\"text-muted-foreground mt-4 text-center text-sm\">Card Table</p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/table/table-08.html",
          "target": "components/ui/table-08.html",
          "type": "registry:component",
          "content": "<template>\n  <div><div class=\"bg-background overflow-hidden rounded-md border\"><Table><TableHeader><TableRow class=\"hover:bg-transparent\"><TableHead class=\"h-11\"><Checkbox checked=\"${allSelected || (someSelected && 'indeterminate')}\" oncheckedchange=\"${(value) => {\n                    const checked = toChecked(value)\n                    setSelectedRows(Object.fromEntries(items.map((item) => [item.id, checked])))\n                  }}\" on-click=\"${() => {\n                    const next = !allSelected\n                    setSelectedRows(Object.fromEntries(items.map((item) => [item.id, next])))\n                  }}\" aria-label=\"Select all rows\" /></TableHead><TableHead class=\"h-11\">Name</TableHead><TableHead class=\"h-11\">Email</TableHead><TableHead class=\"h-11\">Location</TableHead><TableHead class=\"h-11\">Status</TableHead><TableHead class=\"h-11 text-right\">Balance</TableHead></TableRow></TableHeader><TableBody><!-- Loop items -->\n<TableRow key=\"${item.id}\" data-state=\"${selectedRows[item.id] ? 'selected' : undefined}\"><TableCell><Checkbox id=\"${`table-checkbox-${item.id}`}\" checked=\"${!!selectedRows[item.id]}\" oncheckedchange=\"${(value) => {\n                      const checked = toChecked(value)\n                      setSelectedRows((prev) => ({ ...prev, [item.id]: checked }))\n                    }}\" on-click=\"${() => {\n                      setSelectedRows((prev) => ({ ...prev, [item.id]: !prev[item.id] }))\n                    }}\" aria-label=\"${`Select ${item.name}`}\" /></TableCell><TableCell class=\"font-medium\">${item.name}</TableCell><TableCell>${item.email}</TableCell><TableCell>${item.location}</TableCell><TableCell>${item.status}</TableCell><TableCell class=\"text-right\">${item.balance}</TableCell></TableRow>\n<!-- End Loop --></TableBody><TableFooter class=\"bg-transparent\"><TableRow class=\"hover:bg-transparent\"><TableCell colspan=\"${5}\">Total</TableCell><TableCell class=\"text-right\">$2,500.00</TableCell></TableRow></TableFooter></Table></div><p class=\"text-muted-foreground mt-4 text-center text-sm\">Card Table</p></div>\n</template>"
        },
        {
          "path": "registry/default/components/table/table-08.wxml",
          "target": "components/ui/table-08/table-08.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><view class=\"bg-background overflow-hidden rounded-md border\"><table><tableheader><tablerow class=\"hover:bg-transparent\"><tablehead class=\"h-11\"><checkbox checked=\"{{allSelected || (someSelected && 'indeterminate')}}\" oncheckedchange=\"{{(value) => {\n                    const checked = toChecked(value)\n                    setSelectedRows(Object.fromEntries(items.map((item) => [item.id, checked])))\n                  }}}\" bindtap=\"{\n                    const next = !allSelected\n                    setSelectedRows(Object.fromEntries(items.map((item) => [item.id, next])))\n                  }\" aria-label=\"Select all rows\" /></tablehead><tablehead class=\"h-11\">Name</tablehead><tablehead class=\"h-11\">Email</tablehead><tablehead class=\"h-11\">Location</tablehead><tablehead class=\"h-11\">Status</tablehead><tablehead class=\"h-11 text-right\">Balance</tablehead></tablerow></tableheader><tablebody><tablerow wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{item.id}}\" data-state=\"{{selectedRows[item.id] ? 'selected' : undefined}}\"><tablecell><checkbox id=\"{{`table-checkbox-${item.id}`}}\" checked=\"{{!!selectedRows[item.id]}}\" oncheckedchange=\"{{(value) => {\n                      const checked = toChecked(value)\n                      setSelectedRows((prev) => ({ ...prev, [item.id]: checked }))\n                    }}}\" bindtap=\"{\n                      setSelectedRows((prev) => ({ ...prev, [item.id]: !prev[item.id] }))\n                    }\" aria-label=\"{{`Select ${item.name}`}}\" /></tablecell><tablecell class=\"font-medium\">{{ item.name }}</tablecell><tablecell>{{ item.email }}</tablecell><tablecell>{{ item.location }}</tablecell><tablecell>{{ item.status }}</tablecell><tablecell class=\"text-right\">{{ item.balance }}</tablecell></tablerow></tablebody><tablefooter class=\"bg-transparent\"><tablerow class=\"hover:bg-transparent\"><tablecell colspan=\"{{5}}\">Total</tablecell><tablecell class=\"text-right\">$2,500.00</tablecell></tablerow></tablefooter></table></view><text class=\"text-muted-foreground mt-4 text-center text-sm\">Card Table</text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "table",
          "checkbox",
          "card"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "table-08",
          "group": "table",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "table-08",
              "path": "registry/default/components/table/table-08.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "table-08",
              "path": "registry/default/components/table/table-08.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "table-08",
              "path": "registry/default/components/table/table-08.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "table-08",
              "path": "registry/default/components/table/table-08.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tables",
        "title": "Table · Select all rows"
      },
      "categories": [
        "tables",
        "table"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "table-09",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/table.json"
      ],
      "files": [
        {
          "path": "registry/default/components/table/table-09.tsx",
          "type": "registry:component",
          "target": "components/ui/table-09.tsx",
          "content": "import { Table, TableBody, TableCell, TableRow } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"mx-auto max-w-lg\">\n      <div className=\"bg-background overflow-hidden rounded-md border\">\n        <Table>\n          <TableBody>\n            <TableRow className=\"*:border-border hover:bg-transparent [&>:not(:last-child)]:border-r\">\n              <TableCell className=\"bg-muted/50 py-2 font-medium\">Name</TableCell>\n              <TableCell className=\"py-2\">David Kim</TableCell>\n            </TableRow>\n            <TableRow className=\"*:border-border hover:bg-transparent [&>:not(:last-child)]:border-r\">\n              <TableCell className=\"bg-muted/50 py-2 font-medium\">Email</TableCell>\n              <TableCell className=\"py-2\">d.kim@company.com</TableCell>\n            </TableRow>\n            <TableRow className=\"*:border-border hover:bg-transparent [&>:not(:last-child)]:border-r\">\n              <TableCell className=\"bg-muted/50 py-2 font-medium\">Location</TableCell>\n              <TableCell className=\"py-2\">Seoul, KR</TableCell>\n            </TableRow>\n            <TableRow className=\"*:border-border hover:bg-transparent [&>:not(:last-child)]:border-r\">\n              <TableCell className=\"bg-muted/50 py-2 font-medium\">Status</TableCell>\n              <TableCell className=\"py-2\">Active</TableCell>\n            </TableRow>\n            <TableRow className=\"*:border-border hover:bg-transparent [&>:not(:last-child)]:border-r\">\n              <TableCell className=\"bg-muted/50 py-2 font-medium\">Balance</TableCell>\n              <TableCell className=\"py-2\">$1,000.00</TableCell>\n            </TableRow>\n          </TableBody>\n        </Table>\n      </div>\n      <p className=\"text-muted-foreground mt-4 text-center text-sm\">Vertical table</p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/table/table-09.vue",
          "target": "components/ui/table-09.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Table } from '@timui/vue';\nimport { TableBody } from '@timui/vue';\nimport { TableCell } from '@timui/vue';\nimport { TableRow } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"mx-auto max-w-lg\"><div class=\"bg-background overflow-hidden rounded-md border\"><Table><TableBody><TableRow class=\"*:border-border hover:bg-transparent [&>:not(:last-child)]:border-r\"><TableCell class=\"bg-muted/50 py-2 font-medium\">Name</TableCell><TableCell class=\"py-2\">David Kim</TableCell></TableRow><TableRow class=\"*:border-border hover:bg-transparent [&>:not(:last-child)]:border-r\"><TableCell class=\"bg-muted/50 py-2 font-medium\">Email</TableCell><TableCell class=\"py-2\">d.kim@company.com</TableCell></TableRow><TableRow class=\"*:border-border hover:bg-transparent [&>:not(:last-child)]:border-r\"><TableCell class=\"bg-muted/50 py-2 font-medium\">Location</TableCell><TableCell class=\"py-2\">Seoul, KR</TableCell></TableRow><TableRow class=\"*:border-border hover:bg-transparent [&>:not(:last-child)]:border-r\"><TableCell class=\"bg-muted/50 py-2 font-medium\">Status</TableCell><TableCell class=\"py-2\">Active</TableCell></TableRow><TableRow class=\"*:border-border hover:bg-transparent [&>:not(:last-child)]:border-r\"><TableCell class=\"bg-muted/50 py-2 font-medium\">Balance</TableCell><TableCell class=\"py-2\">$1,000.00</TableCell></TableRow></TableBody></Table></div><p class=\"text-muted-foreground mt-4 text-center text-sm\">Vertical table</p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/table/table-09.html",
          "target": "components/ui/table-09.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"mx-auto max-w-lg\"><div class=\"bg-background overflow-hidden rounded-md border\"><Table><TableBody><TableRow class=\"*:border-border hover:bg-transparent [&>:not(:last-child)]:border-r\"><TableCell class=\"bg-muted/50 py-2 font-medium\">Name</TableCell><TableCell class=\"py-2\">David Kim</TableCell></TableRow><TableRow class=\"*:border-border hover:bg-transparent [&>:not(:last-child)]:border-r\"><TableCell class=\"bg-muted/50 py-2 font-medium\">Email</TableCell><TableCell class=\"py-2\">d.kim@company.com</TableCell></TableRow><TableRow class=\"*:border-border hover:bg-transparent [&>:not(:last-child)]:border-r\"><TableCell class=\"bg-muted/50 py-2 font-medium\">Location</TableCell><TableCell class=\"py-2\">Seoul, KR</TableCell></TableRow><TableRow class=\"*:border-border hover:bg-transparent [&>:not(:last-child)]:border-r\"><TableCell class=\"bg-muted/50 py-2 font-medium\">Status</TableCell><TableCell class=\"py-2\">Active</TableCell></TableRow><TableRow class=\"*:border-border hover:bg-transparent [&>:not(:last-child)]:border-r\"><TableCell class=\"bg-muted/50 py-2 font-medium\">Balance</TableCell><TableCell class=\"py-2\">$1,000.00</TableCell></TableRow></TableBody></Table></div><p class=\"text-muted-foreground mt-4 text-center text-sm\">Vertical table</p></div>\n</template>"
        },
        {
          "path": "registry/default/components/table/table-09.wxml",
          "target": "components/ui/table-09/table-09.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"mx-auto max-w-lg\"><view class=\"bg-background overflow-hidden rounded-md border\"><table><tablebody><tablerow class=\"*:border-border hover:bg-transparent [&>:not(:last-child)]:border-r\"><tablecell class=\"bg-muted/50 py-2 font-medium\">Name</tablecell><tablecell class=\"py-2\">David Kim</tablecell></tablerow><tablerow class=\"*:border-border hover:bg-transparent [&>:not(:last-child)]:border-r\"><tablecell class=\"bg-muted/50 py-2 font-medium\">Email</tablecell><tablecell class=\"py-2\">d.kim@company.com</tablecell></tablerow><tablerow class=\"*:border-border hover:bg-transparent [&>:not(:last-child)]:border-r\"><tablecell class=\"bg-muted/50 py-2 font-medium\">Location</tablecell><tablecell class=\"py-2\">Seoul, KR</tablecell></tablerow><tablerow class=\"*:border-border hover:bg-transparent [&>:not(:last-child)]:border-r\"><tablecell class=\"bg-muted/50 py-2 font-medium\">Status</tablecell><tablecell class=\"py-2\">Active</tablecell></tablerow><tablerow class=\"*:border-border hover:bg-transparent [&>:not(:last-child)]:border-r\"><tablecell class=\"bg-muted/50 py-2 font-medium\">Balance</tablecell><tablecell class=\"py-2\">$1,000.00</tablecell></tablerow></tablebody></table></view><text class=\"text-muted-foreground mt-4 text-center text-sm\">Vertical table</text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "table",
          "vertical table"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "table-09",
          "group": "table",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "table-09",
              "path": "registry/default/components/table/table-09.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "table-09",
              "path": "registry/default/components/table/table-09.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "table-09",
              "path": "registry/default/components/table/table-09.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "table-09",
              "path": "registry/default/components/table/table-09.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tables",
        "title": "Table · Interactive State"
      },
      "categories": [
        "tables",
        "table"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "table-10",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/table.json"
      ],
      "files": [
        {
          "path": "registry/default/components/table/table-10.tsx",
          "type": "registry:component",
          "target": "components/ui/table-10.tsx",
          "content": "import {\n  Table,\n  TableBody,\n  TableCell,\n  TableFooter,\n  TableHead,\n  TableHeader,\n  TableRow,\n} from '@timui/react'\n\nconst items = [\n  {\n    id: '1',\n    name: 'Alex Thompson',\n    email: 'alex.t@company.com',\n    location: 'San Francisco, US',\n    status: 'Active',\n    balance: '$1,250.00',\n  },\n  {\n    id: '2',\n    name: 'Sarah Chen',\n    email: 'sarah.c@company.com',\n    location: 'Singapore',\n    status: 'Active',\n    balance: '$600.00',\n  },\n  {\n    id: '3',\n    name: 'James Wilson',\n    email: 'j.wilson@company.com',\n    location: 'London, UK',\n    status: 'Inactive',\n    balance: '$650.00',\n  },\n  {\n    id: '4',\n    name: 'Maria Garcia',\n    email: 'm.garcia@company.com',\n    location: 'Madrid, Spain',\n    status: 'Active',\n    balance: '$0.00',\n  },\n  {\n    id: '5',\n    name: 'David Kim',\n    email: 'd.kim@company.com',\n    location: 'Seoul, KR',\n    status: 'Active',\n    balance: '-$1,000.00',\n  },\n  {\n    id: '6',\n    name: 'John Brown',\n    email: 'john.brown@company.com',\n    location: 'New York, US',\n    status: 'Active',\n    balance: '$1,500.00',\n  },\n  {\n    id: '7',\n    name: 'Jane Doe',\n    email: 'jane.doe@company.com',\n    location: 'Paris, FR',\n    status: 'Inactive',\n    balance: '$200.00',\n  },\n  {\n    id: '8',\n    name: 'Peter Smith',\n    email: 'peter.smith@company.com',\n    location: 'Berlin, DE',\n    status: 'Active',\n    balance: '$1,000.00',\n  },\n  {\n    id: '9',\n    name: 'Olivia Lee',\n    email: 'olivia.lee@company.com',\n    location: 'Tokyo, JP',\n    status: 'Active',\n    balance: '$500.00',\n  },\n  {\n    id: '10',\n    name: 'Liam Chen',\n    email: 'liam.chen@company.com',\n    location: 'Shanghai, CN',\n    status: 'Inactive',\n    balance: '$300.00',\n  },\n  {\n    id: '11',\n    name: 'Ethan Kim',\n    email: 'ethan.kim@company.com',\n    location: 'Busan, KR',\n    status: 'Active',\n    balance: '$800.00',\n  },\n  {\n    id: '12',\n    name: 'Ava Brown',\n    email: 'ava.brown@company.com',\n    location: 'London, UK',\n    status: 'Active',\n    balance: '$1,200.00',\n  },\n  {\n    id: '13',\n    name: 'Lily Lee',\n    email: 'lily.lee@company.com',\n    location: 'Seoul, KR',\n    status: 'Active',\n    balance: '$400.00',\n  },\n  {\n    id: '14',\n    name: 'Noah Smith',\n    email: 'noah.smith@company.com',\n    location: 'New York, US',\n    status: 'Inactive',\n    balance: '$600.00',\n  },\n  {\n    id: '15',\n    name: 'Eve Chen',\n    email: 'eve.chen@company.com',\n    location: 'Taipei, TW',\n    status: 'Active',\n    balance: '$1,800.00',\n  },\n]\n\nexport default function Component() {\n  return (\n    <div>\n      <div className=\"[&>div]:max-h-96\">\n        <Table className=\"[&_td]:border-border [&_th]:border-border border-separate border-spacing-0 [&_tfoot_td]:border-t [&_th]:border-b [&_tr]:border-none [&_tr:not(:last-child)_td]:border-b\">\n          <TableHeader className=\"bg-background/90 sticky top-0 z-10 backdrop-blur-xs\">\n            <TableRow className=\"hover:bg-transparent\">\n              <TableHead>Name</TableHead>\n              <TableHead>Email</TableHead>\n              <TableHead>Location</TableHead>\n              <TableHead>Status</TableHead>\n              <TableHead className=\"text-right\">Balance</TableHead>\n            </TableRow>\n          </TableHeader>\n          <TableBody>\n            {items.map((item) => (\n              <TableRow key={item.id}>\n                <TableCell className=\"font-medium\">{item.name}</TableCell>\n                <TableCell>{item.email}</TableCell>\n                <TableCell>{item.location}</TableCell>\n                <TableCell>{item.status}</TableCell>\n                <TableCell className=\"text-right\">{item.balance}</TableCell>\n              </TableRow>\n            ))}\n          </TableBody>\n          <TableFooter className=\"bg-transparent\">\n            <TableRow className=\"hover:bg-transparent\">\n              <TableCell colSpan={4}>Total</TableCell>\n              <TableCell className=\"text-right\">$2,500.00</TableCell>\n            </TableRow>\n          </TableFooter>\n        </Table>\n      </div>\n      <p className=\"text-muted-foreground mt-8 text-center text-sm\">Table with sticky header</p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/table/table-10.vue",
          "target": "components/ui/table-10.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Table } from '@timui/vue';\nimport { TableBody } from '@timui/vue';\nimport { TableCell } from '@timui/vue';\nimport { TableFooter } from '@timui/vue';\nimport { TableHead } from '@timui/vue';\nimport { TableHeader } from '@timui/vue';\nimport { TableRow } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: '1',\n    name: 'Alex Thompson',\n    email: 'alex.t@company.com',\n    location: 'San Francisco, US',\n    status: 'Active',\n    balance: '$1,250.00',\n  },\n  {\n    id: '2',\n    name: 'Sarah Chen',\n    email: 'sarah.c@company.com',\n    location: 'Singapore',\n    status: 'Active',\n    balance: '$600.00',\n  },\n  {\n    id: '3',\n    name: 'James Wilson',\n    email: 'j.wilson@company.com',\n    location: 'London, UK',\n    status: 'Inactive',\n    balance: '$650.00',\n  },\n  {\n    id: '4',\n    name: 'Maria Garcia',\n    email: 'm.garcia@company.com',\n    location: 'Madrid, Spain',\n    status: 'Active',\n    balance: '$0.00',\n  },\n  {\n    id: '5',\n    name: 'David Kim',\n    email: 'd.kim@company.com',\n    location: 'Seoul, KR',\n    status: 'Active',\n    balance: '-$1,000.00',\n  },\n  {\n    id: '6',\n    name: 'John Brown',\n    email: 'john.brown@company.com',\n    location: 'New York, US',\n    status: 'Active',\n    balance: '$1,500.00',\n  },\n  {\n    id: '7',\n    name: 'Jane Doe',\n    email: 'jane.doe@company.com',\n    location: 'Paris, FR',\n    status: 'Inactive',\n    balance: '$200.00',\n  },\n  {\n    id: '8',\n    name: 'Peter Smith',\n    email: 'peter.smith@company.com',\n    location: 'Berlin, DE',\n    status: 'Active',\n    balance: '$1,000.00',\n  },\n  {\n    id: '9',\n    name: 'Olivia Lee',\n    email: 'olivia.lee@company.com',\n    location: 'Tokyo, JP',\n    status: 'Active',\n    balance: '$500.00',\n  },\n  {\n    id: '10',\n    name: 'Liam Chen',\n    email: 'liam.chen@company.com',\n    location: 'Shanghai, CN',\n    status: 'Inactive',\n    balance: '$300.00',\n  },\n  {\n    id: '11',\n    name: 'Ethan Kim',\n    email: 'ethan.kim@company.com',\n    location: 'Busan, KR',\n    status: 'Active',\n    balance: '$800.00',\n  },\n  {\n    id: '12',\n    name: 'Ava Brown',\n    email: 'ava.brown@company.com',\n    location: 'London, UK',\n    status: 'Active',\n    balance: '$1,200.00',\n  },\n  {\n    id: '13',\n    name: 'Lily Lee',\n    email: 'lily.lee@company.com',\n    location: 'Seoul, KR',\n    status: 'Active',\n    balance: '$400.00',\n  },\n  {\n    id: '14',\n    name: 'Noah Smith',\n    email: 'noah.smith@company.com',\n    location: 'New York, US',\n    status: 'Inactive',\n    balance: '$600.00',\n  },\n  {\n    id: '15',\n    name: 'Eve Chen',\n    email: 'eve.chen@company.com',\n    location: 'Taipei, TW',\n    status: 'Active',\n    balance: '$1,800.00',\n  },\n]\n\n</script>\n\n<template>\n  <div><div class=\"[&>div]:max-h-96\"><Table class=\"[&_td]:border-border [&_th]:border-border border-separate border-spacing-0 [&_tfoot_td]:border-t [&_th]:border-b [&_tr]:border-none [&_tr:not(:last-child)_td]:border-b\"><TableHeader class=\"bg-background/90 sticky top-0 z-10 backdrop-blur-xs\"><TableRow class=\"hover:bg-transparent\"><TableHead>Name</TableHead><TableHead>Email</TableHead><TableHead>Location</TableHead><TableHead>Status</TableHead><TableHead class=\"text-right\">Balance</TableHead></TableRow></TableHeader><TableBody><TableRow v-for=\"(item, index) in items\" :key=\"item.id\"><TableCell class=\"font-medium\">{{ item.name }}</TableCell><TableCell>{{ item.email }}</TableCell><TableCell>{{ item.location }}</TableCell><TableCell>{{ item.status }}</TableCell><TableCell class=\"text-right\">{{ item.balance }}</TableCell></TableRow></TableBody><TableFooter class=\"bg-transparent\"><TableRow class=\"hover:bg-transparent\"><TableCell :colSpan=\"4\">Total</TableCell><TableCell class=\"text-right\">$2,500.00</TableCell></TableRow></TableFooter></Table></div><p class=\"text-muted-foreground mt-8 text-center text-sm\">Table with sticky header</p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/table/table-10.html",
          "target": "components/ui/table-10.html",
          "type": "registry:component",
          "content": "<template>\n  <div><div class=\"[&>div]:max-h-96\"><Table class=\"[&_td]:border-border [&_th]:border-border border-separate border-spacing-0 [&_tfoot_td]:border-t [&_th]:border-b [&_tr]:border-none [&_tr:not(:last-child)_td]:border-b\"><TableHeader class=\"bg-background/90 sticky top-0 z-10 backdrop-blur-xs\"><TableRow class=\"hover:bg-transparent\"><TableHead>Name</TableHead><TableHead>Email</TableHead><TableHead>Location</TableHead><TableHead>Status</TableHead><TableHead class=\"text-right\">Balance</TableHead></TableRow></TableHeader><TableBody><!-- Loop items -->\n<TableRow key=\"${item.id}\"><TableCell class=\"font-medium\">${item.name}</TableCell><TableCell>${item.email}</TableCell><TableCell>${item.location}</TableCell><TableCell>${item.status}</TableCell><TableCell class=\"text-right\">${item.balance}</TableCell></TableRow>\n<!-- End Loop --></TableBody><TableFooter class=\"bg-transparent\"><TableRow class=\"hover:bg-transparent\"><TableCell colspan=\"${4}\">Total</TableCell><TableCell class=\"text-right\">$2,500.00</TableCell></TableRow></TableFooter></Table></div><p class=\"text-muted-foreground mt-8 text-center text-sm\">Table with sticky header</p></div>\n</template>"
        },
        {
          "path": "registry/default/components/table/table-10.wxml",
          "target": "components/ui/table-10/table-10.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><view class=\"[&>div]:max-h-96\"><table class=\"[&_td]:border-border [&_th]:border-border border-separate border-spacing-0 [&_tfoot_td]:border-t [&_th]:border-b [&_tr]:border-none [&_tr:not(:last-child)_td]:border-b\"><tableheader class=\"bg-background/90 sticky top-0 z-10 backdrop-blur-xs\"><tablerow class=\"hover:bg-transparent\"><tablehead>Name</tablehead><tablehead>Email</tablehead><tablehead>Location</tablehead><tablehead>Status</tablehead><tablehead class=\"text-right\">Balance</tablehead></tablerow></tableheader><tablebody><tablerow wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{item.id}}\"><tablecell class=\"font-medium\">{{ item.name }}</tablecell><tablecell>{{ item.email }}</tablecell><tablecell>{{ item.location }}</tablecell><tablecell>{{ item.status }}</tablecell><tablecell class=\"text-right\">{{ item.balance }}</tablecell></tablerow></tablebody><tablefooter class=\"bg-transparent\"><tablerow class=\"hover:bg-transparent\"><tablecell colspan=\"{{4}}\">Total</tablecell><tablecell class=\"text-right\">$2,500.00</tablecell></tablerow></tablefooter></table></view><text class=\"text-muted-foreground mt-8 text-center text-sm\">Table with sticky header</text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "table",
          "sticky"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "table-10",
          "group": "table",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "table-10",
              "path": "registry/default/components/table/table-10.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "table-10",
              "path": "registry/default/components/table/table-10.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "table-10",
              "path": "registry/default/components/table/table-10.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "table-10",
              "path": "registry/default/components/table/table-10.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tables",
        "title": "Table · Interactive State"
      },
      "categories": [
        "tables",
        "table"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "table-11",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/table.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/table/table-11.tsx",
          "type": "registry:component",
          "target": "components/ui/table-11.tsx",
          "content": "import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@timui/react'\nimport { CheckIcon, MonitorIcon, SmartphoneIcon, XIcon } from 'lucide-react'\n\nconst items = [\n  {\n    feature: 'scroll-timeline',\n    desktop: [\n      { name: 'Chrome', supported: true, version: '115' },\n      { name: 'Edge', supported: true, version: '115' },\n      { name: 'Firefox', supported: false, version: '111' },\n      { name: 'Opera', supported: true, version: '101' },\n      { name: 'Safari', supported: false, version: 'No' },\n    ],\n    mobile: [\n      { name: 'Chrome Android', supported: true, version: '115' },\n      { name: 'Firefox Android', supported: false, version: 'No' },\n      { name: 'Opera Android', supported: true, version: '77' },\n      { name: 'Safari iOS', supported: false, version: 'No' },\n      { name: 'Samsung Internet', supported: true, version: '23' },\n    ],\n  },\n  {\n    feature: 'view-timeline',\n    desktop: [\n      { name: 'Chrome', supported: true, version: '115' },\n      { name: 'Edge', supported: true, version: '115' },\n      { name: 'Firefox', supported: false, version: '114' },\n      { name: 'Opera', supported: true, version: '101' },\n      { name: 'Safari', supported: false, version: 'No' },\n    ],\n    mobile: [\n      { name: 'Chrome Android', supported: true, version: '115' },\n      { name: 'Firefox Android', supported: false, version: 'No' },\n      { name: 'Opera Android', supported: true, version: '77' },\n      { name: 'Safari iOS', supported: false, version: 'No' },\n      { name: 'Samsung Internet', supported: true, version: '23' },\n    ],\n  },\n  {\n    feature: 'font-size-adjust',\n    desktop: [\n      { name: 'Chrome', supported: true, version: '127' },\n      { name: 'Edge', supported: true, version: '127' },\n      { name: 'Firefox', supported: false, version: '3' },\n      { name: 'Opera', supported: true, version: '113' },\n      { name: 'Safari', supported: true, version: '16.4' },\n    ],\n    mobile: [\n      { name: 'Chrome Android', supported: true, version: '127' },\n      { name: 'Firefox Android', supported: true, version: '4' },\n      { name: 'Opera Android', supported: true, version: '84' },\n      { name: 'Safari iOS', supported: true, version: '16.4' },\n      { name: 'Samsung Internet', supported: false, version: 'No' },\n    ],\n  },\n]\n\nexport default function Component() {\n  return (\n    <Table>\n      <TableHeader>\n        <TableRow className=\"*:border-border border-y-0 hover:bg-transparent [&>:not(:last-child)]:border-r\">\n          <TableCell></TableCell>\n          <TableHead className=\"border-b text-center\" colSpan={5}>\n            <MonitorIcon className=\"inline-flex\" size={16} aria-hidden=\"true\" />\n            <span className=\"sr-only\">Desktop browsers</span>\n          </TableHead>\n          <TableHead className=\"border-b text-center\" colSpan={5}>\n            <SmartphoneIcon className=\"inline-flex\" size={16} aria-hidden=\"true\" />\n            <span className=\"sr-only\">Mobile browsers</span>\n          </TableHead>\n        </TableRow>\n      </TableHeader>\n      <TableHeader>\n        <TableRow className=\"*:border-border hover:bg-transparent [&>:not(:last-child)]:border-r\">\n          <TableCell></TableCell>\n          {items[0].desktop.map((browser) => (\n            <TableHead key={browser.name} className=\"text-foreground h-auto py-3 align-bottom\">\n              <span className=\"relative left-[calc(50%-.5rem)] block rotate-180 leading-4 whitespace-nowrap [text-orientation:sideways] [writing-mode:vertical-rl]\">\n                {browser.name}\n              </span>\n            </TableHead>\n          ))}\n          {items[0].mobile.map((browser) => (\n            <TableHead key={browser.name} className=\"text-foreground h-auto py-3 align-bottom\">\n              <span className=\"relative left-[calc(50%-.5rem)] block rotate-180 leading-4 whitespace-nowrap [text-orientation:sideways] [writing-mode:vertical-rl]\">\n                {browser.name}\n              </span>\n            </TableHead>\n          ))}\n        </TableRow>\n      </TableHeader>\n      <TableBody>\n        {items.map((item) => (\n          <TableRow key={item.feature} className=\"*:border-border [&>:not(:last-child)]:border-r\">\n            <TableHead className=\"text-foreground font-medium\">{item.feature}</TableHead>\n            {[...item.desktop, ...item.mobile].map((browser, index) => (\n              <TableCell key={`${browser.name}-${index}`} className=\"space-y-1 text-center\">\n                {browser.supported ? (\n                  <CheckIcon\n                    className=\"inline-flex stroke-emerald-600\"\n                    size={16}\n                    aria-hidden=\"true\"\n                  />\n                ) : (\n                  <XIcon className=\"inline-flex stroke-red-600\" size={16} aria-hidden=\"true\" />\n                )}\n                <span className=\"sr-only\">{browser.supported ? 'Supported' : 'Not supported'}</span>\n                <div className=\"text-muted-foreground text-xs font-medium\">{browser.version}</div>\n              </TableCell>\n            ))}\n          </TableRow>\n        ))}\n      </TableBody>\n    </Table>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/table/table-11.vue",
          "target": "components/ui/table-11.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { CheckIcon, MonitorIcon, SmartphoneIcon, XIcon } from 'lucide-vue-next';\nimport { Table } from '@timui/vue';\nimport { TableBody } from '@timui/vue';\nimport { TableCell } from '@timui/vue';\nimport { TableHead } from '@timui/vue';\nimport { TableHeader } from '@timui/vue';\nimport { TableRow } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    feature: 'scroll-timeline',\n    desktop: [\n      { name: 'Chrome', supported: true, version: '115' },\n      { name: 'Edge', supported: true, version: '115' },\n      { name: 'Firefox', supported: false, version: '111' },\n      { name: 'Opera', supported: true, version: '101' },\n      { name: 'Safari', supported: false, version: 'No' },\n    ],\n    mobile: [\n      { name: 'Chrome Android', supported: true, version: '115' },\n      { name: 'Firefox Android', supported: false, version: 'No' },\n      { name: 'Opera Android', supported: true, version: '77' },\n      { name: 'Safari iOS', supported: false, version: 'No' },\n      { name: 'Samsung Internet', supported: true, version: '23' },\n    ],\n  },\n  {\n    feature: 'view-timeline',\n    desktop: [\n      { name: 'Chrome', supported: true, version: '115' },\n      { name: 'Edge', supported: true, version: '115' },\n      { name: 'Firefox', supported: false, version: '114' },\n      { name: 'Opera', supported: true, version: '101' },\n      { name: 'Safari', supported: false, version: 'No' },\n    ],\n    mobile: [\n      { name: 'Chrome Android', supported: true, version: '115' },\n      { name: 'Firefox Android', supported: false, version: 'No' },\n      { name: 'Opera Android', supported: true, version: '77' },\n      { name: 'Safari iOS', supported: false, version: 'No' },\n      { name: 'Samsung Internet', supported: true, version: '23' },\n    ],\n  },\n  {\n    feature: 'font-size-adjust',\n    desktop: [\n      { name: 'Chrome', supported: true, version: '127' },\n      { name: 'Edge', supported: true, version: '127' },\n      { name: 'Firefox', supported: false, version: '3' },\n      { name: 'Opera', supported: true, version: '113' },\n      { name: 'Safari', supported: true, version: '16.4' },\n    ],\n    mobile: [\n      { name: 'Chrome Android', supported: true, version: '127' },\n      { name: 'Firefox Android', supported: true, version: '4' },\n      { name: 'Opera Android', supported: true, version: '84' },\n      { name: 'Safari iOS', supported: true, version: '16.4' },\n      { name: 'Samsung Internet', supported: false, version: 'No' },\n    ],\n  },\n]\n\n</script>\n\n<template>\n  <Table><TableHeader><TableRow class=\"*:border-border border-y-0 hover:bg-transparent [&>:not(:last-child)]:border-r\"><TableCell></TableCell><TableHead class=\"border-b text-center\" :colSpan=\"5\"><MonitorIcon class=\"inline-flex\" :size=\"16\" aria-hidden=\"true\" /><span class=\"sr-only\">Desktop browsers</span></TableHead><TableHead class=\"border-b text-center\" :colSpan=\"5\"><SmartphoneIcon class=\"inline-flex\" :size=\"16\" aria-hidden=\"true\" /><span class=\"sr-only\">Mobile browsers</span></TableHead></TableRow></TableHeader><TableHeader><TableRow class=\"*:border-border hover:bg-transparent [&>:not(:last-child)]:border-r\"><TableCell></TableCell><TableHead v-for=\"(browser, index) in items[0].desktop\" :key=\"browser.name\" class=\"text-foreground h-auto py-3 align-bottom\"><span class=\"relative left-[calc(50%-.5rem)] block rotate-180 leading-4 whitespace-nowrap [text-orientation:sideways] [writing-mode:vertical-rl]\">{{ browser.name }}</span></TableHead><TableHead v-for=\"(browser, index) in items[0].mobile\" :key=\"browser.name\" class=\"text-foreground h-auto py-3 align-bottom\"><span class=\"relative left-[calc(50%-.5rem)] block rotate-180 leading-4 whitespace-nowrap [text-orientation:sideways] [writing-mode:vertical-rl]\">{{ browser.name }}</span></TableHead></TableRow></TableHeader><TableBody><TableRow v-for=\"(item, index) in items\" :key=\"item.feature\" class=\"*:border-border [&>:not(:last-child)]:border-r\"><TableHead class=\"text-foreground font-medium\">{{ item.feature }}</TableHead><TableCell v-for=\"(browser, index) in [...item.desktop, ...item.mobile]\" :key=\"`${browser.name}-${index}`\" class=\"space-y-1 text-center\"><template v-if=\"browser.supported\">\n<CheckIcon class=\"inline-flex stroke-emerald-600\" :size=\"16\" aria-hidden=\"true\" />\n</template>\n<template v-else>\n<XIcon class=\"inline-flex stroke-red-600\" :size=\"16\" aria-hidden=\"true\" />\n</template><span class=\"sr-only\"><template v-if=\"browser.supported\">\n{{ 'Supported' }}\n</template>\n<template v-else>\n{{ 'Not supported' }}\n</template></span><div class=\"text-muted-foreground text-xs font-medium\">{{ browser.version }}</div></TableCell></TableRow></TableBody></Table>\n</template>\n"
        },
        {
          "path": "registry/default/components/table/table-11.html",
          "target": "components/ui/table-11.html",
          "type": "registry:component",
          "content": "<template>\n  <Table><TableHeader><TableRow class=\"*:border-border border-y-0 hover:bg-transparent [&>:not(:last-child)]:border-r\"><TableCell></TableCell><TableHead class=\"border-b text-center\" colspan=\"${5}\"><MonitorIcon class=\"inline-flex\" size=\"${16}\" aria-hidden=\"true\" /><span class=\"sr-only\">Desktop browsers</span></TableHead><TableHead class=\"border-b text-center\" colspan=\"${5}\"><SmartphoneIcon class=\"inline-flex\" size=\"${16}\" aria-hidden=\"true\" /><span class=\"sr-only\">Mobile browsers</span></TableHead></TableRow></TableHeader><TableHeader><TableRow class=\"*:border-border hover:bg-transparent [&>:not(:last-child)]:border-r\"><TableCell></TableCell><!-- Loop items[0].desktop -->\n<TableHead key=\"${browser.name}\" class=\"text-foreground h-auto py-3 align-bottom\"><span class=\"relative left-[calc(50%-.5rem)] block rotate-180 leading-4 whitespace-nowrap [text-orientation:sideways] [writing-mode:vertical-rl]\">${browser.name}</span></TableHead>\n<!-- End Loop --><!-- Loop items[0].mobile -->\n<TableHead key=\"${browser.name}\" class=\"text-foreground h-auto py-3 align-bottom\"><span class=\"relative left-[calc(50%-.5rem)] block rotate-180 leading-4 whitespace-nowrap [text-orientation:sideways] [writing-mode:vertical-rl]\">${browser.name}</span></TableHead>\n<!-- End Loop --></TableRow></TableHeader><TableBody><!-- Loop items -->\n<TableRow key=\"${item.feature}\" class=\"*:border-border [&>:not(:last-child)]:border-r\"><TableHead class=\"text-foreground font-medium\">${item.feature}</TableHead><!-- Loop [...item.desktop, ...item.mobile] -->\n<TableCell key=\"${`${browser.name}-${index}`}\" class=\"space-y-1 text-center\"><!-- if browser.supported -->\n<CheckIcon class=\"inline-flex stroke-emerald-600\" size=\"${16}\" aria-hidden=\"true\" />\n<!-- else -->\n<XIcon class=\"inline-flex stroke-red-600\" size=\"${16}\" aria-hidden=\"true\" />\n<!-- endif --><span class=\"sr-only\"><!-- if browser.supported -->\n${'Supported'}\n<!-- else -->\n${'Not supported'}\n<!-- endif --></span><div class=\"text-muted-foreground text-xs font-medium\">${browser.version}</div></TableCell>\n<!-- End Loop --></TableRow>\n<!-- End Loop --></TableBody></Table>\n</template>"
        },
        {
          "path": "registry/default/components/table/table-11.wxml",
          "target": "components/ui/table-11/table-11.wxml",
          "type": "registry:component",
          "content": "<view>\n  <table><tableheader><tablerow class=\"*:border-border border-y-0 hover:bg-transparent [&>:not(:last-child)]:border-r\"><tablecell></tablecell><tablehead class=\"border-b text-center\" colspan=\"{{5}}\"><monitoricon class=\"inline-flex\" size=\"{{16}}\" aria-hidden=\"true\" /><text class=\"sr-only\">Desktop browsers</text></tablehead><tablehead class=\"border-b text-center\" colspan=\"{{5}}\"><smartphoneicon class=\"inline-flex\" size=\"{{16}}\" aria-hidden=\"true\" /><text class=\"sr-only\">Mobile browsers</text></tablehead></tablerow></tableheader><tableheader><tablerow class=\"*:border-border hover:bg-transparent [&>:not(:last-child)]:border-r\"><tablecell></tablecell><tablehead wx:for=\"{{items[0].desktop}}\" wx:for-item=\"browser\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{browser.name}}\" class=\"text-foreground h-auto py-3 align-bottom\"><text class=\"relative left-[calc(50%-.5rem)] block rotate-180 leading-4 whitespace-nowrap [text-orientation:sideways] [writing-mode:vertical-rl]\">{{ browser.name }}</text></tablehead><tablehead wx:for=\"{{items[0].mobile}}\" wx:for-item=\"browser\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{browser.name}}\" class=\"text-foreground h-auto py-3 align-bottom\"><text class=\"relative left-[calc(50%-.5rem)] block rotate-180 leading-4 whitespace-nowrap [text-orientation:sideways] [writing-mode:vertical-rl]\">{{ browser.name }}</text></tablehead></tablerow></tableheader><tablebody><tablerow wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{item.feature}}\" class=\"*:border-border [&>:not(:last-child)]:border-r\"><tablehead class=\"text-foreground font-medium\">{{ item.feature }}</tablehead><tablecell wx:for=\"{{[...item.desktop, ...item.mobile]}}\" wx:for-item=\"browser\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{`${browser.name}-${index}`}}\" class=\"space-y-1 text-center\"><block wx:if=\"{{browser.supported}}\">\n<checkicon class=\"inline-flex stroke-emerald-600\" size=\"{{16}}\" aria-hidden=\"true\" />\n</block>\n<block wx:else>\n<xicon class=\"inline-flex stroke-red-600\" size=\"{{16}}\" aria-hidden=\"true\" />\n</block><text class=\"sr-only\"><block wx:if=\"{{browser.supported}}\">\n{{ 'Supported' }}\n</block>\n<block wx:else>\n{{ 'Not supported' }}\n</block></text><view class=\"text-muted-foreground text-xs font-medium\">{{ browser.version }}</view></tablecell></tablerow></tablebody></table>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "table"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "table-11",
          "group": "table",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "table-11",
              "path": "registry/default/components/table/table-11.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "table-11",
              "path": "registry/default/components/table/table-11.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "table-11",
              "path": "registry/default/components/table/table-11.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "table-11",
              "path": "registry/default/components/table/table-11.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tables",
        "title": "Table · Interactive State"
      },
      "categories": [
        "tables",
        "table"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "table-12",
      "type": "registry:component",
      "dependencies": [
        "@tanstack/react-table",
        "@timui/core",
        "@timui/react"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/badge.json",
        "https://ui.timkit.cn/r/checkbox.json",
        "https://ui.timkit.cn/r/table.json"
      ],
      "files": [
        {
          "path": "registry/default/components/table/table-12.tsx",
          "type": "registry:component",
          "target": "components/ui/table-12.tsx",
          "content": "'use client'\n\nimport { useEffect, useState } from 'react'\nimport {\n  ColumnDef,\n  flexRender,\n  getCoreRowModel,\n  RowSelectionState,\n  useReactTable,\n} from '@tanstack/react-table'\nimport { cn } from '@timui/core'\nimport {\n  Badge,\n  Checkbox,\n  Table,\n  TableBody,\n  TableCell,\n  TableFooter,\n  TableHead,\n  TableHeader,\n  TableRow,\n} from '@timui/react'\n\ntype Item = {\n  id: string\n  name: string\n  email: string\n  location: string\n  flag: string\n  status: 'Active' | 'Inactive' | 'Pending'\n  balance: number\n}\n\nconst columns: ColumnDef<Item>[] = [\n  {\n    id: 'select',\n    header: ({ table }) => (\n      <Checkbox\n        checked={\n          table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && 'indeterminate')\n        }\n        onCheckedChange={(value: any) =>\n          table.toggleAllPageRowsSelected(!!(value?.detail?.checked ?? value))\n        }\n        onClick={() => table.toggleAllPageRowsSelected(!table.getIsAllPageRowsSelected())}\n        aria-label=\"Select all\"\n      />\n    ),\n    cell: ({ row }) => (\n      <Checkbox\n        checked={row.getIsSelected()}\n        onCheckedChange={(value: any) => row.toggleSelected(!!(value?.detail?.checked ?? value))}\n        onClick={() => row.toggleSelected(!row.getIsSelected())}\n        aria-label=\"Select row\"\n      />\n    ),\n  },\n  {\n    header: 'Name',\n    accessorKey: 'name',\n    cell: ({ row }) => <div className=\"font-medium\">{row.getValue('name')}</div>,\n  },\n  {\n    header: 'Email',\n    accessorKey: 'email',\n  },\n  {\n    header: 'Location',\n    accessorKey: 'location',\n    cell: ({ row }) => (\n      <div>\n        <span className=\"text-lg leading-none\">{row.original.flag}</span> {row.getValue('location')}\n      </div>\n    ),\n  },\n  {\n    header: 'Status',\n    accessorKey: 'status',\n    cell: ({ row }) => (\n      <Badge\n        className={cn(\n          row.getValue('status') === 'Inactive' && 'bg-muted-foreground/60 text-primary-foreground'\n        )}\n      >\n        {row.getValue('status')}\n      </Badge>\n    ),\n  },\n  {\n    header: () => <div className=\"text-right\">Balance</div>,\n    accessorKey: 'balance',\n    cell: ({ row }) => {\n      const amount = parseFloat(row.getValue('balance'))\n      const formatted = new Intl.NumberFormat('en-US', {\n        style: 'currency',\n        currency: 'USD',\n      }).format(amount)\n      return <div className=\"text-right\">{formatted}</div>\n    },\n  },\n]\n\nexport default function Component() {\n  const [data, setData] = useState<Item[]>([])\n  const [rowSelection, setRowSelection] = useState<RowSelectionState>({})\n\n  useEffect(() => {\n    async function fetchPosts() {\n      const res = await fetch(\n        'https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/users-01_fertyx.json'\n      )\n      const data = await res.json()\n      setData(data.slice(0, 5)) // Limit to 5 items\n    }\n    fetchPosts()\n  }, [])\n\n  const table = useReactTable({\n    data,\n    columns,\n    getCoreRowModel: getCoreRowModel(),\n    enableRowSelection: true,\n    onRowSelectionChange: setRowSelection,\n    getRowId: (row) => row.id,\n    state: {\n      rowSelection,\n    },\n  })\n\n  return (\n    <div>\n      <Table>\n        <TableHeader>\n          {table.getHeaderGroups().map((headerGroup) => (\n            <TableRow key={headerGroup.id} className=\"hover:bg-transparent\">\n              {headerGroup.headers.map((header) => {\n                return (\n                  <TableHead key={header.id}>\n                    {header.isPlaceholder\n                      ? null\n                      : flexRender(header.column.columnDef.header, header.getContext())}\n                  </TableHead>\n                )\n              })}\n            </TableRow>\n          ))}\n        </TableHeader>\n        <TableBody>\n          {table.getRowModel().rows?.length ? (\n            table.getRowModel().rows.map((row) => (\n              <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>\n                {row.getVisibleCells().map((cell) => (\n                  <TableCell key={cell.id}>\n                    {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                  </TableCell>\n                ))}\n              </TableRow>\n            ))\n          ) : (\n            <TableRow>\n              <TableCell colSpan={columns.length} className=\"h-24 text-center\">\n                No results.\n              </TableCell>\n            </TableRow>\n          )}\n        </TableBody>\n        <TableFooter className=\"bg-transparent\">\n          <TableRow className=\"hover:bg-transparent\">\n            <TableCell colSpan={5}>Total</TableCell>\n            <TableCell className=\"text-right\">\n              {new Intl.NumberFormat('en-US', {\n                style: 'currency',\n                currency: 'USD',\n              }).format(data.reduce((total, item) => total + item.balance, 0))}\n            </TableCell>\n          </TableRow>\n        </TableFooter>\n      </Table>\n      <p className=\"text-muted-foreground mt-4 text-center text-sm\">\n        Basic data table made with{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://tanstack.com/table\"\n          target=\"_blank\"\n          rel=\"noopener noreferrer\"\n        >\n          TanStack Table\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/table/table-12.vue",
          "target": "components/ui/table-12.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, reactive } from 'vue'\nimport { cn } from '@timui/core'\nimport { Badge } from '@timui/vue'\nimport { Checkbox } from '@timui/vue'\nimport { Table } from '@timui/vue'\nimport { TableBody } from '@timui/vue'\nimport { TableCell } from '@timui/vue'\nimport { TableFooter } from '@timui/vue'\nimport { TableHead } from '@timui/vue'\nimport { TableHeader } from '@timui/vue'\nimport { TableRow } from '@timui/vue'\nimport { formatCurrency, tableUsers } from './table-demo-data'\n\nconst rows = tableUsers.slice(0, 8)\nconst selectedIds = reactive(new Set<string>())\n\nfunction toChecked(value: unknown) {\n  return !!((value as { detail?: { checked?: boolean } })?.detail?.checked ?? value)\n}\n\nconst allSelected = computed(() => rows.length > 0 && rows.every((row) => selectedIds.has(row.id)))\nconst someSelected = computed(\n  () => rows.some((row) => selectedIds.has(row.id)) && !allSelected.value\n)\n\nconst totalBalance = computed(() => rows.reduce((total, row) => total + row.balance, 0))\n\nfunction toggleAll(next: boolean) {\n  selectedIds.clear()\n  if (next) {\n    rows.forEach((row) => selectedIds.add(row.id))\n  }\n}\n\nfunction toggleRow(id: string, next: boolean) {\n  if (next) {\n    selectedIds.add(id)\n  } else {\n    selectedIds.delete(id)\n  }\n}\n</script>\n\n<template>\n  <div>\n    <Table>\n      <TableHeader>\n        <TableRow class=\"hover:bg-transparent\">\n          <TableHead>\n            <Checkbox\n              :checked=\"allSelected || (someSelected && 'indeterminate')\"\n              :onCheckedChange=\"(value: unknown) => toggleAll(toChecked(value))\"\n              aria-label=\"Select all\"\n            />\n          </TableHead>\n          <TableHead>Name</TableHead>\n          <TableHead>Email</TableHead>\n          <TableHead>Location</TableHead>\n          <TableHead>Status</TableHead>\n          <TableHead class=\"text-right\">Balance</TableHead>\n        </TableRow>\n      </TableHeader>\n      <TableBody>\n        <TableRow\n          v-for=\"row in rows\"\n          :key=\"row.id\"\n          :data-state=\"selectedIds.has(row.id) ? 'selected' : undefined\"\n        >\n          <TableCell>\n            <Checkbox\n              :checked=\"selectedIds.has(row.id)\"\n              :onCheckedChange=\"(value: unknown) => toggleRow(row.id, toChecked(value))\"\n              :aria-label=\"`Select ${row.name}`\"\n            />\n          </TableCell>\n          <TableCell class=\"font-medium\">{{ row.name }}</TableCell>\n          <TableCell>{{ row.email }}</TableCell>\n          <TableCell>{{ row.flag }} {{ row.location }}</TableCell>\n          <TableCell>\n            <Badge\n              :class=\"\n                cn(\n                  row.status === 'Inactive' && 'bg-muted-foreground/60 text-primary-foreground',\n                  row.status === 'Pending' && 'bg-amber-500/20 text-amber-600'\n                )\n              \"\n            >\n              {{ row.status }}\n            </Badge>\n          </TableCell>\n          <TableCell class=\"text-right\">{{ formatCurrency(row.balance) }}</TableCell>\n        </TableRow>\n      </TableBody>\n      <TableFooter class=\"bg-transparent\">\n        <TableRow class=\"hover:bg-transparent\">\n          <TableCell :colSpan=\"5\">Total</TableCell>\n          <TableCell class=\"text-right\">{{ formatCurrency(totalBalance) }}</TableCell>\n        </TableRow>\n      </TableFooter>\n    </Table>\n    <p class=\"text-muted-foreground mt-4 text-center text-sm\">\n      Basic data table made with\n      <a class=\"hover:text-foreground underline\" href=\"https://tanstack.com/table\" target=\"_blank\" rel=\"noopener noreferrer\">\n        TanStack Table\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/table/table-12.html",
          "target": "components/ui/table-12.html",
          "type": "registry:component",
          "content": "<template>\n  <div><Table><TableHeader><!-- Loop table.getHeaderGroups() -->\n<TableRow key=\"${headerGroup.id}\" class=\"hover:bg-transparent\">${headerGroup.headers.map((header) => {\n                return (\n                  <TableHead key={header.id}>\n                    {header.isPlaceholder\n                      ? null\n                      : flexRender(header.column.columnDef.header, header.getContext())}\n                  </TableHead>\n                )\n              })}</TableRow>\n<!-- End Loop --></TableHeader><TableBody><!-- if table.getRowModel().rows?.length -->\n${table.getRowModel().rows.map((row) => (\n              <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>\n                {row.getVisibleCells().map((cell) => (\n                  <TableCell key={cell.id}>\n                    {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                  </TableCell>\n                ))}\n              </TableRow>\n            ))}\n<!-- else -->\n<TableRow><TableCell colspan=\"${columns.length}\" class=\"h-24 text-center\">No results.\n              </TableCell></TableRow>\n<!-- endif --></TableBody><TableFooter class=\"bg-transparent\"><TableRow class=\"hover:bg-transparent\"><TableCell colspan=\"${5}\">Total</TableCell><TableCell class=\"text-right\">${new Intl.NumberFormat('en-US', {\n                style: 'currency',\n                currency: 'USD',\n              }).format(data.reduce((total, item) => total + item.balance, 0))}</TableCell></TableRow></TableFooter></Table><p class=\"text-muted-foreground mt-4 text-center text-sm\">Basic data table made with${' '}<a class=\"hover:text-foreground underline\" href=\"https://tanstack.com/table\" target=\"_blank\" rel=\"noopener noreferrer\">TanStack Table\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/table/table-12.wxml",
          "target": "components/ui/table-12/table-12.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><table><tableheader><tablerow wx:for=\"{{table.getHeaderGroups()}}\" wx:for-item=\"headerGroup\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{headerGroup.id}}\" class=\"hover:bg-transparent\">{{ headerGroup.headers.map((header) => {\n                return (\n                  <TableHead key={header.id}>\n                    {header.isPlaceholder\n                      ? null\n                      : flexRender(header.column.columnDef.header, header.getContext())}\n                  </TableHead>\n                )\n              }) }}</tablerow></tableheader><tablebody><block wx:if=\"{{table.getRowModel().rows?.length}}\">\n{{ table.getRowModel().rows.map((row) => (\n              <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>\n                {row.getVisibleCells().map((cell) => (\n                  <TableCell key={cell.id}>\n                    {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                  </TableCell>\n                ))}\n              </TableRow>\n            )) }}\n</block>\n<block wx:else>\n<tablerow><tablecell colspan=\"{{columns.length}}\" class=\"h-24 text-center\">No results.\n              </tablecell></tablerow>\n</block></tablebody><tablefooter class=\"bg-transparent\"><tablerow class=\"hover:bg-transparent\"><tablecell colspan=\"{{5}}\">Total</tablecell><tablecell class=\"text-right\">{{ new Intl.NumberFormat('en-US', {\n                style: 'currency',\n                currency: 'USD',\n              }).format(data.reduce((total, item) => total + item.balance, 0)) }}</tablecell></tablerow></tablefooter></table><text class=\"text-muted-foreground mt-4 text-center text-sm\">Basic data table made with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://tanstack.com/table\" target=\"_blank\" rel=\"noopener noreferrer\">TanStack Table\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "table",
          "tanstack",
          "checkbox",
          "badge",
          "chip",
          "flag"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "table-12",
          "group": "table",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "table-12",
              "path": "registry/default/components/table/table-12.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "table-12",
              "path": "registry/default/components/table/table-12.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "table-12",
              "path": "registry/default/components/table/table-12.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "table-12",
              "path": "registry/default/components/table/table-12.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@tanstack/react-table",
              "@timui/core",
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tables",
        "title": "Table · Select all"
      },
      "categories": [
        "tables",
        "table"
      ]
    },
    {
      "name": "table-13",
      "type": "registry:component",
      "dependencies": [
        "@tanstack/react-table",
        "@timui/core",
        "@timui/react"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/checkbox.json",
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/select.json",
        "https://ui.timkit.cn/r/table.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/table/table-13.tsx",
          "type": "registry:component",
          "target": "components/ui/table-13.tsx",
          "content": "'use client'\n\nimport { useId, useMemo, useState } from 'react'\nimport {\n  Column,\n  ColumnDef,\n  ColumnFiltersState,\n  flexRender,\n  getCoreRowModel,\n  getFacetedMinMaxValues,\n  getFacetedRowModel,\n  getFacetedUniqueValues,\n  getFilteredRowModel,\n  getSortedRowModel,\n  RowData,\n  RowSelectionState,\n  SortingState,\n  useReactTable,\n} from '@tanstack/react-table'\nimport { cn } from '@timui/core'\nimport {\n  Checkbox,\n  Input,\n  Label,\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n  Table,\n  TableBody,\n  TableCell,\n  TableHead,\n  TableHeader,\n  TableRow,\n} from '@timui/react'\nimport { ChevronDownIcon, ChevronUpIcon, ExternalLinkIcon, SearchIcon } from 'lucide-react'\n\ndeclare module '@tanstack/react-table' {\n  //allows us to define custom properties for our columns\n  interface ColumnMeta<TData extends RowData, TValue> {\n    filterVariant?: 'text' | 'range' | 'select'\n  }\n}\n\ntype Item = {\n  id: string\n  keyword: string\n  intents: Array<'Informational' | 'Navigational' | 'Commercial' | 'Transactional'>\n  volume: number\n  cpc: number\n  traffic: number\n  link: string\n}\n\nconst columns: ColumnDef<Item>[] = [\n  {\n    id: 'select',\n    header: ({ table }) => (\n      <Checkbox\n        checked={\n          table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && 'indeterminate')\n        }\n        onCheckedChange={(value: any) =>\n          table.toggleAllPageRowsSelected(!!(value?.detail?.checked ?? value))\n        }\n        onClick={() => table.toggleAllPageRowsSelected(!table.getIsAllPageRowsSelected())}\n        aria-label=\"Select all\"\n      />\n    ),\n    cell: ({ row }) => (\n      <Checkbox\n        checked={row.getIsSelected()}\n        onCheckedChange={(value: any) => row.toggleSelected(!!(value?.detail?.checked ?? value))}\n        onClick={() => row.toggleSelected(!row.getIsSelected())}\n        aria-label=\"Select row\"\n      />\n    ),\n  },\n  {\n    header: 'Keyword',\n    accessorKey: 'keyword',\n    cell: ({ row }) => <div className=\"font-medium\">{row.getValue('keyword')}</div>,\n  },\n  {\n    header: 'Intents',\n    accessorKey: 'intents',\n    cell: ({ row }) => {\n      const intents = row.getValue('intents') as string[]\n      return (\n        <div className=\"flex gap-1\">\n          {intents.map((intent) => {\n            const styles = {\n              Informational: 'bg-indigo-400/20 text-indigo-500',\n              Navigational: 'bg-emerald-400/20 text-emerald-500',\n              Commercial: 'bg-amber-400/20 text-amber-500',\n              Transactional: 'bg-rose-400/20 text-rose-500',\n            }[intent]\n\n            return (\n              <div\n                key={intent}\n                className={cn(\n                  'flex size-5 items-center justify-center rounded text-xs font-medium',\n                  styles\n                )}\n              >\n                {intent.charAt(0)}\n              </div>\n            )\n          })}\n        </div>\n      )\n    },\n    enableSorting: false,\n    meta: {\n      filterVariant: 'select',\n    },\n    filterFn: (row, id, filterValue) => {\n      const rowValue = row.getValue(id)\n      return Array.isArray(rowValue) && rowValue.includes(filterValue)\n    },\n  },\n  {\n    header: 'Volume',\n    accessorKey: 'volume',\n    cell: ({ row }) => {\n      const volume = parseInt(row.getValue('volume'))\n      return new Intl.NumberFormat('en-US', {\n        notation: 'compact',\n        maximumFractionDigits: 1,\n      }).format(volume)\n    },\n    meta: {\n      filterVariant: 'range',\n    },\n  },\n  {\n    header: 'CPC',\n    accessorKey: 'cpc',\n    cell: ({ row }) => <div>${row.getValue('cpc')}</div>,\n    meta: {\n      filterVariant: 'range',\n    },\n  },\n  {\n    header: 'Traffic',\n    accessorKey: 'traffic',\n    cell: ({ row }) => {\n      const traffic = parseInt(row.getValue('traffic'))\n      return new Intl.NumberFormat('en-US', {\n        notation: 'compact',\n        maximumFractionDigits: 1,\n      }).format(traffic)\n    },\n    meta: {\n      filterVariant: 'range',\n    },\n  },\n  {\n    header: 'Link',\n    accessorKey: 'link',\n    cell: ({ row }) => (\n      <a className=\"inline-flex items-center gap-1 hover:underline\" href=\"#\">\n        {row.getValue('link')} <ExternalLinkIcon size={12} aria-hidden=\"true\" />\n      </a>\n    ),\n    enableSorting: false,\n  },\n]\n\nconst items: Item[] = [\n  {\n    id: '1',\n    keyword: 'react components',\n    intents: ['Informational', 'Navigational'],\n    volume: 2507,\n    cpc: 2.5,\n    traffic: 88,\n    link: 'https://ui.timkit.cn',\n  },\n  {\n    id: '2',\n    keyword: 'buy react templates',\n    intents: ['Commercial', 'Transactional'],\n    volume: 1850,\n    cpc: 4.75,\n    traffic: 65,\n    link: 'https://ui.timkit.cn/input',\n  },\n  {\n    id: '3',\n    keyword: 'react ui library',\n    intents: ['Informational', 'Commercial'],\n    volume: 3200,\n    cpc: 3.25,\n    traffic: 112,\n    link: 'https://ui.timkit.cn/badge',\n  },\n  {\n    id: '4',\n    keyword: 'tailwind components download',\n    intents: ['Transactional'],\n    volume: 890,\n    cpc: 1.95,\n    traffic: 45,\n    link: 'https://ui.timkit.cn/alert',\n  },\n  {\n    id: '5',\n    keyword: 'react dashboard template free',\n    intents: ['Commercial', 'Transactional'],\n    volume: 4100,\n    cpc: 5.5,\n    traffic: 156,\n    link: 'https://ui.timkit.cn/tabs',\n  },\n  {\n    id: '6',\n    keyword: 'how to use react components',\n    intents: ['Informational'],\n    volume: 1200,\n    cpc: 1.25,\n    traffic: 42,\n    link: 'https://ui.timkit.cn/table',\n  },\n  {\n    id: '7',\n    keyword: 'react ui kit premium',\n    intents: ['Commercial', 'Transactional'],\n    volume: 760,\n    cpc: 6.8,\n    traffic: 28,\n    link: 'https://ui.timkit.cn/avatar',\n  },\n  {\n    id: '8',\n    keyword: 'react component documentation',\n    intents: ['Informational', 'Navigational'],\n    volume: 950,\n    cpc: 1.8,\n    traffic: 35,\n    link: 'https://ui.timkit.cn',\n  },\n]\n\nexport default function Component() {\n  const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([])\n  const [rowSelection, setRowSelection] = useState<RowSelectionState>({})\n  const [sorting, setSorting] = useState<SortingState>([\n    {\n      id: 'traffic',\n      desc: false,\n    },\n  ])\n\n  const table = useReactTable({\n    data: items,\n    columns,\n    state: {\n      sorting,\n      columnFilters,\n      rowSelection,\n    },\n    onColumnFiltersChange: setColumnFilters,\n    onRowSelectionChange: setRowSelection,\n    enableRowSelection: true,\n    getRowId: (row) => row.id,\n    getCoreRowModel: getCoreRowModel(),\n    getFilteredRowModel: getFilteredRowModel(), //client-side filtering\n    getSortedRowModel: getSortedRowModel(),\n    getFacetedRowModel: getFacetedRowModel(), // client-side faceting\n    getFacetedUniqueValues: getFacetedUniqueValues(), // generate unique values for select filter/autocomplete\n    getFacetedMinMaxValues: getFacetedMinMaxValues(), // generate min/max values for range filter\n    onSortingChange: setSorting,\n    enableSortingRemoval: false,\n  })\n\n  return (\n    <div className=\"space-y-6\">\n      {/* Filters */}\n      <div className=\"flex flex-wrap gap-3\">\n        {/* Search input */}\n        <div className=\"w-44\">\n          <Filter column={table.getColumn('keyword')!} />\n        </div>\n        {/* Intents select */}\n        <div className=\"w-36\">\n          <Filter column={table.getColumn('intents')!} />\n        </div>\n        {/* Volume inputs */}\n        <div className=\"w-36\">\n          <Filter column={table.getColumn('volume')!} />\n        </div>\n        {/* CPC inputs */}\n        <div className=\"w-36\">\n          <Filter column={table.getColumn('cpc')!} />\n        </div>\n        {/* Traffic inputs */}\n        <div className=\"w-36\">\n          <Filter column={table.getColumn('traffic')!} />\n        </div>\n      </div>\n\n      <Table>\n        <TableHeader>\n          {table.getHeaderGroups().map((headerGroup) => (\n            <TableRow key={headerGroup.id} className=\"bg-muted/50\">\n              {headerGroup.headers.map((header) => {\n                return (\n                  <TableHead\n                    key={header.id}\n                    className=\"relative h-10 border-t select-none\"\n                    aria-sort={\n                      header.column.getIsSorted() === 'asc'\n                        ? 'ascending'\n                        : header.column.getIsSorted() === 'desc'\n                          ? 'descending'\n                          : 'none'\n                    }\n                  >\n                    {header.isPlaceholder ? null : header.column.getCanSort() ? (\n                      <div\n                        className={cn(\n                          header.column.getCanSort() &&\n                            'flex h-full cursor-pointer items-center justify-between gap-2 select-none'\n                        )}\n                        onClick={header.column.getToggleSortingHandler()}\n                        onKeyDown={(e) => {\n                          // Enhanced keyboard handling for sorting\n                          if (header.column.getCanSort() && (e.key === 'Enter' || e.key === ' ')) {\n                            e.preventDefault()\n                            header.column.getToggleSortingHandler()?.(e)\n                          }\n                        }}\n                        tabIndex={header.column.getCanSort() ? 0 : undefined}\n                      >\n                        {flexRender(header.column.columnDef.header, header.getContext())}\n                        {{\n                          asc: (\n                            <ChevronUpIcon\n                              className=\"shrink-0 opacity-60\"\n                              size={16}\n                              aria-hidden=\"true\"\n                            />\n                          ),\n                          desc: (\n                            <ChevronDownIcon\n                              className=\"shrink-0 opacity-60\"\n                              size={16}\n                              aria-hidden=\"true\"\n                            />\n                          ),\n                        }[header.column.getIsSorted() as string] ?? (\n                          <span className=\"size-4\" aria-hidden=\"true\" />\n                        )}\n                      </div>\n                    ) : (\n                      flexRender(header.column.columnDef.header, header.getContext())\n                    )}\n                  </TableHead>\n                )\n              })}\n            </TableRow>\n          ))}\n        </TableHeader>\n        <TableBody>\n          {table.getRowModel().rows?.length ? (\n            table.getRowModel().rows.map((row) => (\n              <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>\n                {row.getVisibleCells().map((cell) => (\n                  <TableCell key={cell.id}>\n                    {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                  </TableCell>\n                ))}\n              </TableRow>\n            ))\n          ) : (\n            <TableRow>\n              <TableCell colSpan={columns.length} className=\"h-24 text-center\">\n                No results.\n              </TableCell>\n            </TableRow>\n          )}\n        </TableBody>\n      </Table>\n      <p className=\"text-muted-foreground mt-4 text-center text-sm\">\n        Data table with filters made with{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://tanstack.com/table\"\n          target=\"_blank\"\n          rel=\"noopener noreferrer\"\n        >\n          TanStack Table\n        </a>\n      </p>\n    </div>\n  )\n}\n\nfunction Filter({ column }: { column: Column<any, unknown> }) {\n  const id = useId()\n  const columnFilterValue = column.getFilterValue()\n  const { filterVariant } = column.columnDef.meta ?? {}\n  const columnHeader = typeof column.columnDef.header === 'string' ? column.columnDef.header : ''\n  const sortedUniqueValues = useMemo(() => {\n    if (filterVariant === 'range') return []\n\n    // Get all unique values from the column\n    const values = Array.from(column.getFacetedUniqueValues().keys())\n\n    // If the values are arrays, flatten them and get unique items\n    const flattenedValues = values.reduce((acc: string[], curr) => {\n      if (Array.isArray(curr)) {\n        return [...acc, ...curr]\n      }\n      return [...acc, curr]\n    }, [])\n\n    // Get unique values and sort them\n    return Array.from(new Set(flattenedValues)).sort()\n  }, [column.getFacetedUniqueValues(), filterVariant])\n\n  if (filterVariant === 'range') {\n    return (\n      <div className=\"*:not-first:mt-2\">\n        <Label>{columnHeader}</Label>\n        <div className=\"flex\">\n          <Input\n            id={`${id}-range-1`}\n            className=\"flex-1 rounded-e-none [-moz-appearance:_textfield] focus:z-10 [&::-webkit-inner-spin-button]:m-0 [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:m-0 [&::-webkit-outer-spin-button]:appearance-none\"\n            value={(columnFilterValue as [number, number])?.[0] ?? ''}\n            onChange={(e) =>\n              column.setFilterValue((old: [number, number]) => [\n                e.target.value ? Number(e.target.value) : undefined,\n                old?.[1],\n              ])\n            }\n            placeholder=\"Min\"\n            type=\"number\"\n            aria-label={`${columnHeader} min`}\n          />\n          <Input\n            id={`${id}-range-2`}\n            className=\"-ms-px flex-1 rounded-s-none [-moz-appearance:_textfield] focus:z-10 [&::-webkit-inner-spin-button]:m-0 [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:m-0 [&::-webkit-outer-spin-button]:appearance-none\"\n            value={(columnFilterValue as [number, number])?.[1] ?? ''}\n            onChange={(e) =>\n              column.setFilterValue((old: [number, number]) => [\n                old?.[0],\n                e.target.value ? Number(e.target.value) : undefined,\n              ])\n            }\n            placeholder=\"Max\"\n            type=\"number\"\n            aria-label={`${columnHeader} max`}\n          />\n        </div>\n      </div>\n    )\n  }\n\n  if (filterVariant === 'select') {\n    return (\n      <div className=\"*:not-first:mt-2\">\n        <Label htmlFor={`${id}-select`}>{columnHeader}</Label>\n        <Select\n          value={columnFilterValue?.toString() ?? 'all'}\n          onValueChange={(value: string) => {\n            column.setFilterValue(value === 'all' ? undefined : value)\n          }}\n        >\n          <SelectTrigger id={`${id}-select`}>\n            <SelectValue />\n          </SelectTrigger>\n          <SelectContent>\n            <SelectItem value=\"all\">All</SelectItem>\n            {sortedUniqueValues.map((value) => (\n              <SelectItem key={String(value)} value={String(value)}>\n                {String(value)}\n              </SelectItem>\n            ))}\n          </SelectContent>\n        </Select>\n      </div>\n    )\n  }\n\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={`${id}-input`}>{columnHeader}</Label>\n      <div className=\"relative\">\n        <Input\n          id={`${id}-input`}\n          className=\"peer ps-9\"\n          value={(columnFilterValue ?? '') as string}\n          onChange={(e) => column.setFilterValue(e.target.value)}\n          placeholder={`Search ${columnHeader.toLowerCase()}`}\n          type=\"text\"\n        />\n        <div className=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\">\n          <SearchIcon size={16} />\n        </div>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/table/table-13.vue",
          "target": "components/ui/table-13.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport { cn } from '@timui/core'\nimport { ChevronDownIcon, ChevronUpIcon, ExternalLinkIcon, SearchIcon } from 'lucide-vue-next'\nimport { Input } from '@timui/vue'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/vue'\nimport { Table } from '@timui/vue'\nimport { TableBody } from '@timui/vue'\nimport { TableCell } from '@timui/vue'\nimport { TableHead } from '@timui/vue'\nimport { TableHeader } from '@timui/vue'\nimport { TableRow } from '@timui/vue'\n\ntype KeywordRow = {\n  id: string\n  keyword: string\n  intents: Array<'Informational' | 'Navigational' | 'Commercial' | 'Transactional'>\n  volume: number\n  cpc: number\n  traffic: number\n  link: string\n}\n\nconst rows: KeywordRow[] = [\n  {\n    id: '1',\n    keyword: 'react components',\n    intents: ['Informational', 'Navigational'],\n    volume: 2507,\n    cpc: 2.5,\n    traffic: 88,\n    link: 'https://ui.timkit.cn',\n  },\n  {\n    id: '2',\n    keyword: 'buy react templates',\n    intents: ['Commercial', 'Transactional'],\n    volume: 1850,\n    cpc: 4.75,\n    traffic: 65,\n    link: 'https://ui.timkit.cn/input',\n  },\n  {\n    id: '3',\n    keyword: 'react ui library',\n    intents: ['Informational', 'Commercial'],\n    volume: 3200,\n    cpc: 3.25,\n    traffic: 112,\n    link: 'https://ui.timkit.cn/badge',\n  },\n  {\n    id: '4',\n    keyword: 'tailwind components download',\n    intents: ['Transactional'],\n    volume: 890,\n    cpc: 1.95,\n    traffic: 45,\n    link: 'https://ui.timkit.cn/alert',\n  },\n  {\n    id: '5',\n    keyword: 'react dashboard template free',\n    intents: ['Commercial', 'Transactional'],\n    volume: 4100,\n    cpc: 5.5,\n    traffic: 156,\n    link: 'https://ui.timkit.cn/tabs',\n  },\n  {\n    id: '6',\n    keyword: 'how to use react components',\n    intents: ['Informational'],\n    volume: 1200,\n    cpc: 1.25,\n    traffic: 42,\n    link: 'https://ui.timkit.cn/table',\n  },\n]\n\nconst keywordFilter = ref('')\nconst intentFilter = ref('all')\nconst volumeMin = ref<number | null>(null)\nconst volumeMax = ref<number | null>(null)\nconst cpcMin = ref<number | null>(null)\nconst cpcMax = ref<number | null>(null)\nconst trafficMin = ref<number | null>(null)\nconst trafficMax = ref<number | null>(null)\nconst sortBy = ref<'traffic' | 'volume' | 'cpc'>('traffic')\nconst sortDirection = ref<'asc' | 'desc'>('asc')\n\nfunction toggleSort(field: 'traffic' | 'volume' | 'cpc') {\n  if (sortBy.value === field) {\n    sortDirection.value = sortDirection.value === 'asc' ? 'desc' : 'asc'\n    return\n  }\n\n  sortBy.value = field\n  sortDirection.value = 'asc'\n}\n\nconst filteredRows = computed(() => {\n  let next = rows.filter((row) => {\n    const matchesKeyword =\n      keywordFilter.value.trim().length === 0 ||\n      row.keyword.toLowerCase().includes(keywordFilter.value.toLowerCase())\n\n    const matchesIntent =\n      intentFilter.value === 'all' || row.intents.includes(intentFilter.value as KeywordRow['intents'][number])\n\n    const matchesVolume =\n      (volumeMin.value === null || row.volume >= volumeMin.value) &&\n      (volumeMax.value === null || row.volume <= volumeMax.value)\n\n    const matchesCpc =\n      (cpcMin.value === null || row.cpc >= cpcMin.value) &&\n      (cpcMax.value === null || row.cpc <= cpcMax.value)\n\n    const matchesTraffic =\n      (trafficMin.value === null || row.traffic >= trafficMin.value) &&\n      (trafficMax.value === null || row.traffic <= trafficMax.value)\n\n    return matchesKeyword && matchesIntent && matchesVolume && matchesCpc && matchesTraffic\n  })\n\n  next = [...next].sort((left, right) => {\n    const diff = left[sortBy.value] - right[sortBy.value]\n    return sortDirection.value === 'asc' ? diff : -diff\n  })\n\n  return next\n})\n\nfunction intentClass(intent: KeywordRow['intents'][number]) {\n  return {\n    Informational: 'bg-indigo-400/20 text-indigo-500',\n    Navigational: 'bg-emerald-400/20 text-emerald-500',\n    Commercial: 'bg-amber-400/20 text-amber-500',\n    Transactional: 'bg-rose-400/20 text-rose-500',\n  }[intent]\n}\n</script>\n\n<template>\n  <div class=\"space-y-6\">\n    <div class=\"flex flex-wrap gap-3\">\n      <div class=\"relative w-52\">\n        <Input\n          class=\"peer ps-9\"\n          :value=\"keywordFilter\"\n          placeholder=\"Search keyword...\"\n          @input=\"keywordFilter = ($event.target as HTMLInputElement).value\"\n        />\n        <div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3\">\n          <SearchIcon class=\"size-4\" aria-hidden=\"true\" />\n        </div>\n      </div>\n\n      <div class=\"w-44\">\n        <Select :value=\"intentFilter\" @update:modelValue=\"(value) => (intentFilter = value)\">\n          <SelectTrigger><SelectValue placeholder=\"All intents\" /></SelectTrigger>\n          <SelectContent>\n            <SelectItem value=\"all\">All intents</SelectItem>\n            <SelectItem value=\"Informational\">Informational</SelectItem>\n            <SelectItem value=\"Navigational\">Navigational</SelectItem>\n            <SelectItem value=\"Commercial\">Commercial</SelectItem>\n            <SelectItem value=\"Transactional\">Transactional</SelectItem>\n          </SelectContent>\n        </Select>\n      </div>\n\n      <Input class=\"w-28\" type=\"number\" placeholder=\"Vol min\" @input=\"volumeMin = Number(($event.target as HTMLInputElement).value) || null\" />\n      <Input class=\"w-28\" type=\"number\" placeholder=\"Vol max\" @input=\"volumeMax = Number(($event.target as HTMLInputElement).value) || null\" />\n      <Input class=\"w-28\" type=\"number\" placeholder=\"CPC min\" @input=\"cpcMin = Number(($event.target as HTMLInputElement).value) || null\" />\n      <Input class=\"w-28\" type=\"number\" placeholder=\"CPC max\" @input=\"cpcMax = Number(($event.target as HTMLInputElement).value) || null\" />\n      <Input class=\"w-28\" type=\"number\" placeholder=\"Trf min\" @input=\"trafficMin = Number(($event.target as HTMLInputElement).value) || null\" />\n      <Input class=\"w-28\" type=\"number\" placeholder=\"Trf max\" @input=\"trafficMax = Number(($event.target as HTMLInputElement).value) || null\" />\n    </div>\n\n    <Table>\n      <TableHeader>\n        <TableRow class=\"bg-muted/50\">\n          <TableHead>Keyword</TableHead>\n          <TableHead>Intents</TableHead>\n          <TableHead class=\"cursor-pointer select-none\" @click=\"toggleSort('volume')\">\n            <span class=\"flex items-center gap-1\">\n              Volume\n              <ChevronUpIcon v-if=\"sortBy === 'volume' && sortDirection === 'asc'\" :size=\"14\" />\n              <ChevronDownIcon v-else-if=\"sortBy === 'volume'\" :size=\"14\" />\n            </span>\n          </TableHead>\n          <TableHead class=\"cursor-pointer select-none\" @click=\"toggleSort('cpc')\">\n            <span class=\"flex items-center gap-1\">\n              CPC\n              <ChevronUpIcon v-if=\"sortBy === 'cpc' && sortDirection === 'asc'\" :size=\"14\" />\n              <ChevronDownIcon v-else-if=\"sortBy === 'cpc'\" :size=\"14\" />\n            </span>\n          </TableHead>\n          <TableHead class=\"cursor-pointer select-none\" @click=\"toggleSort('traffic')\">\n            <span class=\"flex items-center gap-1\">\n              Traffic\n              <ChevronUpIcon v-if=\"sortBy === 'traffic' && sortDirection === 'asc'\" :size=\"14\" />\n              <ChevronDownIcon v-else-if=\"sortBy === 'traffic'\" :size=\"14\" />\n            </span>\n          </TableHead>\n          <TableHead>Link</TableHead>\n        </TableRow>\n      </TableHeader>\n\n      <TableBody>\n        <template v-if=\"filteredRows.length > 0\">\n          <TableRow v-for=\"row in filteredRows\" :key=\"row.id\">\n            <TableCell class=\"font-medium\">{{ row.keyword }}</TableCell>\n            <TableCell>\n              <div class=\"flex gap-1\">\n                <span\n                  v-for=\"intent in row.intents\"\n                  :key=\"intent\"\n                  :class=\"cn('flex size-5 items-center justify-center rounded text-xs font-medium', intentClass(intent))\"\n                >\n                  {{ intent.charAt(0) }}\n                </span>\n              </div>\n            </TableCell>\n            <TableCell>{{ row.volume.toLocaleString() }}</TableCell>\n            <TableCell>${{ row.cpc.toFixed(2) }}</TableCell>\n            <TableCell>{{ row.traffic.toLocaleString() }}</TableCell>\n            <TableCell>\n              <a class=\"inline-flex items-center gap-1 hover:underline\" :href=\"row.link\" target=\"_blank\" rel=\"noopener noreferrer\">\n                {{ row.link }}\n                <ExternalLinkIcon :size=\"12\" aria-hidden=\"true\" />\n              </a>\n            </TableCell>\n          </TableRow>\n        </template>\n\n        <template v-else>\n          <TableRow>\n            <TableCell :colSpan=\"6\" class=\"h-24 text-center\">No results.</TableCell>\n          </TableRow>\n        </template>\n      </TableBody>\n    </Table>\n\n    <p class=\"text-muted-foreground mt-4 text-center text-sm\">\n      Data table with filters made with\n      <a class=\"hover:text-foreground underline\" href=\"https://tanstack.com/table\" target=\"_blank\" rel=\"noopener noreferrer\">\n        TanStack Table\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/table/table-13.html",
          "target": "components/ui/table-13.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-6\"><div class=\"flex flex-wrap gap-3\"><div class=\"w-44\"><Filter column=\"${table.getColumn('keyword')!}\" /></div><div class=\"w-36\"><Filter column=\"${table.getColumn('intents')!}\" /></div><div class=\"w-36\"><Filter column=\"${table.getColumn('volume')!}\" /></div><div class=\"w-36\"><Filter column=\"${table.getColumn('cpc')!}\" /></div><div class=\"w-36\"><Filter column=\"${table.getColumn('traffic')!}\" /></div></div><Table><TableHeader><!-- Loop table.getHeaderGroups() -->\n<TableRow key=\"${headerGroup.id}\" class=\"bg-muted/50\">${headerGroup.headers.map((header) => {\n                return (\n                  <TableHead\n                    key={header.id}\n                    className=\"relative h-10 border-t select-none\"\n                    aria-sort={\n                      header.column.getIsSorted() === 'asc'\n                        ? 'ascending'\n                        : header.column.getIsSorted() === 'desc'\n                          ? 'descending'\n                          : 'none'\n                    }\n                  >\n                    {header.isPlaceholder ? null : header.column.getCanSort() ? (\n                      <div\n                        className={cn(\n                          header.column.getCanSort() &&\n                            'flex h-full cursor-pointer items-center justify-between gap-2 select-none'\n                        )}\n                        onClick={header.column.getToggleSortingHandler()}\n                        onKeyDown={(e) => {\n                          // Enhanced keyboard handling for sorting\n                          if (header.column.getCanSort() && (e.key === 'Enter' || e.key === ' ')) {\n                            e.preventDefault()\n                            header.column.getToggleSortingHandler()?.(e)\n                          }\n                        }}\n                        tabIndex={header.column.getCanSort() ? 0 : undefined}\n                      >\n                        {flexRender(header.column.columnDef.header, header.getContext())}\n                        {{\n                          asc: (\n                            <ChevronUpIcon\n                              className=\"shrink-0 opacity-60\"\n                              size={16}\n                              aria-hidden=\"true\"\n                            />\n                          ),\n                          desc: (\n                            <ChevronDownIcon\n                              className=\"shrink-0 opacity-60\"\n                              size={16}\n                              aria-hidden=\"true\"\n                            />\n                          ),\n                        }[header.column.getIsSorted() as string] ?? (\n                          <span className=\"size-4\" aria-hidden=\"true\" />\n                        )}\n                      </div>\n                    ) : (\n                      flexRender(header.column.columnDef.header, header.getContext())\n                    )}\n                  </TableHead>\n                )\n              })}</TableRow>\n<!-- End Loop --></TableHeader><TableBody><!-- if table.getRowModel().rows?.length -->\n${table.getRowModel().rows.map((row) => (\n              <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>\n                {row.getVisibleCells().map((cell) => (\n                  <TableCell key={cell.id}>\n                    {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                  </TableCell>\n                ))}\n              </TableRow>\n            ))}\n<!-- else -->\n<TableRow><TableCell colspan=\"${columns.length}\" class=\"h-24 text-center\">No results.\n              </TableCell></TableRow>\n<!-- endif --></TableBody></Table><p class=\"text-muted-foreground mt-4 text-center text-sm\">Data table with filters made with${' '}<a class=\"hover:text-foreground underline\" href=\"https://tanstack.com/table\" target=\"_blank\" rel=\"noopener noreferrer\">TanStack Table\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/table/table-13.wxml",
          "target": "components/ui/table-13/table-13.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-6\"><view class=\"flex flex-wrap gap-3\"><view class=\"w-44\"><filter column=\"{{table.getColumn('keyword')!}}\" /></view><view class=\"w-36\"><filter column=\"{{table.getColumn('intents')!}}\" /></view><view class=\"w-36\"><filter column=\"{{table.getColumn('volume')!}}\" /></view><view class=\"w-36\"><filter column=\"{{table.getColumn('cpc')!}}\" /></view><view class=\"w-36\"><filter column=\"{{table.getColumn('traffic')!}}\" /></view></view><table><tableheader><tablerow wx:for=\"{{table.getHeaderGroups()}}\" wx:for-item=\"headerGroup\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{headerGroup.id}}\" class=\"bg-muted/50\">{{ headerGroup.headers.map((header) => {\n                return (\n                  <TableHead\n                    key={header.id}\n                    className=\"relative h-10 border-t select-none\"\n                    aria-sort={\n                      header.column.getIsSorted() === 'asc'\n                        ? 'ascending'\n                        : header.column.getIsSorted() === 'desc'\n                          ? 'descending'\n                          : 'none'\n                    }\n                  >\n                    {header.isPlaceholder ? null : header.column.getCanSort() ? (\n                      <div\n                        className={cn(\n                          header.column.getCanSort() &&\n                            'flex h-full cursor-pointer items-center justify-between gap-2 select-none'\n                        )}\n                        onClick={header.column.getToggleSortingHandler()}\n                        onKeyDown={(e) => {\n                          // Enhanced keyboard handling for sorting\n                          if (header.column.getCanSort() && (e.key === 'Enter' || e.key === ' ')) {\n                            e.preventDefault()\n                            header.column.getToggleSortingHandler()?.(e)\n                          }\n                        }}\n                        tabIndex={header.column.getCanSort() ? 0 : undefined}\n                      >\n                        {flexRender(header.column.columnDef.header, header.getContext())}\n                        {{\n                          asc: (\n                            <ChevronUpIcon\n                              className=\"shrink-0 opacity-60\"\n                              size={16}\n                              aria-hidden=\"true\"\n                            />\n                          ),\n                          desc: (\n                            <ChevronDownIcon\n                              className=\"shrink-0 opacity-60\"\n                              size={16}\n                              aria-hidden=\"true\"\n                            />\n                          ),\n                        }[header.column.getIsSorted() as string] ?? (\n                          <span className=\"size-4\" aria-hidden=\"true\" />\n                        )}\n                      </div>\n                    ) : (\n                      flexRender(header.column.columnDef.header, header.getContext())\n                    )}\n                  </TableHead>\n                )\n              }) }}</tablerow></tableheader><tablebody><block wx:if=\"{{table.getRowModel().rows?.length}}\">\n{{ table.getRowModel().rows.map((row) => (\n              <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>\n                {row.getVisibleCells().map((cell) => (\n                  <TableCell key={cell.id}>\n                    {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                  </TableCell>\n                ))}\n              </TableRow>\n            )) }}\n</block>\n<block wx:else>\n<tablerow><tablecell colspan=\"{{columns.length}}\" class=\"h-24 text-center\">No results.\n              </tablecell></tablerow>\n</block></tablebody></table><text class=\"text-muted-foreground mt-4 text-center text-sm\">Data table with filters made with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://tanstack.com/table\" target=\"_blank\" rel=\"noopener noreferrer\">TanStack Table\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "table",
          "tanstack",
          "checkbox",
          "search",
          "select",
          "range",
          "input",
          "filter",
          "sort"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "table-13",
          "group": "table",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "table-13",
              "path": "registry/default/components/table/table-13.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "table-13",
              "path": "registry/default/components/table/table-13.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "table-13",
              "path": "registry/default/components/table/table-13.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "table-13",
              "path": "registry/default/components/table/table-13.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@tanstack/react-table",
              "@timui/core",
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tables",
        "title": "Table · {columnHeader}"
      },
      "categories": [
        "tables",
        "table"
      ]
    },
    {
      "name": "table-14",
      "type": "registry:component",
      "dependencies": [
        "@tanstack/react-table",
        "@timui/core",
        "@timui/react"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/table.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/table/table-14.tsx",
          "type": "registry:component",
          "target": "components/ui/table-14.tsx",
          "content": "'use client'\n\nimport { useEffect, useState } from 'react'\nimport {\n  ColumnDef,\n  flexRender,\n  getCoreRowModel,\n  getSortedRowModel,\n  SortingState,\n  useReactTable,\n} from '@tanstack/react-table'\nimport { cn } from '@timui/core'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@timui/react'\nimport { ChevronDownIcon, ChevronUpIcon } from 'lucide-react'\n\ntype Item = {\n  id: string\n  name: string\n  email: string\n  location: string\n  flag: string\n  status: 'Active' | 'Inactive' | 'Pending'\n  balance: number\n  department: string\n  role: string\n  joinDate: string\n  lastActive: string\n  performance: 'Excellent' | 'Good' | 'Average' | 'Poor'\n}\n\nconst columns: ColumnDef<Item>[] = [\n  {\n    header: 'Name',\n    accessorKey: 'name',\n    cell: ({ row }) => <div className=\"truncate font-medium\">{row.getValue('name')}</div>,\n    sortUndefined: 'last',\n    sortDescFirst: false,\n  },\n  {\n    header: 'Email',\n    accessorKey: 'email',\n  },\n  {\n    header: 'Location',\n    accessorKey: 'location',\n    cell: ({ row }) => (\n      <div className=\"truncate\">\n        <span className=\"text-lg leading-none\">{row.original.flag}</span> {row.getValue('location')}\n      </div>\n    ),\n  },\n  {\n    header: 'Status',\n    accessorKey: 'status',\n  },\n  {\n    header: 'Balance',\n    accessorKey: 'balance',\n    cell: ({ row }) => {\n      const amount = parseFloat(row.getValue('balance'))\n      const formatted = new Intl.NumberFormat('en-US', {\n        style: 'currency',\n        currency: 'USD',\n      }).format(amount)\n      return formatted\n    },\n  },\n  {\n    header: 'Department',\n    accessorKey: 'department',\n  },\n  {\n    header: 'Role',\n    accessorKey: 'role',\n  },\n  {\n    header: 'Join Date',\n    accessorKey: 'joinDate',\n  },\n  {\n    header: 'Last Active',\n    accessorKey: 'lastActive',\n  },\n  {\n    header: 'Performance',\n    accessorKey: 'performance',\n  },\n]\n\nexport default function Component() {\n  const [data, setData] = useState<Item[]>([])\n  const [sorting, setSorting] = useState<SortingState>([\n    {\n      id: 'name',\n      desc: false,\n    },\n  ])\n\n  useEffect(() => {\n    async function fetchPosts() {\n      const res = await fetch(\n        'https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/users-01_fertyx.json'\n      )\n      const data = await res.json()\n      setData(data.slice(0, 5)) // Limit to 5 items\n    }\n    fetchPosts()\n  }, [])\n\n  const table = useReactTable({\n    data,\n    columns,\n    columnResizeMode: 'onChange',\n    getCoreRowModel: getCoreRowModel(),\n    getSortedRowModel: getSortedRowModel(),\n    onSortingChange: setSorting,\n    state: {\n      sorting,\n    },\n    enableSortingRemoval: false,\n  })\n\n  return (\n    <div>\n      <Table\n        className=\"table-fixed\"\n        style={{\n          width: table.getCenterTotalSize(),\n        }}\n      >\n        <TableHeader>\n          {table.getHeaderGroups().map((headerGroup) => (\n            <TableRow key={headerGroup.id} className=\"bg-muted/50\">\n              {headerGroup.headers.map((header) => {\n                return (\n                  <TableHead\n                    key={header.id}\n                    className=\"relative h-10 border-t select-none last:[&>.cursor-col-resize]:opacity-0\"\n                    aria-sort={\n                      header.column.getIsSorted() === 'asc'\n                        ? 'ascending'\n                        : header.column.getIsSorted() === 'desc'\n                          ? 'descending'\n                          : 'none'\n                    }\n                    {...{\n                      colSpan: header.colSpan,\n                      style: {\n                        width: header.getSize(),\n                      },\n                    }}\n                  >\n                    {header.isPlaceholder ? null : (\n                      <div\n                        className={cn(\n                          header.column.getCanSort() &&\n                            'flex h-full cursor-pointer items-center justify-between gap-2 select-none'\n                        )}\n                        onClick={header.column.getToggleSortingHandler()}\n                        onKeyDown={(e) => {\n                          // Enhanced keyboard handling for sorting\n                          if (header.column.getCanSort() && (e.key === 'Enter' || e.key === ' ')) {\n                            e.preventDefault()\n                            header.column.getToggleSortingHandler()?.(e)\n                          }\n                        }}\n                        tabIndex={header.column.getCanSort() ? 0 : undefined}\n                      >\n                        <span className=\"truncate\">\n                          {flexRender(header.column.columnDef.header, header.getContext())}\n                        </span>\n                        {{\n                          asc: (\n                            <ChevronUpIcon\n                              className=\"shrink-0 opacity-60\"\n                              size={16}\n                              aria-hidden=\"true\"\n                            />\n                          ),\n                          desc: (\n                            <ChevronDownIcon\n                              className=\"shrink-0 opacity-60\"\n                              size={16}\n                              aria-hidden=\"true\"\n                            />\n                          ),\n                        }[header.column.getIsSorted() as string] ?? null}\n                      </div>\n                    )}\n                    {header.column.getCanResize() && (\n                      <div\n                        {...{\n                          onDoubleClick: () => header.column.resetSize(),\n                          onMouseDown: header.getResizeHandler(),\n                          onTouchStart: header.getResizeHandler(),\n                          className:\n                            'absolute top-0 h-full w-4 cursor-col-resize user-select-none touch-none -right-2 z-10 flex justify-center before:absolute before:w-px before:inset-y-0 before:bg-border before:translate-x-px',\n                        }}\n                      />\n                    )}\n                  </TableHead>\n                )\n              })}\n            </TableRow>\n          ))}\n        </TableHeader>\n        <TableBody>\n          {table.getRowModel().rows?.length ? (\n            table.getRowModel().rows.map((row) => (\n              <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>\n                {row.getVisibleCells().map((cell) => (\n                  <TableCell key={cell.id} className=\"truncate\">\n                    {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                  </TableCell>\n                ))}\n              </TableRow>\n            ))\n          ) : (\n            <TableRow>\n              <TableCell colSpan={columns.length} className=\"h-24 text-center\">\n                No results.\n              </TableCell>\n            </TableRow>\n          )}\n        </TableBody>\n      </Table>\n      <p className=\"text-muted-foreground mt-4 text-center text-sm\">\n        Resizable and sortable columns made with{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://tanstack.com/table\"\n          target=\"_blank\"\n          rel=\"noopener noreferrer\"\n        >\n          TanStack Table\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/table/table-14.vue",
          "target": "components/ui/table-14.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport { ChevronDownIcon, ChevronUpIcon } from 'lucide-vue-next'\nimport { Input } from '@timui/vue'\nimport { Table } from '@timui/vue'\nimport { TableBody } from '@timui/vue'\nimport { TableCell } from '@timui/vue'\nimport { TableHead } from '@timui/vue'\nimport { TableHeader } from '@timui/vue'\nimport { TableRow } from '@timui/vue'\nimport { formatCurrency, tableUsers, type TableUser } from './table-demo-data'\n\ntype SortKey = 'name' | 'email' | 'location' | 'status' | 'balance' | 'performance'\n\nconst sortKey = ref<SortKey>('name')\nconst sortDirection = ref<'asc' | 'desc'>('asc')\n\nconst widths = ref({\n  name: 180,\n  email: 220,\n  location: 180,\n  status: 120,\n  balance: 120,\n  performance: 140,\n})\n\nconst rows = computed(() => {\n  return [...tableUsers].sort((left, right) => {\n    let leftValue: string | number = left[sortKey.value as keyof TableUser] as string | number\n    let rightValue: string | number = right[sortKey.value as keyof TableUser] as string | number\n\n    if (typeof leftValue === 'string' && typeof rightValue === 'string') {\n      const result = leftValue.localeCompare(rightValue)\n      return sortDirection.value === 'asc' ? result : -result\n    }\n\n    const result = Number(leftValue) - Number(rightValue)\n    return sortDirection.value === 'asc' ? result : -result\n  })\n})\n\nfunction toggleSort(next: SortKey) {\n  if (sortKey.value === next) {\n    sortDirection.value = sortDirection.value === 'asc' ? 'desc' : 'asc'\n    return\n  }\n\n  sortKey.value = next\n  sortDirection.value = 'asc'\n}\n\nfunction sortIcon(column: SortKey) {\n  if (sortKey.value !== column) {\n    return null\n  }\n\n  return sortDirection.value === 'asc' ? ChevronUpIcon : ChevronDownIcon\n}\n</script>\n\n<template>\n  <div class=\"space-y-4\">\n    <div class=\"grid gap-2 sm:grid-cols-2 lg:grid-cols-3\">\n      <label class=\"text-sm\">\n        Name Width\n        <Input type=\"range\" min=\"120\" max=\"260\" :value=\"widths.name\" @input=\"widths.name = Number(($event.target as HTMLInputElement).value)\" />\n      </label>\n      <label class=\"text-sm\">\n        Email Width\n        <Input type=\"range\" min=\"160\" max=\"320\" :value=\"widths.email\" @input=\"widths.email = Number(($event.target as HTMLInputElement).value)\" />\n      </label>\n      <label class=\"text-sm\">\n        Location Width\n        <Input type=\"range\" min=\"120\" max=\"260\" :value=\"widths.location\" @input=\"widths.location = Number(($event.target as HTMLInputElement).value)\" />\n      </label>\n    </div>\n\n    <Table class=\"table-fixed\" :style=\"{ width: `${widths.name + widths.email + widths.location + widths.status + widths.balance + widths.performance}px` }\">\n      <TableHeader>\n        <TableRow class=\"bg-muted/50\">\n          <TableHead class=\"cursor-pointer select-none\" :style=\"{ width: `${widths.name}px` }\" @click=\"toggleSort('name')\">\n            <span class=\"flex items-center justify-between gap-2\">\n              Name\n              <component :is=\"sortIcon('name')\" v-if=\"sortIcon('name')\" :size=\"16\" />\n            </span>\n          </TableHead>\n          <TableHead class=\"cursor-pointer select-none\" :style=\"{ width: `${widths.email}px` }\" @click=\"toggleSort('email')\">\n            <span class=\"flex items-center justify-between gap-2\">\n              Email\n              <component :is=\"sortIcon('email')\" v-if=\"sortIcon('email')\" :size=\"16\" />\n            </span>\n          </TableHead>\n          <TableHead class=\"cursor-pointer select-none\" :style=\"{ width: `${widths.location}px` }\" @click=\"toggleSort('location')\">\n            <span class=\"flex items-center justify-between gap-2\">\n              Location\n              <component :is=\"sortIcon('location')\" v-if=\"sortIcon('location')\" :size=\"16\" />\n            </span>\n          </TableHead>\n          <TableHead class=\"cursor-pointer select-none\" :style=\"{ width: `${widths.status}px` }\" @click=\"toggleSort('status')\">\n            <span class=\"flex items-center justify-between gap-2\">\n              Status\n              <component :is=\"sortIcon('status')\" v-if=\"sortIcon('status')\" :size=\"16\" />\n            </span>\n          </TableHead>\n          <TableHead class=\"cursor-pointer select-none text-right\" :style=\"{ width: `${widths.balance}px` }\" @click=\"toggleSort('balance')\">\n            <span class=\"flex items-center justify-end gap-2\">\n              Balance\n              <component :is=\"sortIcon('balance')\" v-if=\"sortIcon('balance')\" :size=\"16\" />\n            </span>\n          </TableHead>\n          <TableHead class=\"cursor-pointer select-none\" :style=\"{ width: `${widths.performance}px` }\" @click=\"toggleSort('performance')\">\n            <span class=\"flex items-center justify-between gap-2\">\n              Performance\n              <component :is=\"sortIcon('performance')\" v-if=\"sortIcon('performance')\" :size=\"16\" />\n            </span>\n          </TableHead>\n        </TableRow>\n      </TableHeader>\n\n      <TableBody>\n        <TableRow v-for=\"row in rows\" :key=\"row.id\">\n          <TableCell :style=\"{ width: `${widths.name}px` }\" class=\"truncate font-medium\">{{ row.name }}</TableCell>\n          <TableCell :style=\"{ width: `${widths.email}px` }\" class=\"truncate\">{{ row.email }}</TableCell>\n          <TableCell :style=\"{ width: `${widths.location}px` }\" class=\"truncate\">{{ row.flag }} {{ row.location }}</TableCell>\n          <TableCell :style=\"{ width: `${widths.status}px` }\">{{ row.status }}</TableCell>\n          <TableCell :style=\"{ width: `${widths.balance}px` }\" class=\"text-right\">{{ formatCurrency(row.balance) }}</TableCell>\n          <TableCell :style=\"{ width: `${widths.performance}px` }\">{{ row.performance }}</TableCell>\n        </TableRow>\n      </TableBody>\n    </Table>\n\n    <p class=\"text-muted-foreground mt-4 text-center text-sm\">\n      Resizable and sortable columns made with\n      <a class=\"hover:text-foreground underline\" href=\"https://tanstack.com/table\" target=\"_blank\" rel=\"noopener noreferrer\">\n        TanStack Table\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/table/table-14.html",
          "target": "components/ui/table-14.html",
          "type": "registry:component",
          "content": "<template>\n  <div><Table class=\"table-fixed\" style=\"${{\n          width: table.getCenterTotalSize(),\n        }}\"><TableHeader><!-- Loop table.getHeaderGroups() -->\n<TableRow key=\"${headerGroup.id}\" class=\"bg-muted/50\">${headerGroup.headers.map((header) => {\n                return (\n                  <TableHead\n                    key={header.id}\n                    className=\"relative h-10 border-t select-none last:[&>.cursor-col-resize]:opacity-0\"\n                    aria-sort={\n                      header.column.getIsSorted() === 'asc'\n                        ? 'ascending'\n                        : header.column.getIsSorted() === 'desc'\n                          ? 'descending'\n                          : 'none'\n                    }\n                    {...{\n                      colSpan: header.colSpan,\n                      style: {\n                        width: header.getSize(),\n                      },\n                    }}\n                  >\n                    {header.isPlaceholder ? null : (\n                      <div\n                        className={cn(\n                          header.column.getCanSort() &&\n                            'flex h-full cursor-pointer items-center justify-between gap-2 select-none'\n                        )}\n                        onClick={header.column.getToggleSortingHandler()}\n                        onKeyDown={(e) => {\n                          // Enhanced keyboard handling for sorting\n                          if (header.column.getCanSort() && (e.key === 'Enter' || e.key === ' ')) {\n                            e.preventDefault()\n                            header.column.getToggleSortingHandler()?.(e)\n                          }\n                        }}\n                        tabIndex={header.column.getCanSort() ? 0 : undefined}\n                      >\n                        <span className=\"truncate\">\n                          {flexRender(header.column.columnDef.header, header.getContext())}\n                        </span>\n                        {{\n                          asc: (\n                            <ChevronUpIcon\n                              className=\"shrink-0 opacity-60\"\n                              size={16}\n                              aria-hidden=\"true\"\n                            />\n                          ),\n                          desc: (\n                            <ChevronDownIcon\n                              className=\"shrink-0 opacity-60\"\n                              size={16}\n                              aria-hidden=\"true\"\n                            />\n                          ),\n                        }[header.column.getIsSorted() as string] ?? null}\n                      </div>\n                    )}\n                    {header.column.getCanResize() && (\n                      <div\n                        {...{\n                          onDoubleClick: () => header.column.resetSize(),\n                          onMouseDown: header.getResizeHandler(),\n                          onTouchStart: header.getResizeHandler(),\n                          className:\n                            'absolute top-0 h-full w-4 cursor-col-resize user-select-none touch-none -right-2 z-10 flex justify-center before:absolute before:w-px before:inset-y-0 before:bg-border before:translate-x-px',\n                        }}\n                      />\n                    )}\n                  </TableHead>\n                )\n              })}</TableRow>\n<!-- End Loop --></TableHeader><TableBody><!-- if table.getRowModel().rows?.length -->\n${table.getRowModel().rows.map((row) => (\n              <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>\n                {row.getVisibleCells().map((cell) => (\n                  <TableCell key={cell.id} className=\"truncate\">\n                    {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                  </TableCell>\n                ))}\n              </TableRow>\n            ))}\n<!-- else -->\n<TableRow><TableCell colspan=\"${columns.length}\" class=\"h-24 text-center\">No results.\n              </TableCell></TableRow>\n<!-- endif --></TableBody></Table><p class=\"text-muted-foreground mt-4 text-center text-sm\">Resizable and sortable columns made with${' '}<a class=\"hover:text-foreground underline\" href=\"https://tanstack.com/table\" target=\"_blank\" rel=\"noopener noreferrer\">TanStack Table\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/table/table-14.wxml",
          "target": "components/ui/table-14/table-14.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><table class=\"table-fixed\" style=\"{{{\n          width: table.getCenterTotalSize(),\n        }}}\"><tableheader><tablerow wx:for=\"{{table.getHeaderGroups()}}\" wx:for-item=\"headerGroup\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{headerGroup.id}}\" class=\"bg-muted/50\">{{ headerGroup.headers.map((header) => {\n                return (\n                  <TableHead\n                    key={header.id}\n                    className=\"relative h-10 border-t select-none last:[&>.cursor-col-resize]:opacity-0\"\n                    aria-sort={\n                      header.column.getIsSorted() === 'asc'\n                        ? 'ascending'\n                        : header.column.getIsSorted() === 'desc'\n                          ? 'descending'\n                          : 'none'\n                    }\n                    {...{\n                      colSpan: header.colSpan,\n                      style: {\n                        width: header.getSize(),\n                      },\n                    }}\n                  >\n                    {header.isPlaceholder ? null : (\n                      <div\n                        className={cn(\n                          header.column.getCanSort() &&\n                            'flex h-full cursor-pointer items-center justify-between gap-2 select-none'\n                        )}\n                        onClick={header.column.getToggleSortingHandler()}\n                        onKeyDown={(e) => {\n                          // Enhanced keyboard handling for sorting\n                          if (header.column.getCanSort() && (e.key === 'Enter' || e.key === ' ')) {\n                            e.preventDefault()\n                            header.column.getToggleSortingHandler()?.(e)\n                          }\n                        }}\n                        tabIndex={header.column.getCanSort() ? 0 : undefined}\n                      >\n                        <span className=\"truncate\">\n                          {flexRender(header.column.columnDef.header, header.getContext())}\n                        </span>\n                        {{\n                          asc: (\n                            <ChevronUpIcon\n                              className=\"shrink-0 opacity-60\"\n                              size={16}\n                              aria-hidden=\"true\"\n                            />\n                          ),\n                          desc: (\n                            <ChevronDownIcon\n                              className=\"shrink-0 opacity-60\"\n                              size={16}\n                              aria-hidden=\"true\"\n                            />\n                          ),\n                        }[header.column.getIsSorted() as string] ?? null}\n                      </div>\n                    )}\n                    {header.column.getCanResize() && (\n                      <div\n                        {...{\n                          onDoubleClick: () => header.column.resetSize(),\n                          onMouseDown: header.getResizeHandler(),\n                          onTouchStart: header.getResizeHandler(),\n                          className:\n                            'absolute top-0 h-full w-4 cursor-col-resize user-select-none touch-none -right-2 z-10 flex justify-center before:absolute before:w-px before:inset-y-0 before:bg-border before:translate-x-px',\n                        }}\n                      />\n                    )}\n                  </TableHead>\n                )\n              }) }}</tablerow></tableheader><tablebody><block wx:if=\"{{table.getRowModel().rows?.length}}\">\n{{ table.getRowModel().rows.map((row) => (\n              <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>\n                {row.getVisibleCells().map((cell) => (\n                  <TableCell key={cell.id} className=\"truncate\">\n                    {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                  </TableCell>\n                ))}\n              </TableRow>\n            )) }}\n</block>\n<block wx:else>\n<tablerow><tablecell colspan=\"{{columns.length}}\" class=\"h-24 text-center\">No results.\n              </tablecell></tablerow>\n</block></tablebody></table><text class=\"text-muted-foreground mt-4 text-center text-sm\">Resizable and sortable columns made with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://tanstack.com/table\" target=\"_blank\" rel=\"noopener noreferrer\">TanStack Table\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "table",
          "tanstack",
          "flag",
          "sort",
          "resize"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "table-14",
          "group": "table",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "table-14",
              "path": "registry/default/components/table/table-14.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "table-14",
              "path": "registry/default/components/table/table-14.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "table-14",
              "path": "registry/default/components/table/table-14.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "table-14",
              "path": "registry/default/components/table/table-14.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@tanstack/react-table",
              "@timui/core",
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tables",
        "title": "Table · Interactive State"
      },
      "categories": [
        "tables",
        "table"
      ]
    },
    {
      "name": "table-15",
      "type": "registry:component",
      "dependencies": [
        "@tanstack/react-table",
        "@timui/react"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dropdown-menu.json",
        "https://ui.timkit.cn/r/table.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/table/table-15.tsx",
          "type": "registry:component",
          "target": "components/ui/table-15.tsx",
          "content": "'use client'\n\nimport { CSSProperties, useEffect, useState } from 'react'\nimport {\n  Column,\n  ColumnDef,\n  flexRender,\n  getCoreRowModel,\n  getSortedRowModel,\n  SortingState,\n  useReactTable,\n} from '@tanstack/react-table'\nimport {\n  Button,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuTrigger,\n  Table,\n  TableBody,\n  TableCell,\n  TableHead,\n  TableHeader,\n  TableRow,\n} from '@timui/react'\nimport { ArrowLeftToLineIcon, ArrowRightToLineIcon, EllipsisIcon, PinOffIcon } from 'lucide-react'\n\ntype Item = {\n  id: string\n  name: string\n  email: string\n  location: string\n  flag: string\n  status: 'Active' | 'Inactive' | 'Pending'\n  balance: number\n  department: string\n  role: string\n  joinDate: string\n  lastActive: string\n  performance: 'Good' | 'Very Good' | 'Excellent' | 'Outstanding'\n}\n\n// Helper function to compute pinning styles for columns\nconst getPinningStyles = (column: Column<Item>): CSSProperties => {\n  const isPinned = column.getIsPinned()\n  return {\n    left: isPinned === 'left' ? `${column.getStart('left')}px` : undefined,\n    right: isPinned === 'right' ? `${column.getAfter('right')}px` : undefined,\n    position: isPinned ? 'sticky' : 'relative',\n    width: column.getSize(),\n    zIndex: isPinned ? 1 : 0,\n  }\n}\n\nconst columns: ColumnDef<Item>[] = [\n  {\n    header: 'Name',\n    accessorKey: 'name',\n    cell: ({ row }) => <div className=\"truncate font-medium\">{row.getValue('name')}</div>,\n  },\n  {\n    header: 'Email',\n    accessorKey: 'email',\n  },\n  {\n    header: 'Location',\n    accessorKey: 'location',\n    cell: ({ row }) => (\n      <div className=\"truncate\">\n        <span className=\"text-lg leading-none\">{row.original.flag}</span> {row.getValue('location')}\n      </div>\n    ),\n  },\n  {\n    header: 'Status',\n    accessorKey: 'status',\n  },\n  {\n    header: 'Balance',\n    accessorKey: 'balance',\n    cell: ({ row }) => {\n      const amount = parseFloat(row.getValue('balance'))\n      const formatted = new Intl.NumberFormat('en-US', {\n        style: 'currency',\n        currency: 'USD',\n      }).format(amount)\n      return formatted\n    },\n  },\n  {\n    header: 'Department',\n    accessorKey: 'department',\n  },\n  {\n    header: 'Role',\n    accessorKey: 'role',\n  },\n  {\n    header: 'Join Date',\n    accessorKey: 'joinDate',\n  },\n  {\n    header: 'Last Active',\n    accessorKey: 'lastActive',\n  },\n  {\n    header: 'Performance',\n    accessorKey: 'performance',\n  },\n]\n\nexport default function Component() {\n  const [data, setData] = useState<Item[]>([])\n  const [sorting, setSorting] = useState<SortingState>([])\n\n  useEffect(() => {\n    async function fetchPosts() {\n      const res = await fetch(\n        'https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/users-01_fertyx.json'\n      )\n      const data = await res.json()\n      setData(data.slice(0, 5)) // Limit to 5 items\n    }\n    fetchPosts()\n  }, [])\n\n  const table = useReactTable({\n    data,\n    columns,\n    columnResizeMode: 'onChange',\n    getCoreRowModel: getCoreRowModel(),\n    getSortedRowModel: getSortedRowModel(),\n    onSortingChange: setSorting,\n    state: {\n      sorting,\n    },\n    enableSortingRemoval: false,\n  })\n\n  return (\n    <div>\n      <Table\n        className=\"[&_td]:border-border [&_th]:border-border table-fixed border-separate border-spacing-0 [&_tfoot_td]:border-t [&_th]:border-b [&_tr]:border-none [&_tr:not(:last-child)_td]:border-b\"\n        style={{\n          width: table.getTotalSize(),\n        }}\n      >\n        <TableHeader>\n          {table.getHeaderGroups().map((headerGroup) => (\n            <TableRow key={headerGroup.id} className=\"bg-muted/50\">\n              {headerGroup.headers.map((header) => {\n                const { column } = header\n                const isPinned = column.getIsPinned()\n                const isLastLeftPinned = isPinned === 'left' && column.getIsLastColumn('left')\n                const isFirstRightPinned = isPinned === 'right' && column.getIsFirstColumn('right')\n\n                return (\n                  <TableHead\n                    key={header.id}\n                    className=\"[&[data-pinned][data-last-col]]:border-border data-pinned:bg-muted/90 relative h-10 truncate border-t data-pinned:backdrop-blur-xs [&:not([data-pinned]):has(+[data-pinned])_div.cursor-col-resize:last-child]:opacity-0 [&[data-last-col=left]_div.cursor-col-resize:last-child]:opacity-0 [&[data-pinned=left][data-last-col=left]]:border-r [&[data-pinned=right]:last-child_div.cursor-col-resize:last-child]:opacity-0 [&[data-pinned=right][data-last-col=right]]:border-l\"\n                    colSpan={header.colSpan}\n                    style={{ ...getPinningStyles(column) }}\n                    data-pinned={isPinned || undefined}\n                    data-last-col={\n                      isLastLeftPinned ? 'left' : isFirstRightPinned ? 'right' : undefined\n                    }\n                  >\n                    <div className=\"flex items-center justify-between gap-2\">\n                      <span className=\"truncate\">\n                        {header.isPlaceholder\n                          ? null\n                          : flexRender(header.column.columnDef.header, header.getContext())}\n                      </span>\n                      {/* Pin/Unpin column controls with enhanced accessibility */}\n                      {!header.isPlaceholder &&\n                        header.column.getCanPin() &&\n                        (header.column.getIsPinned() ? (\n                          <Button\n                            size=\"icon\"\n                            variant=\"ghost\"\n                            className=\"-mr-1 size-7 shadow-none\"\n                            onClick={() => header.column.pin(false)}\n                            aria-label={`Unpin ${header.column.columnDef.header as string} column`}\n                            title={`Unpin ${header.column.columnDef.header as string} column`}\n                          >\n                            <PinOffIcon className=\"opacity-60\" size={16} aria-hidden=\"true\" />\n                          </Button>\n                        ) : (\n                          <DropdownMenu>\n                            <DropdownMenuTrigger asChild>\n                              <Button\n                                size=\"icon\"\n                                variant=\"ghost\"\n                                className=\"-mr-1 size-7 shadow-none\"\n                                aria-label={`Pin options for ${header.column.columnDef.header as string} column`}\n                                title={`Pin options for ${header.column.columnDef.header as string} column`}\n                              >\n                                <EllipsisIcon className=\"opacity-60\" size={16} aria-hidden=\"true\" />\n                              </Button>\n                            </DropdownMenuTrigger>\n                            <DropdownMenuContent align=\"end\">\n                              <DropdownMenuItem onClick={() => header.column.pin('left')}>\n                                <ArrowLeftToLineIcon\n                                  size={16}\n                                  className=\"opacity-60\"\n                                  aria-hidden=\"true\"\n                                />\n                                Stick to left\n                              </DropdownMenuItem>\n                              <DropdownMenuItem onClick={() => header.column.pin('right')}>\n                                <ArrowRightToLineIcon\n                                  size={16}\n                                  className=\"opacity-60\"\n                                  aria-hidden=\"true\"\n                                />\n                                Stick to right\n                              </DropdownMenuItem>\n                            </DropdownMenuContent>\n                          </DropdownMenu>\n                        ))}\n                      {header.column.getCanResize() && (\n                        <div\n                          {...{\n                            onDoubleClick: () => header.column.resetSize(),\n                            onMouseDown: header.getResizeHandler(),\n                            onTouchStart: header.getResizeHandler(),\n                            className:\n                              'absolute top-0 h-full w-4 cursor-col-resize user-select-none touch-none -right-2 z-10 flex justify-center before:absolute before:w-px before:inset-y-0 before:bg-border before:-translate-x-px',\n                          }}\n                        />\n                      )}\n                    </div>\n                  </TableHead>\n                )\n              })}\n            </TableRow>\n          ))}\n        </TableHeader>\n        <TableBody>\n          {table.getRowModel().rows?.length ? (\n            table.getRowModel().rows.map((row) => (\n              <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>\n                {row.getVisibleCells().map((cell) => {\n                  const { column } = cell\n                  const isPinned = column.getIsPinned()\n                  const isLastLeftPinned = isPinned === 'left' && column.getIsLastColumn('left')\n                  const isFirstRightPinned =\n                    isPinned === 'right' && column.getIsFirstColumn('right')\n\n                  return (\n                    <TableCell\n                      key={cell.id}\n                      className=\"[&[data-pinned][data-last-col]]:border-border data-pinned:bg-background/90 truncate data-pinned:backdrop-blur-xs [&[data-pinned=left][data-last-col=left]]:border-r [&[data-pinned=right][data-last-col=right]]:border-l\"\n                      style={{ ...getPinningStyles(column) }}\n                      data-pinned={isPinned || undefined}\n                      data-last-col={\n                        isLastLeftPinned ? 'left' : isFirstRightPinned ? 'right' : undefined\n                      }\n                    >\n                      {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                    </TableCell>\n                  )\n                })}\n              </TableRow>\n            ))\n          ) : (\n            <TableRow>\n              <TableCell colSpan={columns.length} className=\"h-24 text-center\">\n                No results.\n              </TableCell>\n            </TableRow>\n          )}\n        </TableBody>\n      </Table>\n      <p className=\"text-muted-foreground mt-4 text-center text-sm\">\n        Pinnable columns made with{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://tanstack.com/table\"\n          target=\"_blank\"\n          rel=\"noopener noreferrer\"\n        >\n          TanStack Table\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/table/table-15.vue",
          "target": "components/ui/table-15.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport { ArrowLeftToLineIcon, ArrowRightToLineIcon, PinOffIcon } from 'lucide-vue-next'\nimport { Button } from '@timui/vue'\nimport { Table } from '@timui/vue'\nimport { TableBody } from '@timui/vue'\nimport { TableCell } from '@timui/vue'\nimport { TableHead } from '@timui/vue'\nimport { TableHeader } from '@timui/vue'\nimport { TableRow } from '@timui/vue'\nimport { formatCurrency, tableUsers } from './table-demo-data'\n\ntype ColumnKey = 'name' | 'email' | 'location' | 'status' | 'balance'\n\ntype ColumnConfig = {\n  key: ColumnKey\n  label: string\n  width: number\n  align?: 'left' | 'right'\n}\n\nconst columns: ColumnConfig[] = [\n  { key: 'name', label: 'Name', width: 180 },\n  { key: 'email', label: 'Email', width: 220 },\n  { key: 'location', label: 'Location', width: 180 },\n  { key: 'status', label: 'Status', width: 120 },\n  { key: 'balance', label: 'Balance', width: 140, align: 'right' },\n]\n\nconst rows = tableUsers.slice(0, 10)\nconst leftPinned = ref<ColumnKey | null>('name')\nconst rightPinned = ref<ColumnKey | null>('balance')\n\nconst tableWidth = computed(() => columns.reduce((total, column) => total + column.width, 0))\n\nfunction pinLeft(key: ColumnKey) {\n  leftPinned.value = key\n  if (rightPinned.value === key) {\n    rightPinned.value = null\n  }\n}\n\nfunction pinRight(key: ColumnKey) {\n  rightPinned.value = key\n  if (leftPinned.value === key) {\n    leftPinned.value = null\n  }\n}\n\nfunction unpin(key: ColumnKey) {\n  if (leftPinned.value === key) {\n    leftPinned.value = null\n  }\n\n  if (rightPinned.value === key) {\n    rightPinned.value = null\n  }\n}\n\nfunction cellStyle(column: ColumnConfig) {\n  const baseStyle: Record<string, string> = {\n    width: `${column.width}px`,\n  }\n\n  if (leftPinned.value === column.key) {\n    baseStyle.position = 'sticky'\n    baseStyle.left = '0px'\n    baseStyle.zIndex = '20'\n    baseStyle.background = 'var(--background)'\n  }\n\n  if (rightPinned.value === column.key) {\n    baseStyle.position = 'sticky'\n    baseStyle.right = '0px'\n    baseStyle.zIndex = '20'\n    baseStyle.background = 'var(--background)'\n  }\n\n  return baseStyle\n}\n\nfunction rowValue(row: (typeof rows)[number], column: ColumnConfig) {\n  if (column.key === 'balance') {\n    return formatCurrency(row.balance)\n  }\n\n  if (column.key === 'location') {\n    return `${row.flag} ${row.location}`\n  }\n\n  return row[column.key]\n}\n</script>\n\n<template>\n  <div>\n    <Table\n      class=\"[&_td]:border-border [&_th]:border-border table-fixed border-separate border-spacing-0 [&_th]:border-b [&_tr]:border-none [&_tr:not(:last-child)_td]:border-b\"\n      :style=\"{ width: `${tableWidth}px` }\"\n    >\n      <TableHeader>\n        <TableRow class=\"bg-muted/50\">\n          <TableHead\n            v-for=\"column in columns\"\n            :key=\"column.key\"\n            :style=\"cellStyle(column)\"\n            class=\"h-11\"\n          >\n            <div class=\"flex items-center justify-between gap-2\">\n              <span>{{ column.label }}</span>\n              <div class=\"flex items-center gap-1\">\n                <Button size=\"icon\" variant=\"ghost\" class=\"size-6\" @click=\"pinLeft(column.key)\" :aria-label=\"`Pin ${column.label} left`\">\n                  <ArrowLeftToLineIcon :size=\"14\" />\n                </Button>\n                <Button size=\"icon\" variant=\"ghost\" class=\"size-6\" @click=\"pinRight(column.key)\" :aria-label=\"`Pin ${column.label} right`\">\n                  <ArrowRightToLineIcon :size=\"14\" />\n                </Button>\n                <Button size=\"icon\" variant=\"ghost\" class=\"size-6\" @click=\"unpin(column.key)\" :aria-label=\"`Unpin ${column.label}`\">\n                  <PinOffIcon :size=\"14\" />\n                </Button>\n              </div>\n            </div>\n          </TableHead>\n        </TableRow>\n      </TableHeader>\n\n      <TableBody>\n        <TableRow v-for=\"row in rows\" :key=\"row.id\">\n          <TableCell\n            v-for=\"column in columns\"\n            :key=\"`${row.id}-${column.key}`\"\n            :style=\"cellStyle(column)\"\n            :class=\"column.align === 'right' ? 'text-right' : undefined\"\n          >\n            {{ rowValue(row, column) }}\n          </TableCell>\n        </TableRow>\n      </TableBody>\n    </Table>\n\n    <p class=\"text-muted-foreground mt-4 text-center text-sm\">\n      Pinnable columns made with\n      <a class=\"hover:text-foreground underline\" href=\"https://tanstack.com/table\" target=\"_blank\" rel=\"noopener noreferrer\">\n        TanStack Table\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/table/table-15.html",
          "target": "components/ui/table-15.html",
          "type": "registry:component",
          "content": "<template>\n  <div><Table class=\"[&_td]:border-border [&_th]:border-border table-fixed border-separate border-spacing-0 [&_tfoot_td]:border-t [&_th]:border-b [&_tr]:border-none [&_tr:not(:last-child)_td]:border-b\" style=\"${{\n          width: table.getTotalSize(),\n        }}\"><TableHeader><!-- Loop table.getHeaderGroups() -->\n<TableRow key=\"${headerGroup.id}\" class=\"bg-muted/50\">${headerGroup.headers.map((header) => {\n                const { column } = header\n                const isPinned = column.getIsPinned()\n                const isLastLeftPinned = isPinned === 'left' && column.getIsLastColumn('left')\n                const isFirstRightPinned = isPinned === 'right' && column.getIsFirstColumn('right')\n\n                return (\n                  <TableHead\n                    key={header.id}\n                    className=\"[&[data-pinned][data-last-col]]:border-border data-pinned:bg-muted/90 relative h-10 truncate border-t data-pinned:backdrop-blur-xs [&:not([data-pinned]):has(+[data-pinned])_div.cursor-col-resize:last-child]:opacity-0 [&[data-last-col=left]_div.cursor-col-resize:last-child]:opacity-0 [&[data-pinned=left][data-last-col=left]]:border-r [&[data-pinned=right]:last-child_div.cursor-col-resize:last-child]:opacity-0 [&[data-pinned=right][data-last-col=right]]:border-l\"\n                    colSpan={header.colSpan}\n                    style={{ ...getPinningStyles(column) }}\n                    data-pinned={isPinned || undefined}\n                    data-last-col={\n                      isLastLeftPinned ? 'left' : isFirstRightPinned ? 'right' : undefined\n                    }\n                  >\n                    <div className=\"flex items-center justify-between gap-2\">\n                      <span className=\"truncate\">\n                        {header.isPlaceholder\n                          ? null\n                          : flexRender(header.column.columnDef.header, header.getContext())}\n                      </span>\n                      {/* Pin/Unpin column controls with enhanced accessibility */}\n                      {!header.isPlaceholder &&\n                        header.column.getCanPin() &&\n                        (header.column.getIsPinned() ? (\n                          <Button\n                            size=\"icon\"\n                            variant=\"ghost\"\n                            className=\"-mr-1 size-7 shadow-none\"\n                            onClick={() => header.column.pin(false)}\n                            aria-label={`Unpin ${header.column.columnDef.header as string} column`}\n                            title={`Unpin ${header.column.columnDef.header as string} column`}\n                          >\n                            <PinOffIcon className=\"opacity-60\" size={16} aria-hidden=\"true\" />\n                          </Button>\n                        ) : (\n                          <DropdownMenu>\n                            <DropdownMenuTrigger asChild>\n                              <Button\n                                size=\"icon\"\n                                variant=\"ghost\"\n                                className=\"-mr-1 size-7 shadow-none\"\n                                aria-label={`Pin options for ${header.column.columnDef.header as string} column`}\n                                title={`Pin options for ${header.column.columnDef.header as string} column`}\n                              >\n                                <EllipsisIcon className=\"opacity-60\" size={16} aria-hidden=\"true\" />\n                              </Button>\n                            </DropdownMenuTrigger>\n                            <DropdownMenuContent align=\"end\">\n                              <DropdownMenuItem onClick={() => header.column.pin('left')}>\n                                <ArrowLeftToLineIcon\n                                  size={16}\n                                  className=\"opacity-60\"\n                                  aria-hidden=\"true\"\n                                />\n                                Stick to left\n                              </DropdownMenuItem>\n                              <DropdownMenuItem onClick={() => header.column.pin('right')}>\n                                <ArrowRightToLineIcon\n                                  size={16}\n                                  className=\"opacity-60\"\n                                  aria-hidden=\"true\"\n                                />\n                                Stick to right\n                              </DropdownMenuItem>\n                            </DropdownMenuContent>\n                          </DropdownMenu>\n                        ))}\n                      {header.column.getCanResize() && (\n                        <div\n                          {...{\n                            onDoubleClick: () => header.column.resetSize(),\n                            onMouseDown: header.getResizeHandler(),\n                            onTouchStart: header.getResizeHandler(),\n                            className:\n                              'absolute top-0 h-full w-4 cursor-col-resize user-select-none touch-none -right-2 z-10 flex justify-center before:absolute before:w-px before:inset-y-0 before:bg-border before:-translate-x-px',\n                          }}\n                        />\n                      )}\n                    </div>\n                  </TableHead>\n                )\n              })}</TableRow>\n<!-- End Loop --></TableHeader><TableBody><!-- if table.getRowModel().rows?.length -->\n${table.getRowModel().rows.map((row) => (\n              <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>\n                {row.getVisibleCells().map((cell) => {\n                  const { column } = cell\n                  const isPinned = column.getIsPinned()\n                  const isLastLeftPinned = isPinned === 'left' && column.getIsLastColumn('left')\n                  const isFirstRightPinned =\n                    isPinned === 'right' && column.getIsFirstColumn('right')\n\n                  return (\n                    <TableCell\n                      key={cell.id}\n                      className=\"[&[data-pinned][data-last-col]]:border-border data-pinned:bg-background/90 truncate data-pinned:backdrop-blur-xs [&[data-pinned=left][data-last-col=left]]:border-r [&[data-pinned=right][data-last-col=right]]:border-l\"\n                      style={{ ...getPinningStyles(column) }}\n                      data-pinned={isPinned || undefined}\n                      data-last-col={\n                        isLastLeftPinned ? 'left' : isFirstRightPinned ? 'right' : undefined\n                      }\n                    >\n                      {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                    </TableCell>\n                  )\n                })}\n              </TableRow>\n            ))}\n<!-- else -->\n<TableRow><TableCell colspan=\"${columns.length}\" class=\"h-24 text-center\">No results.\n              </TableCell></TableRow>\n<!-- endif --></TableBody></Table><p class=\"text-muted-foreground mt-4 text-center text-sm\">Pinnable columns made with${' '}<a class=\"hover:text-foreground underline\" href=\"https://tanstack.com/table\" target=\"_blank\" rel=\"noopener noreferrer\">TanStack Table\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/table/table-15.wxml",
          "target": "components/ui/table-15/table-15.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><table class=\"[&_td]:border-border [&_th]:border-border table-fixed border-separate border-spacing-0 [&_tfoot_td]:border-t [&_th]:border-b [&_tr]:border-none [&_tr:not(:last-child)_td]:border-b\" style=\"{{{\n          width: table.getTotalSize(),\n        }}}\"><tableheader><tablerow wx:for=\"{{table.getHeaderGroups()}}\" wx:for-item=\"headerGroup\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{headerGroup.id}}\" class=\"bg-muted/50\">{{ headerGroup.headers.map((header) => {\n                const { column } = header\n                const isPinned = column.getIsPinned()\n                const isLastLeftPinned = isPinned === 'left' && column.getIsLastColumn('left')\n                const isFirstRightPinned = isPinned === 'right' && column.getIsFirstColumn('right')\n\n                return (\n                  <TableHead\n                    key={header.id}\n                    className=\"[&[data-pinned][data-last-col]]:border-border data-pinned:bg-muted/90 relative h-10 truncate border-t data-pinned:backdrop-blur-xs [&:not([data-pinned]):has(+[data-pinned])_div.cursor-col-resize:last-child]:opacity-0 [&[data-last-col=left]_div.cursor-col-resize:last-child]:opacity-0 [&[data-pinned=left][data-last-col=left]]:border-r [&[data-pinned=right]:last-child_div.cursor-col-resize:last-child]:opacity-0 [&[data-pinned=right][data-last-col=right]]:border-l\"\n                    colSpan={header.colSpan}\n                    style={{ ...getPinningStyles(column) }}\n                    data-pinned={isPinned || undefined}\n                    data-last-col={\n                      isLastLeftPinned ? 'left' : isFirstRightPinned ? 'right' : undefined\n                    }\n                  >\n                    <div className=\"flex items-center justify-between gap-2\">\n                      <span className=\"truncate\">\n                        {header.isPlaceholder\n                          ? null\n                          : flexRender(header.column.columnDef.header, header.getContext())}\n                      </span>\n                      {/* Pin/Unpin column controls with enhanced accessibility */}\n                      {!header.isPlaceholder &&\n                        header.column.getCanPin() &&\n                        (header.column.getIsPinned() ? (\n                          <Button\n                            size=\"icon\"\n                            variant=\"ghost\"\n                            className=\"-mr-1 size-7 shadow-none\"\n                            onClick={() => header.column.pin(false)}\n                            aria-label={`Unpin ${header.column.columnDef.header as string} column`}\n                            title={`Unpin ${header.column.columnDef.header as string} column`}\n                          >\n                            <PinOffIcon className=\"opacity-60\" size={16} aria-hidden=\"true\" />\n                          </Button>\n                        ) : (\n                          <DropdownMenu>\n                            <DropdownMenuTrigger asChild>\n                              <Button\n                                size=\"icon\"\n                                variant=\"ghost\"\n                                className=\"-mr-1 size-7 shadow-none\"\n                                aria-label={`Pin options for ${header.column.columnDef.header as string} column`}\n                                title={`Pin options for ${header.column.columnDef.header as string} column`}\n                              >\n                                <EllipsisIcon className=\"opacity-60\" size={16} aria-hidden=\"true\" />\n                              </Button>\n                            </DropdownMenuTrigger>\n                            <DropdownMenuContent align=\"end\">\n                              <DropdownMenuItem onClick={() => header.column.pin('left')}>\n                                <ArrowLeftToLineIcon\n                                  size={16}\n                                  className=\"opacity-60\"\n                                  aria-hidden=\"true\"\n                                />\n                                Stick to left\n                              </DropdownMenuItem>\n                              <DropdownMenuItem onClick={() => header.column.pin('right')}>\n                                <ArrowRightToLineIcon\n                                  size={16}\n                                  className=\"opacity-60\"\n                                  aria-hidden=\"true\"\n                                />\n                                Stick to right\n                              </DropdownMenuItem>\n                            </DropdownMenuContent>\n                          </DropdownMenu>\n                        ))}\n                      {header.column.getCanResize() && (\n                        <div\n                          {...{\n                            onDoubleClick: () => header.column.resetSize(),\n                            onMouseDown: header.getResizeHandler(),\n                            onTouchStart: header.getResizeHandler(),\n                            className:\n                              'absolute top-0 h-full w-4 cursor-col-resize user-select-none touch-none -right-2 z-10 flex justify-center before:absolute before:w-px before:inset-y-0 before:bg-border before:-translate-x-px',\n                          }}\n                        />\n                      )}\n                    </div>\n                  </TableHead>\n                )\n              }) }}</tablerow></tableheader><tablebody><block wx:if=\"{{table.getRowModel().rows?.length}}\">\n{{ table.getRowModel().rows.map((row) => (\n              <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>\n                {row.getVisibleCells().map((cell) => {\n                  const { column } = cell\n                  const isPinned = column.getIsPinned()\n                  const isLastLeftPinned = isPinned === 'left' && column.getIsLastColumn('left')\n                  const isFirstRightPinned =\n                    isPinned === 'right' && column.getIsFirstColumn('right')\n\n                  return (\n                    <TableCell\n                      key={cell.id}\n                      className=\"[&[data-pinned][data-last-col]]:border-border data-pinned:bg-background/90 truncate data-pinned:backdrop-blur-xs [&[data-pinned=left][data-last-col=left]]:border-r [&[data-pinned=right][data-last-col=right]]:border-l\"\n                      style={{ ...getPinningStyles(column) }}\n                      data-pinned={isPinned || undefined}\n                      data-last-col={\n                        isLastLeftPinned ? 'left' : isFirstRightPinned ? 'right' : undefined\n                      }\n                    >\n                      {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                    </TableCell>\n                  )\n                })}\n              </TableRow>\n            )) }}\n</block>\n<block wx:else>\n<tablerow><tablecell colspan=\"{{columns.length}}\" class=\"h-24 text-center\">No results.\n              </tablecell></tablerow>\n</block></tablebody></table><text class=\"text-muted-foreground mt-4 text-center text-sm\">Pinnable columns made with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://tanstack.com/table\" target=\"_blank\" rel=\"noopener noreferrer\">TanStack Table\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "table",
          "tanstack",
          "flag",
          "sticky",
          "resize"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "table-15",
          "group": "table",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "table-15",
              "path": "registry/default/components/table/table-15.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "table-15",
              "path": "registry/default/components/table/table-15.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "table-15",
              "path": "registry/default/components/table/table-15.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "table-15",
              "path": "registry/default/components/table/table-15.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@tanstack/react-table",
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tables",
        "title": "Table · Interactive State"
      },
      "categories": [
        "tables",
        "table"
      ]
    },
    {
      "name": "table-16",
      "type": "registry:component",
      "dependencies": [
        "@dnd-kit/core",
        "@dnd-kit/modifiers",
        "@dnd-kit/sortable",
        "@dnd-kit/utilities",
        "@tanstack/react-table",
        "@timui/react"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dropdown-menu.json",
        "https://ui.timkit.cn/r/table.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/table/table-16.tsx",
          "type": "registry:component",
          "target": "components/ui/table-16.tsx",
          "content": "'use client'\n\nimport { CSSProperties, useEffect, useId, useState } from 'react'\nimport {\n  closestCenter,\n  DndContext,\n  KeyboardSensor,\n  MouseSensor,\n  TouchSensor,\n  useSensor,\n  useSensors,\n  type DragEndEvent,\n} from '@dnd-kit/core'\nimport { restrictToHorizontalAxis } from '@dnd-kit/modifiers'\nimport {\n  arrayMove,\n  horizontalListSortingStrategy,\n  SortableContext,\n  useSortable,\n} from '@dnd-kit/sortable'\nimport { CSS } from '@dnd-kit/utilities'\nimport {\n  Cell,\n  ColumnDef,\n  flexRender,\n  getCoreRowModel,\n  getSortedRowModel,\n  Header,\n  SortingState,\n  useReactTable,\n} from '@tanstack/react-table'\nimport { Button, Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@timui/react'\nimport { ChevronDownIcon, ChevronUpIcon, GripVerticalIcon } from 'lucide-react'\n\ntype Item = {\n  id: string\n  name: string\n  email: string\n  location: string\n  flag: string\n  status: 'Active' | 'Inactive' | 'Pending'\n  balance: number\n}\n\nconst columns: ColumnDef<Item>[] = [\n  {\n    id: 'name',\n    header: 'Name',\n    accessorKey: 'name',\n    cell: ({ row }) => <div className=\"truncate font-medium\">{row.getValue('name')}</div>,\n    sortUndefined: 'last',\n    sortDescFirst: false,\n  },\n  {\n    id: 'email',\n    header: 'Email',\n    accessorKey: 'email',\n  },\n  {\n    id: 'location',\n    header: 'Location',\n    accessorKey: 'location',\n    cell: ({ row }) => (\n      <div className=\"truncate\">\n        <span className=\"text-lg leading-none\">{row.original.flag}</span> {row.getValue('location')}\n      </div>\n    ),\n  },\n  {\n    id: 'status',\n    header: 'Status',\n    accessorKey: 'status',\n  },\n  {\n    id: 'balance',\n    header: 'Balance',\n    accessorKey: 'balance',\n    cell: ({ row }) => {\n      const amount = parseFloat(row.getValue('balance'))\n      const formatted = new Intl.NumberFormat('en-US', {\n        style: 'currency',\n        currency: 'USD',\n      }).format(amount)\n      return formatted\n    },\n  },\n]\n\nexport default function Component() {\n  const [data, setData] = useState<Item[]>([])\n  const [sorting, setSorting] = useState<SortingState>([])\n  const [columnOrder, setColumnOrder] = useState<string[]>(\n    columns.map((column) => column.id as string)\n  )\n\n  useEffect(() => {\n    async function fetchPosts() {\n      const res = await fetch(\n        'https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/users-01_fertyx.json'\n      )\n      const data = await res.json()\n      setData(data.slice(0, 5)) // Limit to 5 items\n    }\n    fetchPosts()\n  }, [])\n\n  const table = useReactTable({\n    data,\n    columns,\n    columnResizeMode: 'onChange',\n    getCoreRowModel: getCoreRowModel(),\n    getSortedRowModel: getSortedRowModel(),\n    onSortingChange: setSorting,\n    state: {\n      sorting,\n      columnOrder,\n    },\n    onColumnOrderChange: setColumnOrder,\n    enableSortingRemoval: false,\n  })\n\n  // reorder columns after drag & drop\n  function handleDragEnd(event: DragEndEvent) {\n    const { active, over } = event\n    if (active && over && active.id !== over.id) {\n      setColumnOrder((columnOrder) => {\n        const oldIndex = columnOrder.indexOf(active.id as string)\n        const newIndex = columnOrder.indexOf(over.id as string)\n        return arrayMove(columnOrder, oldIndex, newIndex) //this is just a splice util\n      })\n    }\n  }\n\n  const sensors = useSensors(\n    useSensor(MouseSensor, {}),\n    useSensor(TouchSensor, {}),\n    useSensor(KeyboardSensor, {})\n  )\n\n  return (\n    <DndContext\n      id={useId()}\n      collisionDetection={closestCenter}\n      modifiers={[restrictToHorizontalAxis]}\n      onDragEnd={handleDragEnd}\n      sensors={sensors}\n    >\n      <Table>\n        <TableHeader>\n          {table.getHeaderGroups().map((headerGroup) => (\n            <TableRow key={headerGroup.id} className=\"bg-muted/50\">\n              <SortableContext items={columnOrder} strategy={horizontalListSortingStrategy}>\n                {headerGroup.headers.map((header) => (\n                  <DraggableTableHeader key={header.id} header={header} />\n                ))}\n              </SortableContext>\n            </TableRow>\n          ))}\n        </TableHeader>\n        <TableBody>\n          {table.getRowModel().rows?.length ? (\n            table.getRowModel().rows.map((row) => (\n              <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>\n                {row.getVisibleCells().map((cell) => (\n                  <SortableContext\n                    key={cell.id}\n                    items={columnOrder}\n                    strategy={horizontalListSortingStrategy}\n                  >\n                    <DragAlongCell key={cell.id} cell={cell} />\n                  </SortableContext>\n                ))}\n              </TableRow>\n            ))\n          ) : (\n            <TableRow>\n              <TableCell colSpan={columns.length} className=\"h-24 text-center\">\n                No results.\n              </TableCell>\n            </TableRow>\n          )}\n        </TableBody>\n      </Table>\n      <p className=\"text-muted-foreground mt-4 text-center text-sm\">\n        Draggable columns made with{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://tanstack.com/table\"\n          target=\"_blank\"\n          rel=\"noopener noreferrer\"\n        >\n          TanStack Table\n        </a>{' '}\n        and{' '}\n        <a href=\"https://dndkit.com/\" target=\"_blank\" rel=\"noopener noreferrer\">\n          dnd kit\n        </a>\n      </p>\n    </DndContext>\n  )\n}\n\nconst DraggableTableHeader = ({ header }: { header: Header<Item, unknown> }) => {\n  const { attributes, isDragging, listeners, setNodeRef, transform, transition } = useSortable({\n    id: header.column.id,\n  })\n\n  const style: CSSProperties = {\n    opacity: isDragging ? 0.8 : 1,\n    position: 'relative',\n    transform: CSS.Translate.toString(transform),\n    transition,\n    whiteSpace: 'nowrap',\n    width: header.column.getSize(),\n    zIndex: isDragging ? 1 : 0,\n  }\n\n  return (\n    <TableHead\n      ref={setNodeRef}\n      className=\"before:bg-border relative h-10 border-t before:absolute before:inset-y-0 before:start-0 before:w-px first:before:bg-transparent\"\n      style={style}\n      aria-sort={\n        header.column.getIsSorted() === 'asc'\n          ? 'ascending'\n          : header.column.getIsSorted() === 'desc'\n            ? 'descending'\n            : 'none'\n      }\n    >\n      <div className=\"flex items-center justify-start gap-0.5\">\n        <Button\n          size=\"icon\"\n          variant=\"ghost\"\n          className=\"-ml-2 size-7 shadow-none\"\n          {...attributes}\n          {...listeners}\n          aria-label=\"Drag to reorder\"\n        >\n          <GripVerticalIcon className=\"opacity-60\" size={16} aria-hidden=\"true\" />\n        </Button>\n        <span className=\"grow truncate\">\n          {header.isPlaceholder\n            ? null\n            : flexRender(header.column.columnDef.header, header.getContext())}\n        </span>\n        <Button\n          size=\"icon\"\n          variant=\"ghost\"\n          className=\"group -mr-1 size-7 shadow-none\"\n          onClick={header.column.getToggleSortingHandler()}\n          onKeyDown={(e) => {\n            // Enhanced keyboard handling for sorting\n            if (header.column.getCanSort() && (e.key === 'Enter' || e.key === ' ')) {\n              e.preventDefault()\n              header.column.getToggleSortingHandler()?.(e)\n            }\n          }}\n        >\n          {{\n            asc: <ChevronUpIcon className=\"shrink-0 opacity-60\" size={16} aria-hidden=\"true\" />,\n            desc: <ChevronDownIcon className=\"shrink-0 opacity-60\" size={16} aria-hidden=\"true\" />,\n          }[header.column.getIsSorted() as string] ?? (\n            <ChevronUpIcon\n              className=\"shrink-0 opacity-0 group-hover:opacity-60\"\n              size={16}\n              aria-hidden=\"true\"\n            />\n          )}\n        </Button>\n      </div>\n    </TableHead>\n  )\n}\n\nconst DragAlongCell = ({ cell }: { cell: Cell<Item, unknown> }) => {\n  const { isDragging, setNodeRef, transform, transition } = useSortable({\n    id: cell.column.id,\n  })\n\n  const style: CSSProperties = {\n    opacity: isDragging ? 0.8 : 1,\n    position: 'relative',\n    transform: CSS.Translate.toString(transform),\n    transition,\n    width: cell.column.getSize(),\n    zIndex: isDragging ? 1 : 0,\n  }\n\n  return (\n    <TableCell ref={setNodeRef} className=\"truncate\" style={style}>\n      {flexRender(cell.column.columnDef.cell, cell.getContext())}\n    </TableCell>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/table/table-16.vue",
          "target": "components/ui/table-16.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { GripVerticalIcon } from 'lucide-vue-next'\nimport { Table } from '@timui/vue'\nimport { TableBody } from '@timui/vue'\nimport { TableCell } from '@timui/vue'\nimport { TableHead } from '@timui/vue'\nimport { TableHeader } from '@timui/vue'\nimport { TableRow } from '@timui/vue'\nimport { formatCurrency, tableUsers } from './table-demo-data'\n\ntype ColumnKey = 'name' | 'email' | 'location' | 'status' | 'balance'\n\ntype ColumnConfig = {\n  key: ColumnKey\n  label: string\n}\n\nconst columns = ref<ColumnConfig[]>([\n  { key: 'name', label: 'Name' },\n  { key: 'email', label: 'Email' },\n  { key: 'location', label: 'Location' },\n  { key: 'status', label: 'Status' },\n  { key: 'balance', label: 'Balance' },\n])\n\nconst rows = tableUsers.slice(0, 10)\nconst draggingColumn = ref<ColumnKey | null>(null)\n\nfunction startDrag(key: ColumnKey) {\n  draggingColumn.value = key\n}\n\nfunction allowDrop(event: DragEvent) {\n  event.preventDefault()\n}\n\nfunction dropOn(key: ColumnKey) {\n  if (!draggingColumn.value || draggingColumn.value === key) {\n    return\n  }\n\n  const from = columns.value.findIndex((column) => column.key === draggingColumn.value)\n  const to = columns.value.findIndex((column) => column.key === key)\n\n  if (from < 0 || to < 0) {\n    draggingColumn.value = null\n    return\n  }\n\n  const next = [...columns.value]\n  const [moved] = next.splice(from, 1)\n  next.splice(to, 0, moved)\n  columns.value = next\n  draggingColumn.value = null\n}\n\nfunction dragEnd() {\n  draggingColumn.value = null\n}\n\nfunction valueFor(row: (typeof rows)[number], key: ColumnKey) {\n  if (key === 'balance') {\n    return formatCurrency(row.balance)\n  }\n\n  if (key === 'location') {\n    return `${row.flag} ${row.location}`\n  }\n\n  return row[key]\n}\n</script>\n\n<template>\n  <div>\n    <Table>\n      <TableHeader>\n        <TableRow class=\"bg-muted/50\">\n          <TableHead\n            v-for=\"column in columns\"\n            :key=\"column.key\"\n            draggable=\"true\"\n            class=\"select-none\"\n            :data-dragging=\"draggingColumn === column.key ? true : undefined\"\n            @dragstart=\"startDrag(column.key)\"\n            @dragover=\"allowDrop\"\n            @drop=\"dropOn(column.key)\"\n            @dragend=\"dragEnd\"\n          >\n            <span class=\"inline-flex items-center gap-2\">\n              <GripVerticalIcon class=\"opacity-60\" :size=\"14\" />\n              {{ column.label }}\n            </span>\n          </TableHead>\n        </TableRow>\n      </TableHeader>\n\n      <TableBody>\n        <TableRow v-for=\"row in rows\" :key=\"row.id\">\n          <TableCell v-for=\"column in columns\" :key=\"`${row.id}-${column.key}`\" :class=\"column.key === 'balance' ? 'text-right' : undefined\">\n            {{ valueFor(row, column.key) }}\n          </TableCell>\n        </TableRow>\n      </TableBody>\n    </Table>\n\n    <p class=\"text-muted-foreground mt-4 text-center text-sm\">\n      Draggable columns made with\n      <a class=\"hover:text-foreground underline\" href=\"https://tanstack.com/table\" target=\"_blank\" rel=\"noopener noreferrer\">\n        TanStack Table\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/table/table-16.html",
          "target": "components/ui/table-16.html",
          "type": "registry:component",
          "content": "<template>\n  <DndContext id=\"${useId()}\" collisiondetection=\"${closestCenter}\" modifiers=\"${[restrictToHorizontalAxis]}\" ondragend=\"${handleDragEnd}\" sensors=\"${sensors}\"><Table><TableHeader><!-- Loop table.getHeaderGroups() -->\n<TableRow key=\"${headerGroup.id}\" class=\"bg-muted/50\"><SortableContext items=\"${columnOrder}\" strategy=\"${horizontalListSortingStrategy}\"><!-- Loop headerGroup.headers -->\n<DraggableTableHeader key=\"${header.id}\" header=\"${header}\" />\n<!-- End Loop --></SortableContext></TableRow>\n<!-- End Loop --></TableHeader><TableBody><!-- if table.getRowModel().rows?.length -->\n${table.getRowModel().rows.map((row) => (\n              <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>\n                {row.getVisibleCells().map((cell) => (\n                  <SortableContext\n                    key={cell.id}\n                    items={columnOrder}\n                    strategy={horizontalListSortingStrategy}\n                  >\n                    <DragAlongCell key={cell.id} cell={cell} />\n                  </SortableContext>\n                ))}\n              </TableRow>\n            ))}\n<!-- else -->\n<TableRow><TableCell colspan=\"${columns.length}\" class=\"h-24 text-center\">No results.\n              </TableCell></TableRow>\n<!-- endif --></TableBody></Table><p class=\"text-muted-foreground mt-4 text-center text-sm\">Draggable columns made with${' '}<a class=\"hover:text-foreground underline\" href=\"https://tanstack.com/table\" target=\"_blank\" rel=\"noopener noreferrer\">TanStack Table\n        </a>${' '}and${' '}<a href=\"https://dndkit.com/\" target=\"_blank\" rel=\"noopener noreferrer\">dnd kit\n        </a></p></DndContext>\n</template>"
        },
        {
          "path": "registry/default/components/table/table-16.wxml",
          "target": "components/ui/table-16/table-16.wxml",
          "type": "registry:component",
          "content": "<view>\n  <dndcontext id=\"{{useId()}}\" collisiondetection=\"{{closestCenter}}\" modifiers=\"{{[restrictToHorizontalAxis]}}\" ondragend=\"{{handleDragEnd}}\" sensors=\"{{sensors}}\"><table><tableheader><tablerow wx:for=\"{{table.getHeaderGroups()}}\" wx:for-item=\"headerGroup\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{headerGroup.id}}\" class=\"bg-muted/50\"><sortablecontext items=\"{{columnOrder}}\" strategy=\"{{horizontalListSortingStrategy}}\"><draggabletableheader wx:for=\"{{headerGroup.headers}}\" wx:for-item=\"header\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{header.id}}\" header=\"{{header}}\" /></sortablecontext></tablerow></tableheader><tablebody><block wx:if=\"{{table.getRowModel().rows?.length}}\">\n{{ table.getRowModel().rows.map((row) => (\n              <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>\n                {row.getVisibleCells().map((cell) => (\n                  <SortableContext\n                    key={cell.id}\n                    items={columnOrder}\n                    strategy={horizontalListSortingStrategy}\n                  >\n                    <DragAlongCell key={cell.id} cell={cell} />\n                  </SortableContext>\n                ))}\n              </TableRow>\n            )) }}\n</block>\n<block wx:else>\n<tablerow><tablecell colspan=\"{{columns.length}}\" class=\"h-24 text-center\">No results.\n              </tablecell></tablerow>\n</block></tablebody></table><text class=\"text-muted-foreground mt-4 text-center text-sm\">Draggable columns made with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://tanstack.com/table\" target=\"_blank\" rel=\"noopener noreferrer\">TanStack Table\n        </a>{{ ' ' }}and{{ ' ' }}<a href=\"https://dndkit.com/\" target=\"_blank\" rel=\"noopener noreferrer\">dnd kit\n        </a></text></dndcontext>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "table",
          "tanstack",
          "flag",
          "sort",
          "drag and drop"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "table-16",
          "group": "table",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "table-16",
              "path": "registry/default/components/table/table-16.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "table-16",
              "path": "registry/default/components/table/table-16.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "table-16",
              "path": "registry/default/components/table/table-16.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "table-16",
              "path": "registry/default/components/table/table-16.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@dnd-kit/core",
              "@dnd-kit/modifiers",
              "@dnd-kit/sortable",
              "@dnd-kit/utilities",
              "@tanstack/react-table",
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tables",
        "title": "Table · Drag to reorder"
      },
      "categories": [
        "tables",
        "table"
      ]
    },
    {
      "name": "table-17",
      "type": "registry:component",
      "dependencies": [
        "@tanstack/react-table",
        "@timui/core",
        "@timui/react"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/badge.json",
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/checkbox.json",
        "https://ui.timkit.cn/r/table.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/table/table-17.tsx",
          "type": "registry:component",
          "target": "components/ui/table-17.tsx",
          "content": "'use client'\n\nimport { Fragment, useEffect, useState } from 'react'\nimport {\n  ColumnDef,\n  flexRender,\n  getCoreRowModel,\n  getExpandedRowModel,\n  RowSelectionState,\n  useReactTable,\n} from '@tanstack/react-table'\nimport { cn } from '@timui/core'\nimport {\n  Badge,\n  Button,\n  Checkbox,\n  Table,\n  TableBody,\n  TableCell,\n  TableHead,\n  TableHeader,\n  TableRow,\n} from '@timui/react'\nimport { ChevronDownIcon, ChevronUpIcon, InfoIcon } from 'lucide-react'\n\ntype Item = {\n  id: string\n  name: string\n  email: string\n  location: string\n  flag: string\n  status: 'Active' | 'Inactive' | 'Pending'\n  balance: number\n  note?: string\n}\n\nconst columns: ColumnDef<Item>[] = [\n  {\n    id: 'expander',\n    header: () => null,\n    cell: ({ row }) => {\n      return row.getCanExpand() ? (\n        <Button\n          {...{\n            className: 'size-7 shadow-none text-muted-foreground',\n            onClick: row.getToggleExpandedHandler(),\n            'aria-expanded': row.getIsExpanded(),\n            'aria-label': row.getIsExpanded()\n              ? `Collapse details for ${row.original.name}`\n              : `Expand details for ${row.original.name}`,\n            size: 'icon',\n            variant: 'ghost',\n          }}\n        >\n          {row.getIsExpanded() ? (\n            <ChevronUpIcon className=\"opacity-60\" size={16} aria-hidden=\"true\" />\n          ) : (\n            <ChevronDownIcon className=\"opacity-60\" size={16} aria-hidden=\"true\" />\n          )}\n        </Button>\n      ) : undefined\n    },\n  },\n  {\n    id: 'select',\n    header: ({ table }) => (\n      <Checkbox\n        checked={\n          table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && 'indeterminate')\n        }\n        onCheckedChange={(value: any) =>\n          table.toggleAllPageRowsSelected(!!(value?.detail?.checked ?? value))\n        }\n        onClick={() => table.toggleAllPageRowsSelected(!table.getIsAllPageRowsSelected())}\n        aria-label=\"Select all\"\n      />\n    ),\n    cell: ({ row }) => (\n      <Checkbox\n        checked={row.getIsSelected()}\n        onCheckedChange={(value: any) => row.toggleSelected(!!(value?.detail?.checked ?? value))}\n        onClick={() => row.toggleSelected(!row.getIsSelected())}\n        aria-label=\"Select row\"\n      />\n    ),\n  },\n  {\n    header: 'Name',\n    accessorKey: 'name',\n    cell: ({ row }) => <div className=\"font-medium\">{row.getValue('name')}</div>,\n  },\n  {\n    header: 'Email',\n    accessorKey: 'email',\n  },\n  {\n    header: 'Location',\n    accessorKey: 'location',\n    cell: ({ row }) => (\n      <div>\n        <span className=\"text-lg leading-none\">{row.original.flag}</span> {row.getValue('location')}\n      </div>\n    ),\n  },\n  {\n    header: 'Status',\n    accessorKey: 'status',\n    cell: ({ row }) => (\n      <Badge\n        className={cn(\n          row.getValue('status') === 'Inactive' && 'bg-muted-foreground/60 text-primary-foreground'\n        )}\n      >\n        {row.getValue('status')}\n      </Badge>\n    ),\n  },\n  {\n    header: () => <div className=\"text-right\">Balance</div>,\n    accessorKey: 'balance',\n    cell: ({ row }) => {\n      const amount = parseFloat(row.getValue('balance'))\n      const formatted = new Intl.NumberFormat('en-US', {\n        style: 'currency',\n        currency: 'USD',\n      }).format(amount)\n      return <div className=\"text-right\">{formatted}</div>\n    },\n  },\n]\n\nexport default function Component() {\n  const [data, setData] = useState<Item[]>([])\n  const [rowSelection, setRowSelection] = useState<RowSelectionState>({})\n\n  useEffect(() => {\n    async function fetchPosts() {\n      const res = await fetch(\n        'https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/users-01_fertyx.json'\n      )\n      const data = await res.json()\n      setData(data.slice(0, 5)) // Limit to 5 items\n    }\n    fetchPosts()\n  }, [])\n\n  const table = useReactTable({\n    data,\n    columns,\n    getRowCanExpand: (row) => Boolean(row.original.note),\n    getCoreRowModel: getCoreRowModel(),\n    getExpandedRowModel: getExpandedRowModel(),\n    enableRowSelection: true,\n    onRowSelectionChange: setRowSelection,\n    getRowId: (row) => row.id,\n    state: {\n      rowSelection,\n    },\n  })\n\n  return (\n    <div>\n      <Table>\n        <TableHeader>\n          {table.getHeaderGroups().map((headerGroup) => (\n            <TableRow key={headerGroup.id} className=\"hover:bg-transparent\">\n              {headerGroup.headers.map((header) => {\n                return (\n                  <TableHead key={header.id}>\n                    {header.isPlaceholder\n                      ? null\n                      : flexRender(header.column.columnDef.header, header.getContext())}\n                  </TableHead>\n                )\n              })}\n            </TableRow>\n          ))}\n        </TableHeader>\n        <TableBody>\n          {table.getRowModel().rows?.length ? (\n            table.getRowModel().rows.map((row) => (\n              <Fragment key={row.id}>\n                <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>\n                  {row.getVisibleCells().map((cell) => (\n                    <TableCell\n                      key={cell.id}\n                      className=\"whitespace-nowrap [&:has([aria-expanded])]:w-px [&:has([aria-expanded])]:py-0 [&:has([aria-expanded])]:pr-0\"\n                    >\n                      {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                    </TableCell>\n                  ))}\n                </TableRow>\n                {row.getIsExpanded() && (\n                  <TableRow>\n                    <TableCell colSpan={row.getVisibleCells().length}>\n                      <div className=\"text-primary/80 flex items-start py-2\">\n                        <span\n                          className=\"me-3 mt-0.5 flex w-7 shrink-0 justify-center\"\n                          aria-hidden=\"true\"\n                        >\n                          <InfoIcon className=\"opacity-60\" size={16} />\n                        </span>\n                        <p className=\"text-sm\">{row.original.note}</p>\n                      </div>\n                    </TableCell>\n                  </TableRow>\n                )}\n              </Fragment>\n            ))\n          ) : (\n            <TableRow>\n              <TableCell colSpan={columns.length} className=\"h-24 text-center\">\n                No results.\n              </TableCell>\n            </TableRow>\n          )}\n        </TableBody>\n      </Table>\n      <p className=\"text-muted-foreground mt-4 text-center text-sm\">\n        Expanding sub-row made with{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://tanstack.com/table\"\n          target=\"_blank\"\n          rel=\"noopener noreferrer\"\n        >\n          TanStack Table\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/table/table-17.vue",
          "target": "components/ui/table-17.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { reactive } from 'vue'\nimport { ChevronDownIcon, ChevronRightIcon } from 'lucide-vue-next'\nimport { Table } from '@timui/vue'\nimport { TableBody } from '@timui/vue'\nimport { TableCell } from '@timui/vue'\nimport { TableHead } from '@timui/vue'\nimport { TableHeader } from '@timui/vue'\nimport { TableRow } from '@timui/vue'\nimport { formatCurrency, tableUsers } from './table-demo-data'\n\nconst rows = tableUsers.slice(0, 8)\nconst expandedIds = reactive(new Set<string>())\n\nfunction toggleRow(id: string) {\n  if (expandedIds.has(id)) {\n    expandedIds.delete(id)\n  } else {\n    expandedIds.add(id)\n  }\n}\n</script>\n\n<template>\n  <div>\n    <Table>\n      <TableHeader>\n        <TableRow class=\"bg-muted/50\">\n          <TableHead class=\"w-10\" />\n          <TableHead>Name</TableHead>\n          <TableHead>Email</TableHead>\n          <TableHead>Location</TableHead>\n          <TableHead>Status</TableHead>\n          <TableHead class=\"text-right\">Balance</TableHead>\n        </TableRow>\n      </TableHeader>\n\n      <TableBody>\n        <template v-for=\"row in rows\" :key=\"row.id\">\n          <TableRow :data-state=\"expandedIds.has(row.id) ? 'expanded' : undefined\">\n            <TableCell>\n              <button class=\"inline-flex h-6 w-6 items-center justify-center\" :aria-label=\"`Toggle ${row.name}`\" @click=\"toggleRow(row.id)\">\n                <ChevronDownIcon v-if=\"expandedIds.has(row.id)\" :size=\"14\" />\n                <ChevronRightIcon v-else :size=\"14\" />\n              </button>\n            </TableCell>\n            <TableCell class=\"font-medium\">{{ row.name }}</TableCell>\n            <TableCell>{{ row.email }}</TableCell>\n            <TableCell>{{ row.flag }} {{ row.location }}</TableCell>\n            <TableCell>{{ row.status }}</TableCell>\n            <TableCell class=\"text-right\">{{ formatCurrency(row.balance) }}</TableCell>\n          </TableRow>\n\n          <TableRow v-if=\"expandedIds.has(row.id)\" class=\"bg-muted/20 hover:bg-muted/20\">\n            <TableCell />\n            <TableCell :colSpan=\"5\">\n              <p class=\"text-sm\">{{ row.note }}</p>\n            </TableCell>\n          </TableRow>\n        </template>\n      </TableBody>\n    </Table>\n\n    <p class=\"text-muted-foreground mt-4 text-center text-sm\">\n      Expanding sub-row made with\n      <a class=\"hover:text-foreground underline\" href=\"https://tanstack.com/table\" target=\"_blank\" rel=\"noopener noreferrer\">\n        TanStack Table\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/table/table-17.html",
          "target": "components/ui/table-17.html",
          "type": "registry:component",
          "content": "<template>\n  <div><Table><TableHeader><!-- Loop table.getHeaderGroups() -->\n<TableRow key=\"${headerGroup.id}\" class=\"hover:bg-transparent\">${headerGroup.headers.map((header) => {\n                return (\n                  <TableHead key={header.id}>\n                    {header.isPlaceholder\n                      ? null\n                      : flexRender(header.column.columnDef.header, header.getContext())}\n                  </TableHead>\n                )\n              })}</TableRow>\n<!-- End Loop --></TableHeader><TableBody><!-- if table.getRowModel().rows?.length -->\n${table.getRowModel().rows.map((row) => (\n              <Fragment key={row.id}>\n                <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>\n                  {row.getVisibleCells().map((cell) => (\n                    <TableCell\n                      key={cell.id}\n                      className=\"whitespace-nowrap [&:has([aria-expanded])]:w-px [&:has([aria-expanded])]:py-0 [&:has([aria-expanded])]:pr-0\"\n                    >\n                      {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                    </TableCell>\n                  ))}\n                </TableRow>\n                {row.getIsExpanded() && (\n                  <TableRow>\n                    <TableCell colSpan={row.getVisibleCells().length}>\n                      <div className=\"text-primary/80 flex items-start py-2\">\n                        <span\n                          className=\"me-3 mt-0.5 flex w-7 shrink-0 justify-center\"\n                          aria-hidden=\"true\"\n                        >\n                          <InfoIcon className=\"opacity-60\" size={16} />\n                        </span>\n                        <p className=\"text-sm\">{row.original.note}</p>\n                      </div>\n                    </TableCell>\n                  </TableRow>\n                )}\n              </Fragment>\n            ))}\n<!-- else -->\n<TableRow><TableCell colspan=\"${columns.length}\" class=\"h-24 text-center\">No results.\n              </TableCell></TableRow>\n<!-- endif --></TableBody></Table><p class=\"text-muted-foreground mt-4 text-center text-sm\">Expanding sub-row made with${' '}<a class=\"hover:text-foreground underline\" href=\"https://tanstack.com/table\" target=\"_blank\" rel=\"noopener noreferrer\">TanStack Table\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/table/table-17.wxml",
          "target": "components/ui/table-17/table-17.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><table><tableheader><tablerow wx:for=\"{{table.getHeaderGroups()}}\" wx:for-item=\"headerGroup\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{headerGroup.id}}\" class=\"hover:bg-transparent\">{{ headerGroup.headers.map((header) => {\n                return (\n                  <TableHead key={header.id}>\n                    {header.isPlaceholder\n                      ? null\n                      : flexRender(header.column.columnDef.header, header.getContext())}\n                  </TableHead>\n                )\n              }) }}</tablerow></tableheader><tablebody><block wx:if=\"{{table.getRowModel().rows?.length}}\">\n{{ table.getRowModel().rows.map((row) => (\n              <Fragment key={row.id}>\n                <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>\n                  {row.getVisibleCells().map((cell) => (\n                    <TableCell\n                      key={cell.id}\n                      className=\"whitespace-nowrap [&:has([aria-expanded])]:w-px [&:has([aria-expanded])]:py-0 [&:has([aria-expanded])]:pr-0\"\n                    >\n                      {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                    </TableCell>\n                  ))}\n                </TableRow>\n                {row.getIsExpanded() && (\n                  <TableRow>\n                    <TableCell colSpan={row.getVisibleCells().length}>\n                      <div className=\"text-primary/80 flex items-start py-2\">\n                        <span\n                          className=\"me-3 mt-0.5 flex w-7 shrink-0 justify-center\"\n                          aria-hidden=\"true\"\n                        >\n                          <InfoIcon className=\"opacity-60\" size={16} />\n                        </span>\n                        <p className=\"text-sm\">{row.original.note}</p>\n                      </div>\n                    </TableCell>\n                  </TableRow>\n                )}\n              </Fragment>\n            )) }}\n</block>\n<block wx:else>\n<tablerow><tablecell colspan=\"{{columns.length}}\" class=\"h-24 text-center\">No results.\n              </tablecell></tablerow>\n</block></tablebody></table><text class=\"text-muted-foreground mt-4 text-center text-sm\">Expanding sub-row made with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://tanstack.com/table\" target=\"_blank\" rel=\"noopener noreferrer\">TanStack Table\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "table",
          "tanstack",
          "checkbox",
          "collapsible",
          "flag",
          "badge",
          "chip"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "table-17",
          "group": "table",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "table-17",
              "path": "registry/default/components/table/table-17.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "table-17",
              "path": "registry/default/components/table/table-17.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "table-17",
              "path": "registry/default/components/table/table-17.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "table-17",
              "path": "registry/default/components/table/table-17.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@tanstack/react-table",
              "@timui/core",
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tables",
        "title": "Table · Select all"
      },
      "categories": [
        "tables",
        "table"
      ]
    },
    {
      "name": "table-18",
      "type": "registry:component",
      "dependencies": [
        "@tanstack/react-table",
        "@timui/core",
        "@timui/react"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/badge.json",
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/checkbox.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/pagination.json",
        "https://ui.timkit.cn/r/select.json",
        "https://ui.timkit.cn/r/table.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/table/table-18.tsx",
          "type": "registry:component",
          "target": "components/ui/table-18.tsx",
          "content": "'use client'\n\nimport { useEffect, useId, useState } from 'react'\nimport {\n  ColumnDef,\n  flexRender,\n  getCoreRowModel,\n  getPaginationRowModel,\n  getSortedRowModel,\n  PaginationState,\n  RowSelectionState,\n  SortingState,\n  useReactTable,\n} from '@tanstack/react-table'\nimport { cn } from '@timui/core'\nimport {\n  Badge,\n  Button,\n  Checkbox,\n  Label,\n  Pagination,\n  PaginationContent,\n  PaginationItem,\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n  Table,\n  TableBody,\n  TableCell,\n  TableHead,\n  TableHeader,\n  TableRow,\n} from '@timui/react'\nimport {\n  ChevronDownIcon,\n  ChevronFirstIcon,\n  ChevronLastIcon,\n  ChevronLeftIcon,\n  ChevronRightIcon,\n  ChevronUpIcon,\n} from 'lucide-react'\n\ntype Item = {\n  id: string\n  name: string\n  email: string\n  location: string\n  flag: string\n  status: 'Active' | 'Inactive' | 'Pending'\n  balance: number\n}\n\nconst columns: ColumnDef<Item>[] = [\n  {\n    id: 'select',\n    header: ({ table }) => (\n      <Checkbox\n        checked={\n          table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && 'indeterminate')\n        }\n        onCheckedChange={(value: any) =>\n          table.toggleAllPageRowsSelected(!!(value?.detail?.checked ?? value))\n        }\n        onClick={() => table.toggleAllPageRowsSelected(!table.getIsAllPageRowsSelected())}\n        aria-label=\"Select all\"\n      />\n    ),\n    cell: ({ row }) => (\n      <Checkbox\n        checked={row.getIsSelected()}\n        onCheckedChange={(value: any) => row.toggleSelected(!!(value?.detail?.checked ?? value))}\n        onClick={() => row.toggleSelected(!row.getIsSelected())}\n        aria-label=\"Select row\"\n      />\n    ),\n    size: 28,\n    enableSorting: false,\n  },\n  {\n    header: 'Name',\n    accessorKey: 'name',\n    cell: ({ row }) => <div className=\"font-medium\">{row.getValue('name')}</div>,\n    size: 180,\n  },\n  {\n    header: 'Email',\n    accessorKey: 'email',\n    size: 200,\n  },\n  {\n    header: 'Location',\n    accessorKey: 'location',\n    cell: ({ row }) => (\n      <div>\n        <span className=\"text-lg leading-none\">{row.original.flag}</span> {row.getValue('location')}\n      </div>\n    ),\n    size: 180,\n  },\n  {\n    header: 'Status',\n    accessorKey: 'status',\n    cell: ({ row }) => (\n      <Badge\n        className={cn(\n          row.getValue('status') === 'Inactive' && 'bg-muted-foreground/60 text-primary-foreground'\n        )}\n      >\n        {row.getValue('status')}\n      </Badge>\n    ),\n    size: 120,\n  },\n  {\n    header: 'Balance',\n    accessorKey: 'balance',\n    cell: ({ row }) => {\n      const amount = parseFloat(row.getValue('balance'))\n      const formatted = new Intl.NumberFormat('en-US', {\n        style: 'currency',\n        currency: 'USD',\n      }).format(amount)\n      return formatted\n    },\n    size: 120,\n  },\n]\n\nexport default function Component() {\n  const id = useId()\n  const [pagination, setPagination] = useState<PaginationState>({\n    pageIndex: 0,\n    pageSize: 5,\n  })\n\n  const [sorting, setSorting] = useState<SortingState>([\n    {\n      id: 'name',\n      desc: false,\n    },\n  ])\n\n  const [data, setData] = useState<Item[]>([])\n  const [rowSelection, setRowSelection] = useState<RowSelectionState>({})\n  useEffect(() => {\n    async function fetchPosts() {\n      const res = await fetch(\n        'https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/users-01_fertyx.json'\n      )\n      const data = await res.json()\n      setData([...data, ...data])\n    }\n    fetchPosts()\n  }, [])\n\n  const table = useReactTable({\n    data,\n    columns,\n    getCoreRowModel: getCoreRowModel(),\n    getSortedRowModel: getSortedRowModel(),\n    onSortingChange: setSorting,\n    enableSortingRemoval: false,\n    getPaginationRowModel: getPaginationRowModel(),\n    onPaginationChange: setPagination,\n    onRowSelectionChange: setRowSelection,\n    enableRowSelection: true,\n    getRowId: (row) => row.id,\n    state: {\n      sorting,\n      pagination,\n      rowSelection,\n    },\n  })\n\n  return (\n    <div className=\"space-y-4\">\n      <div className=\"bg-background overflow-hidden rounded-md border\">\n        <Table className=\"table-fixed\">\n          <TableHeader>\n            {table.getHeaderGroups().map((headerGroup) => (\n              <TableRow key={headerGroup.id} className=\"hover:bg-transparent\">\n                {headerGroup.headers.map((header) => {\n                  return (\n                    <TableHead\n                      key={header.id}\n                      style={{ width: `${header.getSize()}px` }}\n                      className=\"h-11\"\n                    >\n                      {header.isPlaceholder ? null : header.column.getCanSort() ? (\n                        <div\n                          className={cn(\n                            header.column.getCanSort() &&\n                              'flex h-full cursor-pointer items-center justify-between gap-2 select-none'\n                          )}\n                          onClick={header.column.getToggleSortingHandler()}\n                          onKeyDown={(e) => {\n                            // Enhanced keyboard handling for sorting\n                            if (\n                              header.column.getCanSort() &&\n                              (e.key === 'Enter' || e.key === ' ')\n                            ) {\n                              e.preventDefault()\n                              header.column.getToggleSortingHandler()?.(e)\n                            }\n                          }}\n                          tabIndex={header.column.getCanSort() ? 0 : undefined}\n                        >\n                          {flexRender(header.column.columnDef.header, header.getContext())}\n                          {{\n                            asc: (\n                              <ChevronUpIcon\n                                className=\"shrink-0 opacity-60\"\n                                size={16}\n                                aria-hidden=\"true\"\n                              />\n                            ),\n                            desc: (\n                              <ChevronDownIcon\n                                className=\"shrink-0 opacity-60\"\n                                size={16}\n                                aria-hidden=\"true\"\n                              />\n                            ),\n                          }[header.column.getIsSorted() as string] ?? null}\n                        </div>\n                      ) : (\n                        flexRender(header.column.columnDef.header, header.getContext())\n                      )}\n                    </TableHead>\n                  )\n                })}\n              </TableRow>\n            ))}\n          </TableHeader>\n          <TableBody>\n            {table.getRowModel().rows?.length ? (\n              table.getRowModel().rows.map((row) => (\n                <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>\n                  {row.getVisibleCells().map((cell) => (\n                    <TableCell key={cell.id}>\n                      {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                    </TableCell>\n                  ))}\n                </TableRow>\n              ))\n            ) : (\n              <TableRow>\n                <TableCell colSpan={columns.length} className=\"h-24 text-center\">\n                  No results.\n                </TableCell>\n              </TableRow>\n            )}\n          </TableBody>\n        </Table>\n      </div>\n\n      {/* Pagination */}\n      <div className=\"flex items-center justify-between gap-8\">\n        {/* Results per page */}\n        <div className=\"flex items-center gap-3\">\n          <Label htmlFor={id} className=\"max-sm:sr-only\">\n            Rows per page\n          </Label>\n          <Select\n            value={table.getState().pagination.pageSize.toString()}\n            onValueChange={(value: string) => {\n              table.setPageSize(Number(value))\n            }}\n          >\n            <SelectTrigger id={id} className=\"w-fit whitespace-nowrap\">\n              <SelectValue placeholder=\"Select number of results\" />\n            </SelectTrigger>\n            <SelectContent className=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\">\n              {[5, 10, 25, 50].map((pageSize) => (\n                <SelectItem key={pageSize} value={pageSize.toString()}>\n                  {pageSize}\n                </SelectItem>\n              ))}\n            </SelectContent>\n          </Select>\n        </div>\n        {/* Page number information */}\n        <div className=\"text-muted-foreground flex grow justify-end text-sm whitespace-nowrap\">\n          <p className=\"text-muted-foreground text-sm whitespace-nowrap\" aria-live=\"polite\">\n            <span className=\"text-foreground\">\n              {table.getState().pagination.pageIndex * table.getState().pagination.pageSize + 1}-\n              {Math.min(\n                Math.max(\n                  table.getState().pagination.pageIndex * table.getState().pagination.pageSize +\n                    table.getState().pagination.pageSize,\n                  0\n                ),\n                table.getRowCount()\n              )}\n            </span>{' '}\n            of <span className=\"text-foreground\">{table.getRowCount().toString()}</span>\n          </p>\n        </div>\n        {/* Pagination buttons */}\n        <div>\n          <Pagination>\n            <PaginationContent>\n              {/* First page button */}\n              <PaginationItem>\n                <Button\n                  size=\"icon\"\n                  variant=\"outline\"\n                  className=\"disabled:pointer-events-none disabled:opacity-50\"\n                  onClick={() => table.firstPage()}\n                  disabled={!table.getCanPreviousPage()}\n                  aria-label=\"Go to first page\"\n                >\n                  <ChevronFirstIcon size={16} aria-hidden=\"true\" />\n                </Button>\n              </PaginationItem>\n              {/* Previous page button */}\n              <PaginationItem>\n                <Button\n                  size=\"icon\"\n                  variant=\"outline\"\n                  className=\"disabled:pointer-events-none disabled:opacity-50\"\n                  onClick={() => table.previousPage()}\n                  disabled={!table.getCanPreviousPage()}\n                  aria-label=\"Go to previous page\"\n                >\n                  <ChevronLeftIcon size={16} aria-hidden=\"true\" />\n                </Button>\n              </PaginationItem>\n              {/* Next page button */}\n              <PaginationItem>\n                <Button\n                  size=\"icon\"\n                  variant=\"outline\"\n                  className=\"disabled:pointer-events-none disabled:opacity-50\"\n                  onClick={() => table.nextPage()}\n                  disabled={!table.getCanNextPage()}\n                  aria-label=\"Go to next page\"\n                >\n                  <ChevronRightIcon size={16} aria-hidden=\"true\" />\n                </Button>\n              </PaginationItem>\n              {/* Last page button */}\n              <PaginationItem>\n                <Button\n                  size=\"icon\"\n                  variant=\"outline\"\n                  className=\"disabled:pointer-events-none disabled:opacity-50\"\n                  onClick={() => table.lastPage()}\n                  disabled={!table.getCanNextPage()}\n                  aria-label=\"Go to last page\"\n                >\n                  <ChevronLastIcon size={16} aria-hidden=\"true\" />\n                </Button>\n              </PaginationItem>\n            </PaginationContent>\n          </Pagination>\n        </div>\n      </div>\n      <p className=\"text-muted-foreground mt-4 text-center text-sm\">\n        Paginated table made with{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://tanstack.com/table\"\n          target=\"_blank\"\n          rel=\"noopener noreferrer\"\n        >\n          TanStack Table\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/table/table-18.vue",
          "target": "components/ui/table-18.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport { ChevronDownIcon, ChevronFirstIcon, ChevronLastIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon } from 'lucide-vue-next'\nimport { Button } from '@timui/vue'\nimport { Label } from '@timui/vue'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/vue'\nimport { Table } from '@timui/vue'\nimport { TableBody } from '@timui/vue'\nimport { TableCell } from '@timui/vue'\nimport { TableHead } from '@timui/vue'\nimport { TableHeader } from '@timui/vue'\nimport { TableRow } from '@timui/vue'\nimport { formatCurrency, tableUsers } from './table-demo-data'\n\ntype SortKey = 'name' | 'email' | 'location' | 'status' | 'balance'\n\nconst sortKey = ref<SortKey>('name')\nconst sortDirection = ref<'asc' | 'desc'>('asc')\nconst pageIndex = ref(0)\nconst pageSize = ref(5)\n\nconst sortedRows = computed(() => {\n  return [...tableUsers].sort((left, right) => {\n    const leftValue = left[sortKey.value]\n    const rightValue = right[sortKey.value]\n\n    if (typeof leftValue === 'number' && typeof rightValue === 'number') {\n      return sortDirection.value === 'asc' ? leftValue - rightValue : rightValue - leftValue\n    }\n\n    const result = String(leftValue).localeCompare(String(rightValue))\n    return sortDirection.value === 'asc' ? result : -result\n  })\n})\n\nconst pageCount = computed(() => Math.max(1, Math.ceil(sortedRows.value.length / pageSize.value)))\n\nconst pagedRows = computed(() => {\n  const start = pageIndex.value * pageSize.value\n  return sortedRows.value.slice(start, start + pageSize.value)\n})\n\nconst rangeLabel = computed(() => {\n  const start = pageIndex.value * pageSize.value + 1\n  const end = Math.min(start + pageSize.value - 1, sortedRows.value.length)\n  return `${start}-${end} of ${sortedRows.value.length}`\n})\n\nfunction toggleSort(key: SortKey) {\n  if (sortKey.value === key) {\n    sortDirection.value = sortDirection.value === 'asc' ? 'desc' : 'asc'\n    return\n  }\n\n  sortKey.value = key\n  sortDirection.value = 'asc'\n}\n\nfunction changePageSize(value: string) {\n  pageSize.value = Number(value)\n  pageIndex.value = 0\n}\n\nfunction firstPage() {\n  pageIndex.value = 0\n}\n\nfunction previousPage() {\n  pageIndex.value = Math.max(0, pageIndex.value - 1)\n}\n\nfunction nextPage() {\n  pageIndex.value = Math.min(pageCount.value - 1, pageIndex.value + 1)\n}\n\nfunction lastPage() {\n  pageIndex.value = pageCount.value - 1\n}\n\nfunction sortIcon(key: SortKey) {\n  if (sortKey.value !== key) return null\n  return sortDirection.value === 'asc' ? ChevronUpIcon : ChevronDownIcon\n}\n</script>\n\n<template>\n  <div class=\"space-y-4\">\n    <div class=\"bg-background overflow-hidden rounded-md border\">\n      <Table>\n        <TableHeader>\n          <TableRow class=\"hover:bg-transparent\">\n            <TableHead class=\"h-11 cursor-pointer\" @click=\"toggleSort('name')\">\n              <span class=\"flex items-center gap-1\">Name <component :is=\"sortIcon('name')\" v-if=\"sortIcon('name')\" :size=\"14\" /></span>\n            </TableHead>\n            <TableHead class=\"h-11 cursor-pointer\" @click=\"toggleSort('email')\">\n              <span class=\"flex items-center gap-1\">Email <component :is=\"sortIcon('email')\" v-if=\"sortIcon('email')\" :size=\"14\" /></span>\n            </TableHead>\n            <TableHead class=\"h-11 cursor-pointer\" @click=\"toggleSort('location')\">\n              <span class=\"flex items-center gap-1\">Location <component :is=\"sortIcon('location')\" v-if=\"sortIcon('location')\" :size=\"14\" /></span>\n            </TableHead>\n            <TableHead class=\"h-11 cursor-pointer\" @click=\"toggleSort('status')\">\n              <span class=\"flex items-center gap-1\">Status <component :is=\"sortIcon('status')\" v-if=\"sortIcon('status')\" :size=\"14\" /></span>\n            </TableHead>\n            <TableHead class=\"h-11 cursor-pointer text-right\" @click=\"toggleSort('balance')\">\n              <span class=\"flex items-center justify-end gap-1\">Balance <component :is=\"sortIcon('balance')\" v-if=\"sortIcon('balance')\" :size=\"14\" /></span>\n            </TableHead>\n          </TableRow>\n        </TableHeader>\n\n        <TableBody>\n          <TableRow v-for=\"row in pagedRows\" :key=\"row.id\">\n            <TableCell class=\"font-medium\">{{ row.name }}</TableCell>\n            <TableCell>{{ row.email }}</TableCell>\n            <TableCell>{{ row.flag }} {{ row.location }}</TableCell>\n            <TableCell>{{ row.status }}</TableCell>\n            <TableCell class=\"text-right\">{{ formatCurrency(row.balance) }}</TableCell>\n          </TableRow>\n        </TableBody>\n      </Table>\n    </div>\n\n    <div class=\"flex items-center justify-between gap-4 max-sm:flex-col\">\n      <p class=\"text-muted-foreground text-sm\" aria-live=\"polite\">{{ rangeLabel }}</p>\n\n      <div class=\"flex items-center gap-2\">\n        <Button size=\"icon\" variant=\"outline\" :disabled=\"pageIndex === 0\" @click=\"firstPage\" aria-label=\"Go to first page\">\n          <ChevronFirstIcon :size=\"16\" />\n        </Button>\n        <Button size=\"icon\" variant=\"outline\" :disabled=\"pageIndex === 0\" @click=\"previousPage\" aria-label=\"Go to previous page\">\n          <ChevronLeftIcon :size=\"16\" />\n        </Button>\n        <Button size=\"icon\" variant=\"outline\" :disabled=\"pageIndex >= pageCount - 1\" @click=\"nextPage\" aria-label=\"Go to next page\">\n          <ChevronRightIcon :size=\"16\" />\n        </Button>\n        <Button size=\"icon\" variant=\"outline\" :disabled=\"pageIndex >= pageCount - 1\" @click=\"lastPage\" aria-label=\"Go to last page\">\n          <ChevronLastIcon :size=\"16\" />\n        </Button>\n      </div>\n\n      <div class=\"flex items-center gap-2\">\n        <Label for=\"table-18-page-size\">Rows per page</Label>\n        <Select :value=\"String(pageSize)\" @update:modelValue=\"changePageSize\">\n          <SelectTrigger id=\"table-18-page-size\" class=\"w-[120px]\">\n            <SelectValue placeholder=\"Page size\" />\n          </SelectTrigger>\n          <SelectContent>\n            <SelectItem value=\"5\">5</SelectItem>\n            <SelectItem value=\"10\">10</SelectItem>\n            <SelectItem value=\"25\">25</SelectItem>\n            <SelectItem value=\"50\">50</SelectItem>\n          </SelectContent>\n        </Select>\n      </div>\n    </div>\n\n    <p class=\"text-muted-foreground mt-4 text-center text-sm\">\n      Paginated table made with\n      <a class=\"hover:text-foreground underline\" href=\"https://tanstack.com/table\" target=\"_blank\" rel=\"noopener noreferrer\">\n        TanStack Table\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/table/table-18.html",
          "target": "components/ui/table-18.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-4\"><div class=\"bg-background overflow-hidden rounded-md border\"><Table class=\"table-fixed\"><TableHeader><!-- Loop table.getHeaderGroups() -->\n<TableRow key=\"${headerGroup.id}\" class=\"hover:bg-transparent\">${headerGroup.headers.map((header) => {\n                  return (\n                    <TableHead\n                      key={header.id}\n                      style={{ width: `${header.getSize()}px` }}\n                      className=\"h-11\"\n                    >\n                      {header.isPlaceholder ? null : header.column.getCanSort() ? (\n                        <div\n                          className={cn(\n                            header.column.getCanSort() &&\n                              'flex h-full cursor-pointer items-center justify-between gap-2 select-none'\n                          )}\n                          onClick={header.column.getToggleSortingHandler()}\n                          onKeyDown={(e) => {\n                            // Enhanced keyboard handling for sorting\n                            if (\n                              header.column.getCanSort() &&\n                              (e.key === 'Enter' || e.key === ' ')\n                            ) {\n                              e.preventDefault()\n                              header.column.getToggleSortingHandler()?.(e)\n                            }\n                          }}\n                          tabIndex={header.column.getCanSort() ? 0 : undefined}\n                        >\n                          {flexRender(header.column.columnDef.header, header.getContext())}\n                          {{\n                            asc: (\n                              <ChevronUpIcon\n                                className=\"shrink-0 opacity-60\"\n                                size={16}\n                                aria-hidden=\"true\"\n                              />\n                            ),\n                            desc: (\n                              <ChevronDownIcon\n                                className=\"shrink-0 opacity-60\"\n                                size={16}\n                                aria-hidden=\"true\"\n                              />\n                            ),\n                          }[header.column.getIsSorted() as string] ?? null}\n                        </div>\n                      ) : (\n                        flexRender(header.column.columnDef.header, header.getContext())\n                      )}\n                    </TableHead>\n                  )\n                })}</TableRow>\n<!-- End Loop --></TableHeader><TableBody><!-- if table.getRowModel().rows?.length -->\n${table.getRowModel().rows.map((row) => (\n                <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>\n                  {row.getVisibleCells().map((cell) => (\n                    <TableCell key={cell.id}>\n                      {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                    </TableCell>\n                  ))}\n                </TableRow>\n              ))}\n<!-- else -->\n<TableRow><TableCell colspan=\"${columns.length}\" class=\"h-24 text-center\">No results.\n                </TableCell></TableRow>\n<!-- endif --></TableBody></Table></div><div class=\"flex items-center justify-between gap-8\"><div class=\"flex items-center gap-3\"><Label htmlfor=\"${id}\" class=\"max-sm:sr-only\">Rows per page\n          </Label><Select value=\"${table.getState().pagination.pageSize.toString()}\" on-value-change=\"${(value: string) => {\n              table.setPageSize(Number(value))\n            }}\"><SelectTrigger id=\"${id}\" class=\"w-fit whitespace-nowrap\"><SelectValue placeholder=\"Select number of results\" /></SelectTrigger><SelectContent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\"><!-- Loop [5, 10, 25, 50] -->\n<SelectItem key=\"${pageSize}\" value=\"${pageSize.toString()}\">${pageSize}</SelectItem>\n<!-- End Loop --></SelectContent></Select></div><div class=\"text-muted-foreground flex grow justify-end text-sm whitespace-nowrap\"><p class=\"text-muted-foreground text-sm whitespace-nowrap\" aria-live=\"polite\"><span class=\"text-foreground\">${table.getState().pagination.pageIndex * table.getState().pagination.pageSize + 1}-\n              ${Math.min(\n                Math.max(\n                  table.getState().pagination.pageIndex * table.getState().pagination.pageSize +\n                    table.getState().pagination.pageSize,\n                  0\n                ),\n                table.getRowCount()\n              )}</span>${' '}of <span class=\"text-foreground\">${table.getRowCount().toString()}</span></p></div><div><Pagination><PaginationContent><PaginationItem><Button size=\"icon\" variant=\"outline\" class=\"disabled:pointer-events-none disabled:opacity-50\" on-click=\"${() => table.firstPage()}\" disabled=\"${!table.getCanPreviousPage()}\" aria-label=\"Go to first page\"><ChevronFirstIcon size=\"${16}\" aria-hidden=\"true\" /></Button></PaginationItem><PaginationItem><Button size=\"icon\" variant=\"outline\" class=\"disabled:pointer-events-none disabled:opacity-50\" on-click=\"${() => table.previousPage()}\" disabled=\"${!table.getCanPreviousPage()}\" aria-label=\"Go to previous page\"><ChevronLeftIcon size=\"${16}\" aria-hidden=\"true\" /></Button></PaginationItem><PaginationItem><Button size=\"icon\" variant=\"outline\" class=\"disabled:pointer-events-none disabled:opacity-50\" on-click=\"${() => table.nextPage()}\" disabled=\"${!table.getCanNextPage()}\" aria-label=\"Go to next page\"><ChevronRightIcon size=\"${16}\" aria-hidden=\"true\" /></Button></PaginationItem><PaginationItem><Button size=\"icon\" variant=\"outline\" class=\"disabled:pointer-events-none disabled:opacity-50\" on-click=\"${() => table.lastPage()}\" disabled=\"${!table.getCanNextPage()}\" aria-label=\"Go to last page\"><ChevronLastIcon size=\"${16}\" aria-hidden=\"true\" /></Button></PaginationItem></PaginationContent></Pagination></div></div><p class=\"text-muted-foreground mt-4 text-center text-sm\">Paginated table made with${' '}<a class=\"hover:text-foreground underline\" href=\"https://tanstack.com/table\" target=\"_blank\" rel=\"noopener noreferrer\">TanStack Table\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/table/table-18.wxml",
          "target": "components/ui/table-18/table-18.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-4\"><view class=\"bg-background overflow-hidden rounded-md border\"><table class=\"table-fixed\"><tableheader><tablerow wx:for=\"{{table.getHeaderGroups()}}\" wx:for-item=\"headerGroup\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{headerGroup.id}}\" class=\"hover:bg-transparent\">{{ headerGroup.headers.map((header) => {\n                  return (\n                    <TableHead\n                      key={header.id}\n                      style={{ width: `${header.getSize()}px` }}\n                      className=\"h-11\"\n                    >\n                      {header.isPlaceholder ? null : header.column.getCanSort() ? (\n                        <div\n                          className={cn(\n                            header.column.getCanSort() &&\n                              'flex h-full cursor-pointer items-center justify-between gap-2 select-none'\n                          )}\n                          onClick={header.column.getToggleSortingHandler()}\n                          onKeyDown={(e) => {\n                            // Enhanced keyboard handling for sorting\n                            if (\n                              header.column.getCanSort() &&\n                              (e.key === 'Enter' || e.key === ' ')\n                            ) {\n                              e.preventDefault()\n                              header.column.getToggleSortingHandler()?.(e)\n                            }\n                          }}\n                          tabIndex={header.column.getCanSort() ? 0 : undefined}\n                        >\n                          {flexRender(header.column.columnDef.header, header.getContext())}\n                          {{\n                            asc: (\n                              <ChevronUpIcon\n                                className=\"shrink-0 opacity-60\"\n                                size={16}\n                                aria-hidden=\"true\"\n                              />\n                            ),\n                            desc: (\n                              <ChevronDownIcon\n                                className=\"shrink-0 opacity-60\"\n                                size={16}\n                                aria-hidden=\"true\"\n                              />\n                            ),\n                          }[header.column.getIsSorted() as string] ?? null}\n                        </div>\n                      ) : (\n                        flexRender(header.column.columnDef.header, header.getContext())\n                      )}\n                    </TableHead>\n                  )\n                }) }}</tablerow></tableheader><tablebody><block wx:if=\"{{table.getRowModel().rows?.length}}\">\n{{ table.getRowModel().rows.map((row) => (\n                <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>\n                  {row.getVisibleCells().map((cell) => (\n                    <TableCell key={cell.id}>\n                      {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                    </TableCell>\n                  ))}\n                </TableRow>\n              )) }}\n</block>\n<block wx:else>\n<tablerow><tablecell colspan=\"{{columns.length}}\" class=\"h-24 text-center\">No results.\n                </tablecell></tablerow>\n</block></tablebody></table></view><view class=\"flex items-center justify-between gap-8\"><view class=\"flex items-center gap-3\"><label htmlfor=\"{{id}}\" class=\"max-sm:sr-only\">Rows per page\n          </label><select value=\"{{table.getState().pagination.pageSize.toString()}}\" bindchange=\"{\n              table.setPageSize(Number(value))\n            }\"><selecttrigger id=\"{{id}}\" class=\"w-fit whitespace-nowrap\"><selectvalue placeholder=\"Select number of results\" /></selecttrigger><selectcontent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\"><selectitem wx:for=\"{{[5, 10, 25, 50]}}\" wx:for-item=\"pageSize\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{pageSize}}\" value=\"{{pageSize.toString()}}\">{{ pageSize }}</selectitem></selectcontent></select></view><view class=\"text-muted-foreground flex grow justify-end text-sm whitespace-nowrap\"><text class=\"text-muted-foreground text-sm whitespace-nowrap\" aria-live=\"polite\"><text class=\"text-foreground\">{{ table.getState().pagination.pageIndex * table.getState().pagination.pageSize + 1 }}-\n              {{ Math.min(\n                Math.max(\n                  table.getState().pagination.pageIndex * table.getState().pagination.pageSize +\n                    table.getState().pagination.pageSize,\n                  0\n                ),\n                table.getRowCount()\n              ) }}</text>{{ ' ' }}of <text class=\"text-foreground\">{{ table.getRowCount().toString() }}</text></text></view><view><pagination><paginationcontent><paginationitem><button size=\"icon\" variant=\"outline\" class=\"disabled:pointer-events-none disabled:opacity-50\" bindtap=\"table.firstPage()\" disabled=\"{{!table.getCanPreviousPage()}}\" aria-label=\"Go to first page\"><chevronfirsticon size=\"{{16}}\" aria-hidden=\"true\" /></button></paginationitem><paginationitem><button size=\"icon\" variant=\"outline\" class=\"disabled:pointer-events-none disabled:opacity-50\" bindtap=\"table.previousPage()\" disabled=\"{{!table.getCanPreviousPage()}}\" aria-label=\"Go to previous page\"><chevronlefticon size=\"{{16}}\" aria-hidden=\"true\" /></button></paginationitem><paginationitem><button size=\"icon\" variant=\"outline\" class=\"disabled:pointer-events-none disabled:opacity-50\" bindtap=\"table.nextPage()\" disabled=\"{{!table.getCanNextPage()}}\" aria-label=\"Go to next page\"><chevronrighticon size=\"{{16}}\" aria-hidden=\"true\" /></button></paginationitem><paginationitem><button size=\"icon\" variant=\"outline\" class=\"disabled:pointer-events-none disabled:opacity-50\" bindtap=\"table.lastPage()\" disabled=\"{{!table.getCanNextPage()}}\" aria-label=\"Go to last page\"><chevronlasticon size=\"{{16}}\" aria-hidden=\"true\" /></button></paginationitem></paginationcontent></pagination></view></view><text class=\"text-muted-foreground mt-4 text-center text-sm\">Paginated table made with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://tanstack.com/table\" target=\"_blank\" rel=\"noopener noreferrer\">TanStack Table\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "table",
          "tanstack",
          "checkbox",
          "sort",
          "flag",
          "badge",
          "chip",
          "pagination"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "table-18",
          "group": "table",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "table-18",
              "path": "registry/default/components/table/table-18.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "table-18",
              "path": "registry/default/components/table/table-18.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "table-18",
              "path": "registry/default/components/table/table-18.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "table-18",
              "path": "registry/default/components/table/table-18.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@tanstack/react-table",
              "@timui/core",
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tables",
        "title": "Table · Rows per page"
      },
      "categories": [
        "tables",
        "table"
      ]
    },
    {
      "name": "table-19",
      "type": "registry:component",
      "dependencies": [
        "@tanstack/react-table",
        "@timui/core",
        "@timui/react"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/badge.json",
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/checkbox.json",
        "https://ui.timkit.cn/r/pagination.json",
        "https://ui.timkit.cn/r/select.json",
        "https://ui.timkit.cn/r/table.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/table/table-19.tsx",
          "type": "registry:component",
          "target": "components/ui/table-19.tsx",
          "content": "'use client'\n\nimport { useEffect, useState } from 'react'\nimport {\n  ColumnDef,\n  flexRender,\n  getCoreRowModel,\n  getPaginationRowModel,\n  getSortedRowModel,\n  PaginationState,\n  RowSelectionState,\n  SortingState,\n  useReactTable,\n} from '@tanstack/react-table'\nimport { cn } from '@timui/core'\nimport {\n  Badge,\n  Button,\n  Checkbox,\n  Pagination,\n  PaginationContent,\n  PaginationEllipsis,\n  PaginationItem,\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n  Table,\n  TableBody,\n  TableCell,\n  TableHead,\n  TableHeader,\n  TableRow,\n} from '@timui/react'\nimport { ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon } from 'lucide-react'\n\nimport { usePagination } from '@/registry/default/hooks/use-pagination'\n\ntype Item = {\n  id: string\n  name: string\n  email: string\n  location: string\n  flag: string\n  status: 'Active' | 'Inactive' | 'Pending'\n  balance: number\n}\n\nconst columns: ColumnDef<Item>[] = [\n  {\n    id: 'select',\n    header: ({ table }) => (\n      <Checkbox\n        checked={\n          table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && 'indeterminate')\n        }\n        onCheckedChange={(value: any) =>\n          table.toggleAllPageRowsSelected(!!(value?.detail?.checked ?? value))\n        }\n        onClick={() => table.toggleAllPageRowsSelected(!table.getIsAllPageRowsSelected())}\n        aria-label=\"Select all rows\"\n      />\n    ),\n    cell: ({ row }) => (\n      <Checkbox\n        checked={row.getIsSelected()}\n        onCheckedChange={(value: any) => row.toggleSelected(!!(value?.detail?.checked ?? value))}\n        onClick={() => row.toggleSelected(!row.getIsSelected())}\n        aria-label=\"Select row\"\n      />\n    ),\n    size: 28,\n    enableSorting: false,\n  },\n  {\n    header: 'Name',\n    accessorKey: 'name',\n    cell: ({ row }) => <div className=\"font-medium\">{row.getValue('name')}</div>,\n    size: 180,\n  },\n  {\n    header: 'Email',\n    accessorKey: 'email',\n    size: 200,\n  },\n  {\n    header: 'Location',\n    accessorKey: 'location',\n    cell: ({ row }) => (\n      <div>\n        <span className=\"text-lg leading-none\">{row.original.flag}</span> {row.getValue('location')}\n      </div>\n    ),\n    size: 180,\n  },\n  {\n    header: 'Status',\n    accessorKey: 'status',\n    cell: ({ row }) => (\n      <Badge\n        className={cn(\n          row.getValue('status') === 'Inactive' && 'bg-muted-foreground/60 text-primary-foreground'\n        )}\n      >\n        {row.getValue('status')}\n      </Badge>\n    ),\n    size: 120,\n  },\n  {\n    header: 'Balance',\n    accessorKey: 'balance',\n    cell: ({ row }) => {\n      const amount = parseFloat(row.getValue('balance'))\n      const formatted = new Intl.NumberFormat('en-US', {\n        style: 'currency',\n        currency: 'USD',\n      }).format(amount)\n      return formatted\n    },\n    size: 120,\n  },\n]\n\nexport default function Component() {\n  const pageSize = 5\n\n  const [pagination, setPagination] = useState<PaginationState>({\n    pageIndex: 0,\n    pageSize: pageSize,\n  })\n\n  const [sorting, setSorting] = useState<SortingState>([\n    {\n      id: 'name',\n      desc: false,\n    },\n  ])\n\n  const [data, setData] = useState<Item[]>([])\n  const [rowSelection, setRowSelection] = useState<RowSelectionState>({})\n  useEffect(() => {\n    async function fetchPosts() {\n      const res = await fetch(\n        'https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/users-01_fertyx.json'\n      )\n      const data = await res.json()\n      setData(data)\n    }\n    fetchPosts()\n  }, [])\n\n  const table = useReactTable({\n    data,\n    columns,\n    getCoreRowModel: getCoreRowModel(),\n    getSortedRowModel: getSortedRowModel(),\n    onSortingChange: setSorting,\n    enableSortingRemoval: false,\n    getPaginationRowModel: getPaginationRowModel(),\n    onPaginationChange: setPagination,\n    onRowSelectionChange: setRowSelection,\n    enableRowSelection: true,\n    getRowId: (row) => row.id,\n    state: {\n      sorting,\n      pagination,\n      rowSelection,\n    },\n  })\n\n  const { pages, showLeftEllipsis, showRightEllipsis } = usePagination({\n    currentPage: table.getState().pagination.pageIndex + 1,\n    totalPages: table.getPageCount(),\n    paginationItemsToDisplay: 5,\n  })\n\n  return (\n    <div className=\"space-y-4\">\n      <div className=\"bg-background overflow-hidden rounded-md border\">\n        <Table className=\"table-fixed\">\n          <TableHeader>\n            {table.getHeaderGroups().map((headerGroup) => (\n              <TableRow key={headerGroup.id} className=\"hover:bg-transparent\">\n                {headerGroup.headers.map((header) => {\n                  return (\n                    <TableHead\n                      key={header.id}\n                      style={{ width: `${header.getSize()}px` }}\n                      className=\"h-11\"\n                    >\n                      {header.isPlaceholder ? null : header.column.getCanSort() ? (\n                        <div\n                          className={cn(\n                            header.column.getCanSort() &&\n                              'flex h-full cursor-pointer items-center justify-between gap-2 select-none'\n                          )}\n                          onClick={header.column.getToggleSortingHandler()}\n                          onKeyDown={(e) => {\n                            // Enhanced keyboard handling for sorting\n                            if (\n                              header.column.getCanSort() &&\n                              (e.key === 'Enter' || e.key === ' ')\n                            ) {\n                              e.preventDefault()\n                              header.column.getToggleSortingHandler()?.(e)\n                            }\n                          }}\n                          tabIndex={header.column.getCanSort() ? 0 : undefined}\n                        >\n                          {flexRender(header.column.columnDef.header, header.getContext())}\n                          {{\n                            asc: (\n                              <ChevronUpIcon\n                                className=\"shrink-0 opacity-60\"\n                                size={16}\n                                aria-hidden=\"true\"\n                              />\n                            ),\n                            desc: (\n                              <ChevronDownIcon\n                                className=\"shrink-0 opacity-60\"\n                                size={16}\n                                aria-hidden=\"true\"\n                              />\n                            ),\n                          }[header.column.getIsSorted() as string] ?? null}\n                        </div>\n                      ) : (\n                        flexRender(header.column.columnDef.header, header.getContext())\n                      )}\n                    </TableHead>\n                  )\n                })}\n              </TableRow>\n            ))}\n          </TableHeader>\n          <TableBody>\n            {table.getRowModel().rows?.length ? (\n              table.getRowModel().rows.map((row) => (\n                <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>\n                  {row.getVisibleCells().map((cell) => (\n                    <TableCell key={cell.id}>\n                      {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                    </TableCell>\n                  ))}\n                </TableRow>\n              ))\n            ) : (\n              <TableRow>\n                <TableCell colSpan={columns.length} className=\"h-24 text-center\">\n                  No results.\n                </TableCell>\n              </TableRow>\n            )}\n          </TableBody>\n        </Table>\n      </div>\n\n      {/* Pagination */}\n      <div className=\"flex items-center justify-between gap-3 max-sm:flex-col\">\n        {/* Page number information */}\n        <p className=\"text-muted-foreground flex-1 text-sm whitespace-nowrap\" aria-live=\"polite\">\n          Page <span className=\"text-foreground\">{table.getState().pagination.pageIndex + 1}</span>{' '}\n          of <span className=\"text-foreground\">{table.getPageCount()}</span>\n        </p>\n\n        {/* Pagination buttons */}\n        <div className=\"grow\">\n          <Pagination>\n            <PaginationContent>\n              {/* Previous page button */}\n              <PaginationItem>\n                <Button\n                  size=\"icon\"\n                  variant=\"outline\"\n                  className=\"disabled:pointer-events-none disabled:opacity-50\"\n                  onClick={() => table.previousPage()}\n                  disabled={!table.getCanPreviousPage()}\n                  aria-label=\"Go to previous page\"\n                >\n                  <ChevronLeftIcon size={16} aria-hidden=\"true\" />\n                </Button>\n              </PaginationItem>\n\n              {/* Left ellipsis (...) */}\n              {showLeftEllipsis && (\n                <PaginationItem>\n                  <PaginationEllipsis />\n                </PaginationItem>\n              )}\n\n              {/* Page number buttons */}\n              {pages.map((page) => {\n                const isActive = page === table.getState().pagination.pageIndex + 1\n                return (\n                  <PaginationItem key={page}>\n                    <Button\n                      size=\"icon\"\n                      variant={`${isActive ? 'outline' : 'ghost'}`}\n                      onClick={() => table.setPageIndex(page - 1)}\n                      aria-current={isActive ? 'page' : undefined}\n                    >\n                      {page}\n                    </Button>\n                  </PaginationItem>\n                )\n              })}\n\n              {/* Right ellipsis (...) */}\n              {showRightEllipsis && (\n                <PaginationItem>\n                  <PaginationEllipsis />\n                </PaginationItem>\n              )}\n\n              {/* Next page button */}\n              <PaginationItem>\n                <Button\n                  size=\"icon\"\n                  variant=\"outline\"\n                  className=\"disabled:pointer-events-none disabled:opacity-50\"\n                  onClick={() => table.nextPage()}\n                  disabled={!table.getCanNextPage()}\n                  aria-label=\"Go to next page\"\n                >\n                  <ChevronRightIcon size={16} aria-hidden=\"true\" />\n                </Button>\n              </PaginationItem>\n            </PaginationContent>\n          </Pagination>\n        </div>\n\n        {/* Results per page */}\n        <div className=\"flex flex-1 justify-end\">\n          <Select\n            value={table.getState().pagination.pageSize.toString()}\n            onValueChange={(value: string) => {\n              table.setPageSize(Number(value))\n            }}\n            aria-label=\"Results per page\"\n          >\n            <SelectTrigger id=\"results-per-page\" className=\"w-fit whitespace-nowrap\">\n              <SelectValue placeholder=\"Select number of results\" />\n            </SelectTrigger>\n            <SelectContent>\n              {[5, 10, 25, 50].map((pageSize) => (\n                <SelectItem key={pageSize} value={pageSize.toString()}>\n                  {pageSize} / page\n                </SelectItem>\n              ))}\n            </SelectContent>\n          </Select>\n        </div>\n      </div>\n      <p className=\"text-muted-foreground mt-4 text-center text-sm\">\n        Numeric pagination made with{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://tanstack.com/table\"\n          target=\"_blank\"\n          rel=\"noopener noreferrer\"\n        >\n          TanStack Table\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/hooks/use-pagination.ts",
          "type": "registry:hook",
          "target": "components/ui/table-19/use-pagination.ts",
          "content": "type UsePaginationProps = {\n  currentPage: number\n  totalPages: number\n  paginationItemsToDisplay: number\n}\n\ntype UsePaginationReturn = {\n  pages: number[]\n  showLeftEllipsis: boolean\n  showRightEllipsis: boolean\n}\n\nexport function usePagination({\n  currentPage,\n  totalPages,\n  paginationItemsToDisplay,\n}: UsePaginationProps): UsePaginationReturn {\n  const showLeftEllipsis = currentPage - 1 > paginationItemsToDisplay / 2\n  const showRightEllipsis = totalPages - currentPage + 1 > paginationItemsToDisplay / 2\n\n  function calculatePaginationRange(): number[] {\n    if (totalPages <= paginationItemsToDisplay) {\n      return Array.from({ length: totalPages }, (_, i) => i + 1)\n    }\n\n    const halfDisplay = Math.floor(paginationItemsToDisplay / 2)\n    const initialRange = {\n      start: currentPage - halfDisplay,\n      end: currentPage + halfDisplay,\n    }\n\n    const adjustedRange = {\n      start: Math.max(1, initialRange.start),\n      end: Math.min(totalPages, initialRange.end),\n    }\n\n    if (adjustedRange.start === 1) {\n      adjustedRange.end = paginationItemsToDisplay\n    }\n    if (adjustedRange.end === totalPages) {\n      adjustedRange.start = totalPages - paginationItemsToDisplay + 1\n    }\n\n    if (showLeftEllipsis) adjustedRange.start++\n    if (showRightEllipsis) adjustedRange.end--\n\n    return Array.from(\n      { length: adjustedRange.end - adjustedRange.start + 1 },\n      (_, i) => adjustedRange.start + i\n    )\n  }\n\n  const pages = calculatePaginationRange()\n\n  return {\n    pages,\n    showLeftEllipsis,\n    showRightEllipsis,\n  }\n}\n"
        },
        {
          "path": "registry/default/components/table/table-19.vue",
          "target": "components/ui/table-19.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport { ChevronLeftIcon, ChevronRightIcon } from 'lucide-vue-next'\nimport { Button } from '@timui/vue'\nimport { Pagination, PaginationContent, PaginationEllipsis, PaginationItem } from '@timui/vue'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/vue'\nimport { Table } from '@timui/vue'\nimport { TableBody } from '@timui/vue'\nimport { TableCell } from '@timui/vue'\nimport { TableHead } from '@timui/vue'\nimport { TableHeader } from '@timui/vue'\nimport { TableRow } from '@timui/vue'\nimport { usePagination } from '@/registry/default/hooks/use-pagination'\nimport { formatCurrency, tableUsers } from './table-demo-data'\n\nconst pageIndex = ref(0)\nconst pageSize = ref(5)\n\nconst pageCount = computed(() => Math.max(1, Math.ceil(tableUsers.length / pageSize.value)))\n\nconst pagedRows = computed(() => {\n  const start = pageIndex.value * pageSize.value\n  return tableUsers.slice(start, start + pageSize.value)\n})\n\nconst pager = computed(() =>\n  usePagination({\n    currentPage: pageIndex.value + 1,\n    totalPages: pageCount.value,\n    paginationItemsToDisplay: 5,\n  })\n)\n\nfunction previousPage() {\n  pageIndex.value = Math.max(0, pageIndex.value - 1)\n}\n\nfunction nextPage() {\n  pageIndex.value = Math.min(pageCount.value - 1, pageIndex.value + 1)\n}\n\nfunction setPage(page: number) {\n  pageIndex.value = page - 1\n}\n\nfunction changePageSize(value: string) {\n  pageSize.value = Number(value)\n  pageIndex.value = 0\n}\n</script>\n\n<template>\n  <div class=\"space-y-4\">\n    <div class=\"bg-background overflow-hidden rounded-md border\">\n      <Table>\n        <TableHeader>\n          <TableRow class=\"hover:bg-transparent\">\n            <TableHead>Name</TableHead>\n            <TableHead>Email</TableHead>\n            <TableHead>Location</TableHead>\n            <TableHead>Status</TableHead>\n            <TableHead class=\"text-right\">Balance</TableHead>\n          </TableRow>\n        </TableHeader>\n        <TableBody>\n          <TableRow v-for=\"row in pagedRows\" :key=\"row.id\">\n            <TableCell class=\"font-medium\">{{ row.name }}</TableCell>\n            <TableCell>{{ row.email }}</TableCell>\n            <TableCell>{{ row.flag }} {{ row.location }}</TableCell>\n            <TableCell>{{ row.status }}</TableCell>\n            <TableCell class=\"text-right\">{{ formatCurrency(row.balance) }}</TableCell>\n          </TableRow>\n        </TableBody>\n      </Table>\n    </div>\n\n    <div class=\"flex items-center justify-between gap-3 max-sm:flex-col\">\n      <p class=\"text-muted-foreground flex-1 text-sm whitespace-nowrap\" aria-live=\"polite\">\n        Page <span class=\"text-foreground\">{{ pageIndex + 1 }}</span> of <span class=\"text-foreground\">{{ pageCount }}</span>\n      </p>\n\n      <div class=\"grow\">\n        <Pagination>\n          <PaginationContent>\n            <PaginationItem>\n              <Button\n                size=\"icon\"\n                variant=\"outline\"\n                class=\"disabled:pointer-events-none disabled:opacity-50\"\n                :disabled=\"pageIndex === 0\"\n                aria-label=\"Go to previous page\"\n                @click=\"previousPage\"\n              >\n                <ChevronLeftIcon :size=\"16\" aria-hidden=\"true\" />\n              </Button>\n            </PaginationItem>\n\n            <PaginationItem v-if=\"pager.showLeftEllipsis\">\n              <PaginationEllipsis />\n            </PaginationItem>\n\n            <PaginationItem v-for=\"page in pager.pages\" :key=\"page\">\n              <Button\n                size=\"icon\"\n                :variant=\"page === pageIndex + 1 ? 'outline' : 'ghost'\"\n                :aria-current=\"page === pageIndex + 1 ? 'page' : undefined\"\n                @click=\"setPage(page)\"\n              >\n                {{ page }}\n              </Button>\n            </PaginationItem>\n\n            <PaginationItem v-if=\"pager.showRightEllipsis\">\n              <PaginationEllipsis />\n            </PaginationItem>\n\n            <PaginationItem>\n              <Button\n                size=\"icon\"\n                variant=\"outline\"\n                class=\"disabled:pointer-events-none disabled:opacity-50\"\n                :disabled=\"pageIndex >= pageCount - 1\"\n                aria-label=\"Go to next page\"\n                @click=\"nextPage\"\n              >\n                <ChevronRightIcon :size=\"16\" aria-hidden=\"true\" />\n              </Button>\n            </PaginationItem>\n          </PaginationContent>\n        </Pagination>\n      </div>\n\n      <div class=\"flex flex-1 justify-end\">\n        <Select :value=\"String(pageSize)\" @update:modelValue=\"changePageSize\" aria-label=\"Results per page\">\n          <SelectTrigger class=\"w-fit whitespace-nowrap\">\n            <SelectValue placeholder=\"Select number of results\" />\n          </SelectTrigger>\n          <SelectContent>\n            <SelectItem value=\"5\">5 / page</SelectItem>\n            <SelectItem value=\"10\">10 / page</SelectItem>\n            <SelectItem value=\"25\">25 / page</SelectItem>\n            <SelectItem value=\"50\">50 / page</SelectItem>\n          </SelectContent>\n        </Select>\n      </div>\n    </div>\n\n    <p class=\"text-muted-foreground mt-4 text-center text-sm\">\n      Numeric pagination made with\n      <a class=\"hover:text-foreground underline\" href=\"https://tanstack.com/table\" target=\"_blank\" rel=\"noopener noreferrer\">\n        TanStack Table\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/table/table-19.html",
          "target": "components/ui/table-19.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-4\"><div class=\"bg-background overflow-hidden rounded-md border\"><Table class=\"table-fixed\"><TableHeader><!-- Loop table.getHeaderGroups() -->\n<TableRow key=\"${headerGroup.id}\" class=\"hover:bg-transparent\">${headerGroup.headers.map((header) => {\n                  return (\n                    <TableHead\n                      key={header.id}\n                      style={{ width: `${header.getSize()}px` }}\n                      className=\"h-11\"\n                    >\n                      {header.isPlaceholder ? null : header.column.getCanSort() ? (\n                        <div\n                          className={cn(\n                            header.column.getCanSort() &&\n                              'flex h-full cursor-pointer items-center justify-between gap-2 select-none'\n                          )}\n                          onClick={header.column.getToggleSortingHandler()}\n                          onKeyDown={(e) => {\n                            // Enhanced keyboard handling for sorting\n                            if (\n                              header.column.getCanSort() &&\n                              (e.key === 'Enter' || e.key === ' ')\n                            ) {\n                              e.preventDefault()\n                              header.column.getToggleSortingHandler()?.(e)\n                            }\n                          }}\n                          tabIndex={header.column.getCanSort() ? 0 : undefined}\n                        >\n                          {flexRender(header.column.columnDef.header, header.getContext())}\n                          {{\n                            asc: (\n                              <ChevronUpIcon\n                                className=\"shrink-0 opacity-60\"\n                                size={16}\n                                aria-hidden=\"true\"\n                              />\n                            ),\n                            desc: (\n                              <ChevronDownIcon\n                                className=\"shrink-0 opacity-60\"\n                                size={16}\n                                aria-hidden=\"true\"\n                              />\n                            ),\n                          }[header.column.getIsSorted() as string] ?? null}\n                        </div>\n                      ) : (\n                        flexRender(header.column.columnDef.header, header.getContext())\n                      )}\n                    </TableHead>\n                  )\n                })}</TableRow>\n<!-- End Loop --></TableHeader><TableBody><!-- if table.getRowModel().rows?.length -->\n${table.getRowModel().rows.map((row) => (\n                <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>\n                  {row.getVisibleCells().map((cell) => (\n                    <TableCell key={cell.id}>\n                      {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                    </TableCell>\n                  ))}\n                </TableRow>\n              ))}\n<!-- else -->\n<TableRow><TableCell colspan=\"${columns.length}\" class=\"h-24 text-center\">No results.\n                </TableCell></TableRow>\n<!-- endif --></TableBody></Table></div><div class=\"flex items-center justify-between gap-3 max-sm:flex-col\"><p class=\"text-muted-foreground flex-1 text-sm whitespace-nowrap\" aria-live=\"polite\">Page <span class=\"text-foreground\">${table.getState().pagination.pageIndex + 1}</span>${' '}of <span class=\"text-foreground\">${table.getPageCount()}</span></p><div class=\"grow\"><Pagination><PaginationContent><PaginationItem><Button size=\"icon\" variant=\"outline\" class=\"disabled:pointer-events-none disabled:opacity-50\" on-click=\"${() => table.previousPage()}\" disabled=\"${!table.getCanPreviousPage()}\" aria-label=\"Go to previous page\"><ChevronLeftIcon size=\"${16}\" aria-hidden=\"true\" /></Button></PaginationItem><!-- if showLeftEllipsis -->\n<PaginationItem><PaginationEllipsis /></PaginationItem>\n<!-- endif -->${pages.map((page) => {\n                const isActive = page === table.getState().pagination.pageIndex + 1\n                return (\n                  <PaginationItem key={page}>\n                    <Button\n                      size=\"icon\"\n                      variant={`${isActive ? 'outline' : 'ghost'}`}\n                      onClick={() => table.setPageIndex(page - 1)}\n                      aria-current={isActive ? 'page' : undefined}\n                    >\n                      {page}\n                    </Button>\n                  </PaginationItem>\n                )\n              })}<!-- if showRightEllipsis -->\n<PaginationItem><PaginationEllipsis /></PaginationItem>\n<!-- endif --><PaginationItem><Button size=\"icon\" variant=\"outline\" class=\"disabled:pointer-events-none disabled:opacity-50\" on-click=\"${() => table.nextPage()}\" disabled=\"${!table.getCanNextPage()}\" aria-label=\"Go to next page\"><ChevronRightIcon size=\"${16}\" aria-hidden=\"true\" /></Button></PaginationItem></PaginationContent></Pagination></div><div class=\"flex flex-1 justify-end\"><Select value=\"${table.getState().pagination.pageSize.toString()}\" on-value-change=\"${(value: string) => {\n              table.setPageSize(Number(value))\n            }}\" aria-label=\"Results per page\"><SelectTrigger id=\"results-per-page\" class=\"w-fit whitespace-nowrap\"><SelectValue placeholder=\"Select number of results\" /></SelectTrigger><SelectContent><!-- Loop [5, 10, 25, 50] -->\n<SelectItem key=\"${pageSize}\" value=\"${pageSize.toString()}\">${pageSize}/ page\n                </SelectItem>\n<!-- End Loop --></SelectContent></Select></div></div><p class=\"text-muted-foreground mt-4 text-center text-sm\">Numeric pagination made with${' '}<a class=\"hover:text-foreground underline\" href=\"https://tanstack.com/table\" target=\"_blank\" rel=\"noopener noreferrer\">TanStack Table\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/table/table-19.wxml",
          "target": "components/ui/table-19/table-19.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-4\"><view class=\"bg-background overflow-hidden rounded-md border\"><table class=\"table-fixed\"><tableheader><tablerow wx:for=\"{{table.getHeaderGroups()}}\" wx:for-item=\"headerGroup\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{headerGroup.id}}\" class=\"hover:bg-transparent\">{{ headerGroup.headers.map((header) => {\n                  return (\n                    <TableHead\n                      key={header.id}\n                      style={{ width: `${header.getSize()}px` }}\n                      className=\"h-11\"\n                    >\n                      {header.isPlaceholder ? null : header.column.getCanSort() ? (\n                        <div\n                          className={cn(\n                            header.column.getCanSort() &&\n                              'flex h-full cursor-pointer items-center justify-between gap-2 select-none'\n                          )}\n                          onClick={header.column.getToggleSortingHandler()}\n                          onKeyDown={(e) => {\n                            // Enhanced keyboard handling for sorting\n                            if (\n                              header.column.getCanSort() &&\n                              (e.key === 'Enter' || e.key === ' ')\n                            ) {\n                              e.preventDefault()\n                              header.column.getToggleSortingHandler()?.(e)\n                            }\n                          }}\n                          tabIndex={header.column.getCanSort() ? 0 : undefined}\n                        >\n                          {flexRender(header.column.columnDef.header, header.getContext())}\n                          {{\n                            asc: (\n                              <ChevronUpIcon\n                                className=\"shrink-0 opacity-60\"\n                                size={16}\n                                aria-hidden=\"true\"\n                              />\n                            ),\n                            desc: (\n                              <ChevronDownIcon\n                                className=\"shrink-0 opacity-60\"\n                                size={16}\n                                aria-hidden=\"true\"\n                              />\n                            ),\n                          }[header.column.getIsSorted() as string] ?? null}\n                        </div>\n                      ) : (\n                        flexRender(header.column.columnDef.header, header.getContext())\n                      )}\n                    </TableHead>\n                  )\n                }) }}</tablerow></tableheader><tablebody><block wx:if=\"{{table.getRowModel().rows?.length}}\">\n{{ table.getRowModel().rows.map((row) => (\n                <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>\n                  {row.getVisibleCells().map((cell) => (\n                    <TableCell key={cell.id}>\n                      {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                    </TableCell>\n                  ))}\n                </TableRow>\n              )) }}\n</block>\n<block wx:else>\n<tablerow><tablecell colspan=\"{{columns.length}}\" class=\"h-24 text-center\">No results.\n                </tablecell></tablerow>\n</block></tablebody></table></view><view class=\"flex items-center justify-between gap-3 max-sm:flex-col\"><text class=\"text-muted-foreground flex-1 text-sm whitespace-nowrap\" aria-live=\"polite\">Page <text class=\"text-foreground\">{{ table.getState().pagination.pageIndex + 1 }}</text>{{ ' ' }}of <text class=\"text-foreground\">{{ table.getPageCount() }}</text></text><view class=\"grow\"><pagination><paginationcontent><paginationitem><button size=\"icon\" variant=\"outline\" class=\"disabled:pointer-events-none disabled:opacity-50\" bindtap=\"table.previousPage()\" disabled=\"{{!table.getCanPreviousPage()}}\" aria-label=\"Go to previous page\"><chevronlefticon size=\"{{16}}\" aria-hidden=\"true\" /></button></paginationitem><paginationitem wx:if=\"{{showLeftEllipsis}}\"><paginationellipsis /></paginationitem>{{ pages.map((page) => {\n                const isActive = page === table.getState().pagination.pageIndex + 1\n                return (\n                  <PaginationItem key={page}>\n                    <Button\n                      size=\"icon\"\n                      variant={`${isActive ? 'outline' : 'ghost'}`}\n                      onClick={() => table.setPageIndex(page - 1)}\n                      aria-current={isActive ? 'page' : undefined}\n                    >\n                      {page}\n                    </Button>\n                  </PaginationItem>\n                )\n              }) }}<paginationitem wx:if=\"{{showRightEllipsis}}\"><paginationellipsis /></paginationitem><paginationitem><button size=\"icon\" variant=\"outline\" class=\"disabled:pointer-events-none disabled:opacity-50\" bindtap=\"table.nextPage()\" disabled=\"{{!table.getCanNextPage()}}\" aria-label=\"Go to next page\"><chevronrighticon size=\"{{16}}\" aria-hidden=\"true\" /></button></paginationitem></paginationcontent></pagination></view><view class=\"flex flex-1 justify-end\"><select value=\"{{table.getState().pagination.pageSize.toString()}}\" bindchange=\"{\n              table.setPageSize(Number(value))\n            }\" aria-label=\"Results per page\"><selecttrigger id=\"results-per-page\" class=\"w-fit whitespace-nowrap\"><selectvalue placeholder=\"Select number of results\" /></selecttrigger><selectcontent><selectitem wx:for=\"{{[5, 10, 25, 50]}}\" wx:for-item=\"pageSize\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{pageSize}}\" value=\"{{pageSize.toString()}}\">{{ pageSize }}/ page\n                </selectitem></selectcontent></select></view></view><text class=\"text-muted-foreground mt-4 text-center text-sm\">Numeric pagination made with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://tanstack.com/table\" target=\"_blank\" rel=\"noopener noreferrer\">TanStack Table\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "table",
          "tanstack",
          "checkbox",
          "sort",
          "flag",
          "badge",
          "chip",
          "pagination"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "table-19",
          "group": "table",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "table-19",
              "path": "registry/default/components/table/table-19.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "table-19",
              "path": "registry/default/components/table/table-19.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "table-19",
              "path": "registry/default/components/table/table-19.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "table-19",
              "path": "registry/default/components/table/table-19.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@tanstack/react-table",
              "@timui/core",
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tables",
        "title": "Table · Select all rows"
      },
      "categories": [
        "tables",
        "table"
      ]
    },
    {
      "name": "table-20",
      "type": "registry:component",
      "dependencies": [
        "@tanstack/react-table",
        "@timui/core",
        "@timui/react"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/alert-dialog.json",
        "https://ui.timkit.cn/r/badge.json",
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/checkbox.json",
        "https://ui.timkit.cn/r/dropdown-menu.json",
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/pagination.json",
        "https://ui.timkit.cn/r/popover.json",
        "https://ui.timkit.cn/r/select.json",
        "https://ui.timkit.cn/r/table.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/table/table-20.tsx",
          "type": "registry:component",
          "target": "components/ui/table-20.tsx",
          "content": "'use client'\n\nimport { useEffect, useId, useMemo, useRef, useState } from 'react'\nimport type { SyntheticEvent } from 'react'\nimport {\n  ColumnDef,\n  ColumnFiltersState,\n  FilterFn,\n  flexRender,\n  getCoreRowModel,\n  getFacetedUniqueValues,\n  getFilteredRowModel,\n  getPaginationRowModel,\n  getSortedRowModel,\n  PaginationState,\n  Row,\n  RowSelectionState,\n  SortingState,\n  useReactTable,\n  VisibilityState,\n} from '@tanstack/react-table'\nimport { cn } from '@timui/core'\nimport {\n  AlertDialog,\n  AlertDialogAction,\n  AlertDialogCancel,\n  AlertDialogContent,\n  AlertDialogDescription,\n  AlertDialogFooter,\n  AlertDialogHeader,\n  AlertDialogTitle,\n  AlertDialogTrigger,\n  Badge,\n  Button,\n  Checkbox,\n  DropdownMenu,\n  DropdownMenuCheckboxItem,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuPortal,\n  DropdownMenuSeparator,\n  DropdownMenuShortcut,\n  DropdownMenuSub,\n  DropdownMenuSubContent,\n  DropdownMenuSubTrigger,\n  DropdownMenuTrigger,\n  Input,\n  Label,\n  Pagination,\n  PaginationContent,\n  PaginationItem,\n  Popover,\n  PopoverContent,\n  PopoverTrigger,\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n  Table,\n  TableBody,\n  TableCell,\n  TableHead,\n  TableHeader,\n  TableRow,\n} from '@timui/react'\nimport {\n  ChevronDownIcon,\n  ChevronFirstIcon,\n  ChevronLastIcon,\n  ChevronLeftIcon,\n  ChevronRightIcon,\n  ChevronUpIcon,\n  CircleAlertIcon,\n  CircleXIcon,\n  Columns3Icon,\n  EllipsisIcon,\n  FilterIcon,\n  ListFilterIcon,\n  PlusIcon,\n  TrashIcon,\n} from 'lucide-react'\n\ntype Item = {\n  id: string\n  name: string\n  email: string\n  location: string\n  flag: string\n  status: 'Active' | 'Inactive' | 'Pending'\n  balance: number\n}\n\n// Custom filter function for multi-column searching\nconst multiColumnFilterFn: FilterFn<Item> = (row, columnId, filterValue) => {\n  const searchableRowContent = `${row.original.name} ${row.original.email}`.toLowerCase()\n  const searchTerm = (filterValue ?? '').toLowerCase()\n  return searchableRowContent.includes(searchTerm)\n}\n\nconst statusFilterFn: FilterFn<Item> = (row, columnId, filterValue: string[]) => {\n  if (!filterValue?.length) return true\n  const status = row.getValue(columnId) as string\n  return filterValue.includes(status)\n}\n\nconst columns: ColumnDef<Item>[] = [\n  {\n    id: 'select',\n    header: ({ table }) => (\n      <Checkbox\n        checked={\n          table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && 'indeterminate')\n        }\n        onCheckedChange={(value: any) =>\n          table.toggleAllPageRowsSelected(!!(value?.detail?.checked ?? value))\n        }\n        onClick={() => table.toggleAllPageRowsSelected(!table.getIsAllPageRowsSelected())}\n        aria-label=\"Select all\"\n      />\n    ),\n    cell: ({ row }) => (\n      <Checkbox\n        checked={row.getIsSelected()}\n        onCheckedChange={(value: any) => row.toggleSelected(!!(value?.detail?.checked ?? value))}\n        onClick={() => row.toggleSelected(!row.getIsSelected())}\n        aria-label=\"Select row\"\n      />\n    ),\n    size: 28,\n    enableSorting: false,\n    enableHiding: false,\n  },\n  {\n    header: 'Name',\n    accessorKey: 'name',\n    cell: ({ row }) => <div className=\"font-medium\">{row.getValue('name')}</div>,\n    size: 180,\n    filterFn: multiColumnFilterFn,\n    enableHiding: false,\n  },\n  {\n    header: 'Email',\n    accessorKey: 'email',\n    size: 220,\n  },\n  {\n    header: 'Location',\n    accessorKey: 'location',\n    cell: ({ row }) => (\n      <div>\n        <span className=\"text-lg leading-none\">{row.original.flag}</span> {row.getValue('location')}\n      </div>\n    ),\n    size: 180,\n  },\n  {\n    header: 'Status',\n    accessorKey: 'status',\n    cell: ({ row }) => (\n      <Badge\n        className={cn(\n          row.getValue('status') === 'Inactive' && 'bg-muted-foreground/60 text-primary-foreground'\n        )}\n      >\n        {row.getValue('status')}\n      </Badge>\n    ),\n    size: 100,\n    filterFn: statusFilterFn,\n  },\n  {\n    header: 'Performance',\n    accessorKey: 'performance',\n  },\n  {\n    header: 'Balance',\n    accessorKey: 'balance',\n    cell: ({ row }) => {\n      const amount = parseFloat(row.getValue('balance'))\n      const formatted = new Intl.NumberFormat('en-US', {\n        style: 'currency',\n        currency: 'USD',\n      }).format(amount)\n      return formatted\n    },\n    size: 120,\n  },\n  {\n    id: 'actions',\n    header: () => <span className=\"sr-only\">Actions</span>,\n    cell: ({ row }) => <RowActions row={row} />,\n    size: 60,\n    enableHiding: false,\n  },\n]\n\nexport default function Component() {\n  const id = useId()\n  const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([])\n  const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({})\n  const [pagination, setPagination] = useState<PaginationState>({\n    pageIndex: 0,\n    pageSize: 10,\n  })\n  const inputRef = useRef<HTMLInputElement>(null)\n\n  const [sorting, setSorting] = useState<SortingState>([\n    {\n      id: 'name',\n      desc: false,\n    },\n  ])\n\n  const [data, setData] = useState<Item[]>([])\n  const [rowSelection, setRowSelection] = useState<RowSelectionState>({})\n  useEffect(() => {\n    async function fetchPosts() {\n      const res = await fetch(\n        'https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/users-01_fertyx.json'\n      )\n      const data = await res.json()\n      setData(data)\n    }\n    fetchPosts()\n  }, [])\n\n  const handleDeleteRows = () => {\n    const selectedRows = table.getSelectedRowModel().rows\n    const updatedData = data.filter(\n      (item) => !selectedRows.some((row) => row.original.id === item.id)\n    )\n    setData(updatedData)\n    table.resetRowSelection()\n  }\n\n  const table = useReactTable({\n    data,\n    columns,\n    getCoreRowModel: getCoreRowModel(),\n    getSortedRowModel: getSortedRowModel(),\n    onSortingChange: setSorting,\n    enableSortingRemoval: false,\n    getPaginationRowModel: getPaginationRowModel(),\n    onPaginationChange: setPagination,\n    onColumnFiltersChange: setColumnFilters,\n    onColumnVisibilityChange: setColumnVisibility,\n    onRowSelectionChange: setRowSelection,\n    enableRowSelection: true,\n    getRowId: (row) => row.id,\n    getFilteredRowModel: getFilteredRowModel(),\n    getFacetedUniqueValues: getFacetedUniqueValues(),\n    state: {\n      sorting,\n      pagination,\n      columnFilters,\n      columnVisibility,\n      rowSelection,\n    },\n  })\n\n  // Get unique status values\n  const uniqueStatusValues = useMemo(() => {\n    const statusColumn = table.getColumn('status')\n\n    if (!statusColumn) return []\n\n    const values = Array.from(statusColumn.getFacetedUniqueValues().keys())\n\n    return values.sort()\n  }, [table.getColumn('status')?.getFacetedUniqueValues()])\n\n  // Get counts for each status\n  const statusCounts = useMemo(() => {\n    const statusColumn = table.getColumn('status')\n    if (!statusColumn) return new Map()\n    return statusColumn.getFacetedUniqueValues()\n  }, [table.getColumn('status')?.getFacetedUniqueValues()])\n\n  const selectedStatuses = useMemo(() => {\n    const filterValue = table.getColumn('status')?.getFilterValue() as string[]\n    return filterValue ?? []\n  }, [table.getColumn('status')?.getFilterValue()])\n\n  const handleStatusChange = (checked: boolean | 'indeterminate', value: string) => {\n    const filterValue = table.getColumn('status')?.getFilterValue() as string[]\n    const newFilterValue = filterValue ? [...filterValue] : []\n\n    if (checked === true) {\n      newFilterValue.push(value)\n    } else {\n      const index = newFilterValue.indexOf(value)\n      if (index > -1) {\n        newFilterValue.splice(index, 1)\n      }\n    }\n\n    table.getColumn('status')?.setFilterValue(newFilterValue.length ? newFilterValue : undefined)\n  }\n\n  return (\n    <div className=\"space-y-4\">\n      {/* Filters */}\n      <div className=\"flex flex-wrap items-center justify-between gap-3\">\n        <div className=\"flex items-center gap-3\">\n          {/* Filter by name or email */}\n          <div className=\"relative\">\n            <Input\n              id={`${id}-input`}\n              ref={inputRef}\n              className={cn(\n                'peer min-w-60 ps-9',\n                Boolean(table.getColumn('name')?.getFilterValue()) && 'pe-9'\n              )}\n              value={(table.getColumn('name')?.getFilterValue() ?? '') as string}\n              onChange={(e) => table.getColumn('name')?.setFilterValue(e.target.value)}\n              placeholder=\"Filter by name or email...\"\n              type=\"text\"\n              aria-label=\"Filter by name or email\"\n            />\n            <div className=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\">\n              <ListFilterIcon size={16} aria-hidden=\"true\" />\n            </div>\n            {Boolean(table.getColumn('name')?.getFilterValue()) && (\n              <button\n                className=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\"\n                aria-label=\"Clear filter\"\n                onClick={() => {\n                  table.getColumn('name')?.setFilterValue('')\n                  if (inputRef.current) {\n                    inputRef.current.focus()\n                  }\n                }}\n              >\n                <CircleXIcon size={16} aria-hidden=\"true\" />\n              </button>\n            )}\n          </div>\n          {/* Filter by status */}\n          <Popover>\n            <PopoverTrigger asChild>\n              <Button variant=\"outline\">\n                <FilterIcon className=\"-ms-1 opacity-60\" size={16} aria-hidden=\"true\" />\n                Status\n                {selectedStatuses.length > 0 && (\n                  <span className=\"bg-background text-muted-foreground/70 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">\n                    {selectedStatuses.length}\n                  </span>\n                )}\n              </Button>\n            </PopoverTrigger>\n            <PopoverContent className=\"w-auto min-w-36 p-3\" align=\"start\">\n              <div className=\"space-y-3\">\n                <div className=\"text-muted-foreground text-xs font-medium\">Filters</div>\n                <div className=\"space-y-3\">\n                  {uniqueStatusValues.map((value, i) => (\n                    <div key={value} className=\"flex items-center gap-2\">\n                      <Checkbox\n                        id={`${id}-${i}`}\n                        checked={selectedStatuses.includes(value)}\n                        onCheckedChange={(checked: boolean | 'indeterminate') =>\n                          handleStatusChange(checked, value)\n                        }\n                      />\n                      <Label\n                        htmlFor={`${id}-${i}`}\n                        className=\"flex grow justify-between gap-2 font-normal\"\n                      >\n                        {value}{' '}\n                        <span className=\"text-muted-foreground ms-2 text-xs\">\n                          {statusCounts.get(value)}\n                        </span>\n                      </Label>\n                    </div>\n                  ))}\n                </div>\n              </div>\n            </PopoverContent>\n          </Popover>\n          {/* Toggle columns visibility */}\n          <DropdownMenu>\n            <DropdownMenuTrigger asChild>\n              <Button variant=\"outline\">\n                <Columns3Icon className=\"-ms-1 opacity-60\" size={16} aria-hidden=\"true\" />\n                View\n              </Button>\n            </DropdownMenuTrigger>\n            <DropdownMenuContent align=\"end\">\n              <DropdownMenuLabel>Toggle columns</DropdownMenuLabel>\n              {table\n                .getAllColumns()\n                .filter((column) => column.getCanHide())\n                .map((column) => {\n                  return (\n                    <DropdownMenuCheckboxItem\n                      key={column.id}\n                      className=\"capitalize\"\n                      checked={column.getIsVisible()}\n                      onCheckedChange={(value: boolean | 'indeterminate') =>\n                        column.toggleVisibility(!!value)\n                      }\n                      onSelect={(event: SyntheticEvent) => event.preventDefault()}\n                    >\n                      {column.id}\n                    </DropdownMenuCheckboxItem>\n                  )\n                })}\n            </DropdownMenuContent>\n          </DropdownMenu>\n        </div>\n        <div className=\"flex items-center gap-3\">\n          {/* Delete button */}\n          {table.getSelectedRowModel().rows.length > 0 && (\n            <AlertDialog>\n              <AlertDialogTrigger asChild>\n                <Button className=\"ml-auto\" variant=\"outline\">\n                  <TrashIcon className=\"-ms-1 opacity-60\" size={16} aria-hidden=\"true\" />\n                  Delete\n                  <span className=\"bg-background text-muted-foreground/70 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">\n                    {table.getSelectedRowModel().rows.length}\n                  </span>\n                </Button>\n              </AlertDialogTrigger>\n              <AlertDialogContent>\n                <div className=\"flex flex-col gap-2 max-sm:items-center sm:flex-row sm:gap-4\">\n                  <div\n                    className=\"flex size-9 shrink-0 items-center justify-center rounded-full border\"\n                    aria-hidden=\"true\"\n                  >\n                    <CircleAlertIcon className=\"opacity-80\" size={16} />\n                  </div>\n                  <AlertDialogHeader>\n                    <AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>\n                    <AlertDialogDescription>\n                      This action cannot be undone. This will permanently delete{' '}\n                      {table.getSelectedRowModel().rows.length} selected{' '}\n                      {table.getSelectedRowModel().rows.length === 1 ? 'row' : 'rows'}.\n                    </AlertDialogDescription>\n                  </AlertDialogHeader>\n                </div>\n                <AlertDialogFooter>\n                  <AlertDialogCancel>Cancel</AlertDialogCancel>\n                  <AlertDialogAction onClick={handleDeleteRows}>Delete</AlertDialogAction>\n                </AlertDialogFooter>\n              </AlertDialogContent>\n            </AlertDialog>\n          )}\n          {/* Add user button */}\n          <Button className=\"ml-auto\" variant=\"outline\">\n            <PlusIcon className=\"-ms-1 opacity-60\" size={16} aria-hidden=\"true\" />\n            Add user\n          </Button>\n        </div>\n      </div>\n\n      {/* Table */}\n      <div className=\"bg-background overflow-hidden rounded-md border\">\n        <Table className=\"table-fixed\">\n          <TableHeader>\n            {table.getHeaderGroups().map((headerGroup) => (\n              <TableRow key={headerGroup.id} className=\"hover:bg-transparent\">\n                {headerGroup.headers.map((header) => {\n                  return (\n                    <TableHead\n                      key={header.id}\n                      style={{ width: `${header.getSize()}px` }}\n                      className=\"h-11\"\n                    >\n                      {header.isPlaceholder ? null : header.column.getCanSort() ? (\n                        <div\n                          className={cn(\n                            header.column.getCanSort() &&\n                              'flex h-full cursor-pointer items-center justify-between gap-2 select-none'\n                          )}\n                          onClick={header.column.getToggleSortingHandler()}\n                          onKeyDown={(e) => {\n                            // Enhanced keyboard handling for sorting\n                            if (\n                              header.column.getCanSort() &&\n                              (e.key === 'Enter' || e.key === ' ')\n                            ) {\n                              e.preventDefault()\n                              header.column.getToggleSortingHandler()?.(e)\n                            }\n                          }}\n                          tabIndex={header.column.getCanSort() ? 0 : undefined}\n                        >\n                          {flexRender(header.column.columnDef.header, header.getContext())}\n                          {{\n                            asc: (\n                              <ChevronUpIcon\n                                className=\"shrink-0 opacity-60\"\n                                size={16}\n                                aria-hidden=\"true\"\n                              />\n                            ),\n                            desc: (\n                              <ChevronDownIcon\n                                className=\"shrink-0 opacity-60\"\n                                size={16}\n                                aria-hidden=\"true\"\n                              />\n                            ),\n                          }[header.column.getIsSorted() as string] ?? null}\n                        </div>\n                      ) : (\n                        flexRender(header.column.columnDef.header, header.getContext())\n                      )}\n                    </TableHead>\n                  )\n                })}\n              </TableRow>\n            ))}\n          </TableHeader>\n          <TableBody>\n            {table.getRowModel().rows?.length ? (\n              table.getRowModel().rows.map((row) => (\n                <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>\n                  {row.getVisibleCells().map((cell) => (\n                    <TableCell key={cell.id} className=\"last:py-0\">\n                      {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                    </TableCell>\n                  ))}\n                </TableRow>\n              ))\n            ) : (\n              <TableRow>\n                <TableCell colSpan={columns.length} className=\"h-24 text-center\">\n                  No results.\n                </TableCell>\n              </TableRow>\n            )}\n          </TableBody>\n        </Table>\n      </div>\n\n      {/* Pagination */}\n      <div className=\"flex items-center justify-between gap-8\">\n        {/* Results per page */}\n        <div className=\"flex items-center gap-3\">\n          <Label htmlFor={id} className=\"max-sm:sr-only\">\n            Rows per page\n          </Label>\n          <Select\n            value={table.getState().pagination.pageSize.toString()}\n            onValueChange={(value: string) => {\n              table.setPageSize(Number(value))\n            }}\n          >\n            <SelectTrigger id={id} className=\"w-fit whitespace-nowrap\">\n              <SelectValue placeholder=\"Select number of results\" />\n            </SelectTrigger>\n            <SelectContent className=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\">\n              {[5, 10, 25, 50].map((pageSize) => (\n                <SelectItem key={pageSize} value={pageSize.toString()}>\n                  {pageSize}\n                </SelectItem>\n              ))}\n            </SelectContent>\n          </Select>\n        </div>\n        {/* Page number information */}\n        <div className=\"text-muted-foreground flex grow justify-end text-sm whitespace-nowrap\">\n          <p className=\"text-muted-foreground text-sm whitespace-nowrap\" aria-live=\"polite\">\n            <span className=\"text-foreground\">\n              {table.getState().pagination.pageIndex * table.getState().pagination.pageSize + 1}-\n              {Math.min(\n                Math.max(\n                  table.getState().pagination.pageIndex * table.getState().pagination.pageSize +\n                    table.getState().pagination.pageSize,\n                  0\n                ),\n                table.getRowCount()\n              )}\n            </span>{' '}\n            of <span className=\"text-foreground\">{table.getRowCount().toString()}</span>\n          </p>\n        </div>\n\n        {/* Pagination buttons */}\n        <div>\n          <Pagination>\n            <PaginationContent>\n              {/* First page button */}\n              <PaginationItem>\n                <Button\n                  size=\"icon\"\n                  variant=\"outline\"\n                  className=\"disabled:pointer-events-none disabled:opacity-50\"\n                  onClick={() => table.firstPage()}\n                  disabled={!table.getCanPreviousPage()}\n                  aria-label=\"Go to first page\"\n                >\n                  <ChevronFirstIcon size={16} aria-hidden=\"true\" />\n                </Button>\n              </PaginationItem>\n              {/* Previous page button */}\n              <PaginationItem>\n                <Button\n                  size=\"icon\"\n                  variant=\"outline\"\n                  className=\"disabled:pointer-events-none disabled:opacity-50\"\n                  onClick={() => table.previousPage()}\n                  disabled={!table.getCanPreviousPage()}\n                  aria-label=\"Go to previous page\"\n                >\n                  <ChevronLeftIcon size={16} aria-hidden=\"true\" />\n                </Button>\n              </PaginationItem>\n              {/* Next page button */}\n              <PaginationItem>\n                <Button\n                  size=\"icon\"\n                  variant=\"outline\"\n                  className=\"disabled:pointer-events-none disabled:opacity-50\"\n                  onClick={() => table.nextPage()}\n                  disabled={!table.getCanNextPage()}\n                  aria-label=\"Go to next page\"\n                >\n                  <ChevronRightIcon size={16} aria-hidden=\"true\" />\n                </Button>\n              </PaginationItem>\n              {/* Last page button */}\n              <PaginationItem>\n                <Button\n                  size=\"icon\"\n                  variant=\"outline\"\n                  className=\"disabled:pointer-events-none disabled:opacity-50\"\n                  onClick={() => table.lastPage()}\n                  disabled={!table.getCanNextPage()}\n                  aria-label=\"Go to last page\"\n                >\n                  <ChevronLastIcon size={16} aria-hidden=\"true\" />\n                </Button>\n              </PaginationItem>\n            </PaginationContent>\n          </Pagination>\n        </div>\n      </div>\n      <p className=\"text-muted-foreground mt-4 text-center text-sm\">\n        Example of a more complex table made with{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://tanstack.com/table\"\n          target=\"_blank\"\n          rel=\"noopener noreferrer\"\n        >\n          TanStack Table\n        </a>\n      </p>\n    </div>\n  )\n}\n\nfunction RowActions({ row }: { row: Row<Item> }) {\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <div className=\"flex justify-end\">\n          <Button size=\"icon\" variant=\"ghost\" className=\"shadow-none\" aria-label=\"Edit item\">\n            <EllipsisIcon size={16} aria-hidden=\"true\" />\n          </Button>\n        </div>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent align=\"end\">\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <span>Edit</span>\n            <DropdownMenuShortcut>⌘E</DropdownMenuShortcut>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <span>Duplicate</span>\n            <DropdownMenuShortcut>⌘D</DropdownMenuShortcut>\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <span>Archive</span>\n            <DropdownMenuShortcut>⌘A</DropdownMenuShortcut>\n          </DropdownMenuItem>\n          <DropdownMenuSub>\n            <DropdownMenuSubTrigger>More</DropdownMenuSubTrigger>\n            <DropdownMenuPortal>\n              <DropdownMenuSubContent>\n                <DropdownMenuItem>Move to project</DropdownMenuItem>\n                <DropdownMenuItem>Move to folder</DropdownMenuItem>\n                <DropdownMenuSeparator />\n                <DropdownMenuItem>Advanced options</DropdownMenuItem>\n              </DropdownMenuSubContent>\n            </DropdownMenuPortal>\n          </DropdownMenuSub>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuItem>Share</DropdownMenuItem>\n          <DropdownMenuItem>Add to favorites</DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuItem className=\"text-destructive focus:text-destructive\">\n          <span>Delete</span>\n          <DropdownMenuShortcut>⌘⌫</DropdownMenuShortcut>\n        </DropdownMenuItem>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/table/table-20.vue",
          "target": "components/ui/table-20.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, reactive, ref } from 'vue'\nimport {\n  ChevronFirstIcon,\n  ChevronLastIcon,\n  ChevronLeftIcon,\n  ChevronRightIcon,\n  CircleXIcon,\n  Columns3Icon,\n  FilterIcon,\n  ListFilterIcon,\n  PlusIcon,\n  TrashIcon,\n} from 'lucide-vue-next'\nimport { Badge } from '@timui/vue'\nimport { Button } from '@timui/vue'\nimport { Checkbox } from '@timui/vue'\nimport { Input } from '@timui/vue'\nimport { Label } from '@timui/vue'\nimport { Popover, PopoverContent, PopoverTrigger } from '@timui/vue'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/vue'\nimport { Table } from '@timui/vue'\nimport { TableBody } from '@timui/vue'\nimport { TableCell } from '@timui/vue'\nimport { TableHead } from '@timui/vue'\nimport { TableHeader } from '@timui/vue'\nimport { TableRow } from '@timui/vue'\nimport { formatCurrency, tableUsers, type TableUser } from './table-demo-data'\n\nconst data = ref<TableUser[]>([...tableUsers])\nconst selectedIds = reactive(new Set<string>())\nconst searchValue = ref('')\nconst statusFilters = reactive(new Set<TableUser['status']>())\nconst pageIndex = ref(0)\nconst pageSize = ref(10)\n\nconst columnVisibility = reactive({\n  email: true,\n  location: true,\n  status: true,\n  performance: true,\n  balance: true,\n})\n\ntype OptionalColumnKey = keyof typeof columnVisibility\n\nconst optionalColumns: Array<{ key: OptionalColumnKey; label: string }> = [\n  { key: 'email', label: 'Email' },\n  { key: 'location', label: 'Location' },\n  { key: 'status', label: 'Status' },\n  { key: 'performance', label: 'Performance' },\n  { key: 'balance', label: 'Balance' },\n]\n\nfunction toChecked(value: unknown) {\n  return !!((value as { detail?: { checked?: boolean } })?.detail?.checked ?? value)\n}\n\nconst filteredRows = computed(() => {\n  const keyword = searchValue.value.trim().toLowerCase()\n\n  return data.value.filter((row) => {\n    const matchesKeyword =\n      keyword.length === 0 ||\n      row.name.toLowerCase().includes(keyword) ||\n      row.email.toLowerCase().includes(keyword)\n\n    const matchesStatus =\n      statusFilters.size === 0 || statusFilters.has(row.status)\n\n    return matchesKeyword && matchesStatus\n  })\n})\n\nconst pageCount = computed(() => Math.max(1, Math.ceil(filteredRows.value.length / pageSize.value)))\n\nconst pagedRows = computed(() => {\n  const start = pageIndex.value * pageSize.value\n  return filteredRows.value.slice(start, start + pageSize.value)\n})\n\nconst allPageSelected = computed(\n  () => pagedRows.value.length > 0 && pagedRows.value.every((row) => selectedIds.has(row.id))\n)\n\nconst somePageSelected = computed(\n  () => pagedRows.value.some((row) => selectedIds.has(row.id)) && !allPageSelected.value\n)\n\nconst selectedCount = computed(() => selectedIds.size)\n\nconst visibleColumns = computed(() => optionalColumns.filter((column) => columnVisibility[column.key]))\n\nconst uniqueStatusValues = computed(() => ['Active', 'Inactive', 'Pending'] as Array<TableUser['status']>)\n\nconst rangeLabel = computed(() => {\n  const start = pageIndex.value * pageSize.value + 1\n  const end = Math.min(start + pageSize.value - 1, filteredRows.value.length)\n  return `${start}-${end} of ${filteredRows.value.length}`\n})\n\nfunction toggleAllPageRows(next: boolean) {\n  if (next) {\n    pagedRows.value.forEach((row) => selectedIds.add(row.id))\n    return\n  }\n\n  pagedRows.value.forEach((row) => selectedIds.delete(row.id))\n}\n\nfunction toggleRow(id: string, next: boolean) {\n  if (next) {\n    selectedIds.add(id)\n  } else {\n    selectedIds.delete(id)\n  }\n}\n\nfunction toggleStatusFilter(status: TableUser['status'], checked: boolean) {\n  if (checked) {\n    statusFilters.add(status)\n  } else {\n    statusFilters.delete(status)\n  }\n\n  pageIndex.value = 0\n}\n\nfunction clearSearch() {\n  searchValue.value = ''\n  pageIndex.value = 0\n}\n\nfunction toggleColumn(key: OptionalColumnKey, checked: boolean) {\n  columnVisibility[key] = checked\n}\n\nfunction deleteSelected() {\n  if (selectedIds.size === 0) return\n\n  data.value = data.value.filter((row) => !selectedIds.has(row.id))\n  selectedIds.clear()\n\n  if (pageIndex.value >= pageCount.value - 1) {\n    pageIndex.value = Math.max(0, pageCount.value - 1)\n  }\n}\n\nfunction firstPage() {\n  pageIndex.value = 0\n}\n\nfunction previousPage() {\n  pageIndex.value = Math.max(0, pageIndex.value - 1)\n}\n\nfunction nextPage() {\n  pageIndex.value = Math.min(pageCount.value - 1, pageIndex.value + 1)\n}\n\nfunction lastPage() {\n  pageIndex.value = pageCount.value - 1\n}\n\nfunction changePageSize(value: string) {\n  pageSize.value = Number(value)\n  pageIndex.value = 0\n}\n</script>\n\n<template>\n  <div class=\"space-y-4\">\n    <div class=\"flex flex-wrap items-center justify-between gap-3\">\n      <div class=\"flex items-center gap-3\">\n        <div class=\"relative\">\n          <Input\n            class=\"peer min-w-60 ps-9\"\n            :class=\"searchValue ? 'pe-9' : undefined\"\n            :value=\"searchValue\"\n            placeholder=\"Filter by name or email...\"\n            type=\"text\"\n            aria-label=\"Filter by name or email\"\n            @input=\"searchValue = ($event.target as HTMLInputElement).value\"\n          />\n          <div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3\">\n            <ListFilterIcon :size=\"16\" aria-hidden=\"true\" />\n          </div>\n          <button\n            v-if=\"searchValue\"\n            class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px]\"\n            aria-label=\"Clear filter\"\n            @click=\"clearSearch\"\n          >\n            <CircleXIcon :size=\"16\" aria-hidden=\"true\" />\n          </button>\n        </div>\n\n        <Popover>\n          <PopoverTrigger as-child>\n            <Button variant=\"outline\">\n              <FilterIcon class=\"-ms-1 opacity-60\" :size=\"16\" aria-hidden=\"true\" />\n              Status\n              <span\n                v-if=\"statusFilters.size > 0\"\n                class=\"bg-background text-muted-foreground/70 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 text-[0.625rem] font-medium\"\n              >\n                {{ statusFilters.size }}\n              </span>\n            </Button>\n          </PopoverTrigger>\n          <PopoverContent class=\"w-auto min-w-36 p-3\" align=\"start\">\n            <div class=\"space-y-3\">\n              <div class=\"text-muted-foreground text-xs font-medium\">Filters</div>\n              <div class=\"space-y-3\">\n                <div v-for=\"status in uniqueStatusValues\" :key=\"status\" class=\"flex items-center gap-2\">\n                  <Checkbox\n                    :id=\"`status-${status}`\"\n                    :checked=\"statusFilters.has(status)\"\n                    :onCheckedChange=\"(value: unknown) => toggleStatusFilter(status, toChecked(value))\"\n                  />\n                  <Label :for=\"`status-${status}`\" class=\"font-normal\">{{ status }}</Label>\n                </div>\n              </div>\n            </div>\n          </PopoverContent>\n        </Popover>\n\n        <Popover>\n          <PopoverTrigger as-child>\n            <Button variant=\"outline\">\n              <Columns3Icon class=\"-ms-1 opacity-60\" :size=\"16\" aria-hidden=\"true\" />\n              View\n            </Button>\n          </PopoverTrigger>\n          <PopoverContent class=\"w-auto min-w-36 p-3\" align=\"start\">\n            <div class=\"space-y-3\">\n              <div class=\"text-muted-foreground text-xs font-medium\">Toggle columns</div>\n              <div class=\"space-y-3\">\n                <div v-for=\"column in optionalColumns\" :key=\"column.key\" class=\"flex items-center gap-2\">\n                  <Checkbox\n                    :id=\"`column-${column.key}`\"\n                    :checked=\"columnVisibility[column.key]\"\n                    :onCheckedChange=\"(value: unknown) => toggleColumn(column.key, toChecked(value))\"\n                  />\n                  <Label :for=\"`column-${column.key}`\" class=\"font-normal\">{{ column.label }}</Label>\n                </div>\n              </div>\n            </div>\n          </PopoverContent>\n        </Popover>\n      </div>\n\n      <div class=\"flex items-center gap-3\">\n        <Button v-if=\"selectedCount > 0\" variant=\"outline\" @click=\"deleteSelected\">\n          <TrashIcon class=\"-ms-1 opacity-60\" :size=\"16\" aria-hidden=\"true\" />\n          Delete\n          <span class=\"bg-background text-muted-foreground/70 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 text-[0.625rem] font-medium\">\n            {{ selectedCount }}\n          </span>\n        </Button>\n\n        <Button variant=\"outline\">\n          <PlusIcon class=\"-ms-1 opacity-60\" :size=\"16\" aria-hidden=\"true\" />\n          Add user\n        </Button>\n      </div>\n    </div>\n\n    <div class=\"bg-background overflow-hidden rounded-md border\">\n      <Table class=\"table-fixed\">\n        <TableHeader>\n          <TableRow class=\"hover:bg-transparent\">\n            <TableHead class=\"h-11 w-10\">\n              <Checkbox\n                :checked=\"allPageSelected || (somePageSelected && 'indeterminate')\"\n                :onCheckedChange=\"(value: unknown) => toggleAllPageRows(toChecked(value))\"\n                aria-label=\"Select all\"\n              />\n            </TableHead>\n            <TableHead class=\"h-11\">Name</TableHead>\n            <TableHead v-for=\"column in visibleColumns\" :key=\"column.key\" class=\"h-11\">\n              {{ column.label }}\n            </TableHead>\n          </TableRow>\n        </TableHeader>\n\n        <TableBody>\n          <template v-if=\"pagedRows.length > 0\">\n            <TableRow\n              v-for=\"row in pagedRows\"\n              :key=\"row.id\"\n              :data-state=\"selectedIds.has(row.id) ? 'selected' : undefined\"\n            >\n              <TableCell>\n                <Checkbox\n                  :checked=\"selectedIds.has(row.id)\"\n                  :onCheckedChange=\"(value: unknown) => toggleRow(row.id, toChecked(value))\"\n                  :aria-label=\"`Select ${row.name}`\"\n                />\n              </TableCell>\n\n              <TableCell class=\"font-medium\">{{ row.name }}</TableCell>\n\n              <TableCell v-if=\"columnVisibility.email\">{{ row.email }}</TableCell>\n              <TableCell v-if=\"columnVisibility.location\">{{ row.flag }} {{ row.location }}</TableCell>\n              <TableCell v-if=\"columnVisibility.status\">\n                <Badge\n                  :class=\"\n                    row.status === 'Inactive'\n                      ? 'bg-muted-foreground/60 text-primary-foreground'\n                      : row.status === 'Pending'\n                        ? 'bg-amber-500/20 text-amber-600'\n                        : undefined\n                  \"\n                >\n                  {{ row.status }}\n                </Badge>\n              </TableCell>\n              <TableCell v-if=\"columnVisibility.performance\">{{ row.performance }}</TableCell>\n              <TableCell v-if=\"columnVisibility.balance\" class=\"text-right\">{{ formatCurrency(row.balance) }}</TableCell>\n            </TableRow>\n          </template>\n\n          <template v-else>\n            <TableRow>\n              <TableCell :colSpan=\"visibleColumns.length + 2\" class=\"h-24 text-center\">No results.</TableCell>\n            </TableRow>\n          </template>\n        </TableBody>\n      </Table>\n    </div>\n\n    <div class=\"flex items-center justify-between gap-8\">\n      <div class=\"flex items-center gap-3\">\n        <Label for=\"table-20-page-size\" class=\"max-sm:sr-only\">Rows per page</Label>\n        <Select :value=\"String(pageSize)\" @update:modelValue=\"changePageSize\">\n          <SelectTrigger id=\"table-20-page-size\" class=\"w-fit whitespace-nowrap\">\n            <SelectValue placeholder=\"Rows per page\" />\n          </SelectTrigger>\n          <SelectContent>\n            <SelectItem value=\"5\">5</SelectItem>\n            <SelectItem value=\"10\">10</SelectItem>\n            <SelectItem value=\"25\">25</SelectItem>\n            <SelectItem value=\"50\">50</SelectItem>\n          </SelectContent>\n        </Select>\n      </div>\n\n      <div class=\"text-muted-foreground flex grow justify-end text-sm whitespace-nowrap\">\n        <p aria-live=\"polite\">{{ rangeLabel }}</p>\n      </div>\n\n      <div class=\"flex items-center gap-2\">\n        <Button size=\"icon\" variant=\"outline\" :disabled=\"pageIndex === 0\" aria-label=\"Go to first page\" @click=\"firstPage\">\n          <ChevronFirstIcon :size=\"16\" aria-hidden=\"true\" />\n        </Button>\n        <Button size=\"icon\" variant=\"outline\" :disabled=\"pageIndex === 0\" aria-label=\"Go to previous page\" @click=\"previousPage\">\n          <ChevronLeftIcon :size=\"16\" aria-hidden=\"true\" />\n        </Button>\n        <Button size=\"icon\" variant=\"outline\" :disabled=\"pageIndex >= pageCount - 1\" aria-label=\"Go to next page\" @click=\"nextPage\">\n          <ChevronRightIcon :size=\"16\" aria-hidden=\"true\" />\n        </Button>\n        <Button size=\"icon\" variant=\"outline\" :disabled=\"pageIndex >= pageCount - 1\" aria-label=\"Go to last page\" @click=\"lastPage\">\n          <ChevronLastIcon :size=\"16\" aria-hidden=\"true\" />\n        </Button>\n      </div>\n    </div>\n\n    <p class=\"text-muted-foreground mt-4 text-center text-sm\">\n      Example of a more complex table made with\n      <a class=\"hover:text-foreground underline\" href=\"https://tanstack.com/table\" target=\"_blank\" rel=\"noopener noreferrer\">\n        TanStack Table\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/table/table-20.html",
          "target": "components/ui/table-20.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-4\"><div class=\"flex flex-wrap items-center justify-between gap-3\"><div class=\"flex items-center gap-3\"><div class=\"relative\"><Input id=\"${`${id}-input`}\" ref=\"${inputRef}\" class=\"${cn(\n                'peer min-w-60 ps-9',\n                Boolean(table.getColumn('name')?.getFilterValue()) && 'pe-9'\n              )}\" value=\"${(table.getColumn('name')?.getFilterValue() ?? '') as string}\" onchange=\"${(e) => table.getColumn('name')?.setFilterValue(e.target.value)}\" placeholder=\"Filter by name or email...\" type=\"text\" aria-label=\"Filter by name or email\" /><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\"><ListFilterIcon size=\"${16}\" aria-hidden=\"true\" /></div><!-- if Boolean(table.getColumn('name')?.getFilterValue()) -->\n<button class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\" aria-label=\"Clear filter\" on-click=\"${() => {\n                  table.getColumn('name')?.setFilterValue('')\n                  if (inputRef.current) {\n                    inputRef.current.focus()\n                  }\n                }}\"><CircleXIcon size=\"${16}\" aria-hidden=\"true\" /></button>\n<!-- endif --></div><Popover><PopoverTrigger aschild><Button variant=\"outline\"><FilterIcon class=\"-ms-1 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Status\n                <!-- if selectedStatuses.length > 0 -->\n<span class=\"bg-background text-muted-foreground/70 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">${selectedStatuses.length}</span>\n<!-- endif --></Button></PopoverTrigger><PopoverContent class=\"w-auto min-w-36 p-3\" align=\"start\"><div class=\"space-y-3\"><div class=\"text-muted-foreground text-xs font-medium\">Filters</div><div class=\"space-y-3\"><!-- Loop uniqueStatusValues -->\n<div key=\"${value}\" class=\"flex items-center gap-2\"><Checkbox id=\"${`${id}-${i}`}\" checked=\"${selectedStatuses.includes(value)}\" oncheckedchange=\"${(checked: boolean | 'indeterminate') =>\n                          handleStatusChange(checked, value)}\" /><Label htmlfor=\"${`${id}-${i}`}\" class=\"flex grow justify-between gap-2 font-normal\">${value}${' '}<span class=\"text-muted-foreground ms-2 text-xs\">${statusCounts.get(value)}</span></Label></div>\n<!-- End Loop --></div></div></PopoverContent></Popover><DropdownMenu><DropdownMenuTrigger aschild><Button variant=\"outline\"><Columns3Icon class=\"-ms-1 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />View\n              </Button></DropdownMenuTrigger><DropdownMenuContent align=\"end\"><DropdownMenuLabel>Toggle columns</DropdownMenuLabel>${table\n                .getAllColumns()\n                .filter((column) => column.getCanHide())\n                .map((column) => {\n                  return (\n                    <DropdownMenuCheckboxItem\n                      key={column.id}\n                      className=\"capitalize\"\n                      checked={column.getIsVisible()}\n                      onCheckedChange={(value: boolean | 'indeterminate') =>\n                        column.toggleVisibility(!!value)\n                      }\n                      onSelect={(event: SyntheticEvent) => event.preventDefault()}\n                    >\n                      {column.id}\n                    </DropdownMenuCheckboxItem>\n                  )\n                })}</DropdownMenuContent></DropdownMenu></div><div class=\"flex items-center gap-3\"><!-- if table.getSelectedRowModel().rows.length > 0 -->\n<AlertDialog><AlertDialogTrigger aschild><Button class=\"ml-auto\" variant=\"outline\"><TrashIcon class=\"-ms-1 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Delete\n                  <span class=\"bg-background text-muted-foreground/70 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">${table.getSelectedRowModel().rows.length}</span></Button></AlertDialogTrigger><AlertDialogContent><div class=\"flex flex-col gap-2 max-sm:items-center sm:flex-row sm:gap-4\"><div class=\"flex size-9 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><CircleAlertIcon class=\"opacity-80\" size=\"${16}\" /></div><AlertDialogHeader><AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle><AlertDialogDescription>This action cannot be undone. This will permanently delete${' '}${table.getSelectedRowModel().rows.length}selected${' '}<!-- if table.getSelectedRowModel().rows.length === 1 -->\n${'row'}\n<!-- else -->\n${'rows'}\n<!-- endif -->.\n                    </AlertDialogDescription></AlertDialogHeader></div><AlertDialogFooter><AlertDialogCancel>Cancel</AlertDialogCancel><AlertDialogAction on-click=\"${handleDeleteRows}\">Delete</AlertDialogAction></AlertDialogFooter></AlertDialogContent></AlertDialog>\n<!-- endif --><Button class=\"ml-auto\" variant=\"outline\"><PlusIcon class=\"-ms-1 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Add user\n          </Button></div></div><div class=\"bg-background overflow-hidden rounded-md border\"><Table class=\"table-fixed\"><TableHeader><!-- Loop table.getHeaderGroups() -->\n<TableRow key=\"${headerGroup.id}\" class=\"hover:bg-transparent\">${headerGroup.headers.map((header) => {\n                  return (\n                    <TableHead\n                      key={header.id}\n                      style={{ width: `${header.getSize()}px` }}\n                      className=\"h-11\"\n                    >\n                      {header.isPlaceholder ? null : header.column.getCanSort() ? (\n                        <div\n                          className={cn(\n                            header.column.getCanSort() &&\n                              'flex h-full cursor-pointer items-center justify-between gap-2 select-none'\n                          )}\n                          onClick={header.column.getToggleSortingHandler()}\n                          onKeyDown={(e) => {\n                            // Enhanced keyboard handling for sorting\n                            if (\n                              header.column.getCanSort() &&\n                              (e.key === 'Enter' || e.key === ' ')\n                            ) {\n                              e.preventDefault()\n                              header.column.getToggleSortingHandler()?.(e)\n                            }\n                          }}\n                          tabIndex={header.column.getCanSort() ? 0 : undefined}\n                        >\n                          {flexRender(header.column.columnDef.header, header.getContext())}\n                          {{\n                            asc: (\n                              <ChevronUpIcon\n                                className=\"shrink-0 opacity-60\"\n                                size={16}\n                                aria-hidden=\"true\"\n                              />\n                            ),\n                            desc: (\n                              <ChevronDownIcon\n                                className=\"shrink-0 opacity-60\"\n                                size={16}\n                                aria-hidden=\"true\"\n                              />\n                            ),\n                          }[header.column.getIsSorted() as string] ?? null}\n                        </div>\n                      ) : (\n                        flexRender(header.column.columnDef.header, header.getContext())\n                      )}\n                    </TableHead>\n                  )\n                })}</TableRow>\n<!-- End Loop --></TableHeader><TableBody><!-- if table.getRowModel().rows?.length -->\n${table.getRowModel().rows.map((row) => (\n                <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>\n                  {row.getVisibleCells().map((cell) => (\n                    <TableCell key={cell.id} className=\"last:py-0\">\n                      {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                    </TableCell>\n                  ))}\n                </TableRow>\n              ))}\n<!-- else -->\n<TableRow><TableCell colspan=\"${columns.length}\" class=\"h-24 text-center\">No results.\n                </TableCell></TableRow>\n<!-- endif --></TableBody></Table></div><div class=\"flex items-center justify-between gap-8\"><div class=\"flex items-center gap-3\"><Label htmlfor=\"${id}\" class=\"max-sm:sr-only\">Rows per page\n          </Label><Select value=\"${table.getState().pagination.pageSize.toString()}\" on-value-change=\"${(value: string) => {\n              table.setPageSize(Number(value))\n            }}\"><SelectTrigger id=\"${id}\" class=\"w-fit whitespace-nowrap\"><SelectValue placeholder=\"Select number of results\" /></SelectTrigger><SelectContent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\"><!-- Loop [5, 10, 25, 50] -->\n<SelectItem key=\"${pageSize}\" value=\"${pageSize.toString()}\">${pageSize}</SelectItem>\n<!-- End Loop --></SelectContent></Select></div><div class=\"text-muted-foreground flex grow justify-end text-sm whitespace-nowrap\"><p class=\"text-muted-foreground text-sm whitespace-nowrap\" aria-live=\"polite\"><span class=\"text-foreground\">${table.getState().pagination.pageIndex * table.getState().pagination.pageSize + 1}-\n              ${Math.min(\n                Math.max(\n                  table.getState().pagination.pageIndex * table.getState().pagination.pageSize +\n                    table.getState().pagination.pageSize,\n                  0\n                ),\n                table.getRowCount()\n              )}</span>${' '}of <span class=\"text-foreground\">${table.getRowCount().toString()}</span></p></div><div><Pagination><PaginationContent><PaginationItem><Button size=\"icon\" variant=\"outline\" class=\"disabled:pointer-events-none disabled:opacity-50\" on-click=\"${() => table.firstPage()}\" disabled=\"${!table.getCanPreviousPage()}\" aria-label=\"Go to first page\"><ChevronFirstIcon size=\"${16}\" aria-hidden=\"true\" /></Button></PaginationItem><PaginationItem><Button size=\"icon\" variant=\"outline\" class=\"disabled:pointer-events-none disabled:opacity-50\" on-click=\"${() => table.previousPage()}\" disabled=\"${!table.getCanPreviousPage()}\" aria-label=\"Go to previous page\"><ChevronLeftIcon size=\"${16}\" aria-hidden=\"true\" /></Button></PaginationItem><PaginationItem><Button size=\"icon\" variant=\"outline\" class=\"disabled:pointer-events-none disabled:opacity-50\" on-click=\"${() => table.nextPage()}\" disabled=\"${!table.getCanNextPage()}\" aria-label=\"Go to next page\"><ChevronRightIcon size=\"${16}\" aria-hidden=\"true\" /></Button></PaginationItem><PaginationItem><Button size=\"icon\" variant=\"outline\" class=\"disabled:pointer-events-none disabled:opacity-50\" on-click=\"${() => table.lastPage()}\" disabled=\"${!table.getCanNextPage()}\" aria-label=\"Go to last page\"><ChevronLastIcon size=\"${16}\" aria-hidden=\"true\" /></Button></PaginationItem></PaginationContent></Pagination></div></div><p class=\"text-muted-foreground mt-4 text-center text-sm\">Example of a more complex table made with${' '}<a class=\"hover:text-foreground underline\" href=\"https://tanstack.com/table\" target=\"_blank\" rel=\"noopener noreferrer\">TanStack Table\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/table/table-20.wxml",
          "target": "components/ui/table-20/table-20.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-4\"><view class=\"flex flex-wrap items-center justify-between gap-3\"><view class=\"flex items-center gap-3\"><view class=\"relative\"><input id=\"{{`${id}-input`}}\" ref=\"{{inputRef}}\" class=\"{{cn(\n                'peer min-w-60 ps-9',\n                Boolean(table.getColumn('name')?.getFilterValue()) && 'pe-9'\n              )}}\" value=\"{{(table.getColumn('name')?.getFilterValue() ?? '') as string}}\" onchange=\"{{(e) => table.getColumn('name')?.setFilterValue(e.target.value)}}\" placeholder=\"Filter by name or email...\" type=\"text\" aria-label=\"Filter by name or email\" /><view class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\"><listfiltericon size=\"{{16}}\" aria-hidden=\"true\" /></view><button wx:if=\"{{Boolean(table.getColumn('name')?.getFilterValue())}}\" class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\" aria-label=\"Clear filter\" bindtap=\"{\n                  table.getColumn('name')?.setFilterValue('')\n                  if (inputRef.current) {\n                    inputRef.current.focus()\n                  }\n                }\"><circlexicon size=\"{{16}}\" aria-hidden=\"true\" /></button></view><popover><popovertrigger aschild><button variant=\"outline\"><filtericon class=\"-ms-1 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Status\n                <text wx:if=\"{{selectedStatuses.length > 0}}\" class=\"bg-background text-muted-foreground/70 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">{{ selectedStatuses.length }}</text></button></popovertrigger><popovercontent class=\"w-auto min-w-36 p-3\" align=\"start\"><view class=\"space-y-3\"><view class=\"text-muted-foreground text-xs font-medium\">Filters</view><view class=\"space-y-3\"><view wx:for=\"{{uniqueStatusValues}}\" wx:for-item=\"value\" wx:for-index=\"i\" wx:key=\"i\" key=\"{{value}}\" class=\"flex items-center gap-2\"><checkbox id=\"{{`${id}-${i}`}}\" checked=\"{{selectedStatuses.includes(value)}}\" oncheckedchange=\"{{(checked: boolean | 'indeterminate') =>\n                          handleStatusChange(checked, value)}}\" /><label htmlfor=\"{{`${id}-${i}`}}\" class=\"flex grow justify-between gap-2 font-normal\">{{ value }}{{ ' ' }}<text class=\"text-muted-foreground ms-2 text-xs\">{{ statusCounts.get(value) }}</text></label></view></view></view></popovercontent></popover><dropdownmenu><dropdownmenutrigger aschild><button variant=\"outline\"><columns3icon class=\"-ms-1 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />View\n              </button></dropdownmenutrigger><dropdownmenucontent align=\"end\"><dropdownmenulabel>Toggle columns</dropdownmenulabel>{{ table\n                .getAllColumns()\n                .filter((column) => column.getCanHide())\n                .map((column) => {\n                  return (\n                    <DropdownMenuCheckboxItem\n                      key={column.id}\n                      className=\"capitalize\"\n                      checked={column.getIsVisible()}\n                      onCheckedChange={(value: boolean | 'indeterminate') =>\n                        column.toggleVisibility(!!value)\n                      }\n                      onSelect={(event: SyntheticEvent) => event.preventDefault()}\n                    >\n                      {column.id}\n                    </DropdownMenuCheckboxItem>\n                  )\n                }) }}</dropdownmenucontent></dropdownmenu></view><view class=\"flex items-center gap-3\"><alertdialog wx:if=\"{{table.getSelectedRowModel().rows.length > 0}}\"><alertdialogtrigger aschild><button class=\"ml-auto\" variant=\"outline\"><trashicon class=\"-ms-1 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Delete\n                  <text class=\"bg-background text-muted-foreground/70 -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">{{ table.getSelectedRowModel().rows.length }}</text></button></alertdialogtrigger><alertdialogcontent><view class=\"flex flex-col gap-2 max-sm:items-center sm:flex-row sm:gap-4\"><view class=\"flex size-9 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><circlealerticon class=\"opacity-80\" size=\"{{16}}\" /></view><alertdialogheader><alertdialogtitle>Are you absolutely sure?</alertdialogtitle><alertdialogdescription>This action cannot be undone. This will permanently delete{{ ' ' }}{{ table.getSelectedRowModel().rows.length }}selected{{ ' ' }}<block wx:if=\"{{table.getSelectedRowModel().rows.length === 1}}\">\n{{ 'row' }}\n</block>\n<block wx:else>\n{{ 'rows' }}\n</block>.\n                    </alertdialogdescription></alertdialogheader></view><alertdialogfooter><alertdialogcancel>Cancel</alertdialogcancel><alertdialogaction bindtap=\"handleDeleteRows\">Delete</alertdialogaction></alertdialogfooter></alertdialogcontent></alertdialog><button class=\"ml-auto\" variant=\"outline\"><plusicon class=\"-ms-1 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Add user\n          </button></view></view><view class=\"bg-background overflow-hidden rounded-md border\"><table class=\"table-fixed\"><tableheader><tablerow wx:for=\"{{table.getHeaderGroups()}}\" wx:for-item=\"headerGroup\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{headerGroup.id}}\" class=\"hover:bg-transparent\">{{ headerGroup.headers.map((header) => {\n                  return (\n                    <TableHead\n                      key={header.id}\n                      style={{ width: `${header.getSize()}px` }}\n                      className=\"h-11\"\n                    >\n                      {header.isPlaceholder ? null : header.column.getCanSort() ? (\n                        <div\n                          className={cn(\n                            header.column.getCanSort() &&\n                              'flex h-full cursor-pointer items-center justify-between gap-2 select-none'\n                          )}\n                          onClick={header.column.getToggleSortingHandler()}\n                          onKeyDown={(e) => {\n                            // Enhanced keyboard handling for sorting\n                            if (\n                              header.column.getCanSort() &&\n                              (e.key === 'Enter' || e.key === ' ')\n                            ) {\n                              e.preventDefault()\n                              header.column.getToggleSortingHandler()?.(e)\n                            }\n                          }}\n                          tabIndex={header.column.getCanSort() ? 0 : undefined}\n                        >\n                          {flexRender(header.column.columnDef.header, header.getContext())}\n                          {{\n                            asc: (\n                              <ChevronUpIcon\n                                className=\"shrink-0 opacity-60\"\n                                size={16}\n                                aria-hidden=\"true\"\n                              />\n                            ),\n                            desc: (\n                              <ChevronDownIcon\n                                className=\"shrink-0 opacity-60\"\n                                size={16}\n                                aria-hidden=\"true\"\n                              />\n                            ),\n                          }[header.column.getIsSorted() as string] ?? null}\n                        </div>\n                      ) : (\n                        flexRender(header.column.columnDef.header, header.getContext())\n                      )}\n                    </TableHead>\n                  )\n                }) }}</tablerow></tableheader><tablebody><block wx:if=\"{{table.getRowModel().rows?.length}}\">\n{{ table.getRowModel().rows.map((row) => (\n                <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>\n                  {row.getVisibleCells().map((cell) => (\n                    <TableCell key={cell.id} className=\"last:py-0\">\n                      {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                    </TableCell>\n                  ))}\n                </TableRow>\n              )) }}\n</block>\n<block wx:else>\n<tablerow><tablecell colspan=\"{{columns.length}}\" class=\"h-24 text-center\">No results.\n                </tablecell></tablerow>\n</block></tablebody></table></view><view class=\"flex items-center justify-between gap-8\"><view class=\"flex items-center gap-3\"><label htmlfor=\"{{id}}\" class=\"max-sm:sr-only\">Rows per page\n          </label><select value=\"{{table.getState().pagination.pageSize.toString()}}\" bindchange=\"{\n              table.setPageSize(Number(value))\n            }\"><selecttrigger id=\"{{id}}\" class=\"w-fit whitespace-nowrap\"><selectvalue placeholder=\"Select number of results\" /></selecttrigger><selectcontent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\"><selectitem wx:for=\"{{[5, 10, 25, 50]}}\" wx:for-item=\"pageSize\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{pageSize}}\" value=\"{{pageSize.toString()}}\">{{ pageSize }}</selectitem></selectcontent></select></view><view class=\"text-muted-foreground flex grow justify-end text-sm whitespace-nowrap\"><text class=\"text-muted-foreground text-sm whitespace-nowrap\" aria-live=\"polite\"><text class=\"text-foreground\">{{ table.getState().pagination.pageIndex * table.getState().pagination.pageSize + 1 }}-\n              {{ Math.min(\n                Math.max(\n                  table.getState().pagination.pageIndex * table.getState().pagination.pageSize +\n                    table.getState().pagination.pageSize,\n                  0\n                ),\n                table.getRowCount()\n              ) }}</text>{{ ' ' }}of <text class=\"text-foreground\">{{ table.getRowCount().toString() }}</text></text></view><view><pagination><paginationcontent><paginationitem><button size=\"icon\" variant=\"outline\" class=\"disabled:pointer-events-none disabled:opacity-50\" bindtap=\"table.firstPage()\" disabled=\"{{!table.getCanPreviousPage()}}\" aria-label=\"Go to first page\"><chevronfirsticon size=\"{{16}}\" aria-hidden=\"true\" /></button></paginationitem><paginationitem><button size=\"icon\" variant=\"outline\" class=\"disabled:pointer-events-none disabled:opacity-50\" bindtap=\"table.previousPage()\" disabled=\"{{!table.getCanPreviousPage()}}\" aria-label=\"Go to previous page\"><chevronlefticon size=\"{{16}}\" aria-hidden=\"true\" /></button></paginationitem><paginationitem><button size=\"icon\" variant=\"outline\" class=\"disabled:pointer-events-none disabled:opacity-50\" bindtap=\"table.nextPage()\" disabled=\"{{!table.getCanNextPage()}}\" aria-label=\"Go to next page\"><chevronrighticon size=\"{{16}}\" aria-hidden=\"true\" /></button></paginationitem><paginationitem><button size=\"icon\" variant=\"outline\" class=\"disabled:pointer-events-none disabled:opacity-50\" bindtap=\"table.lastPage()\" disabled=\"{{!table.getCanNextPage()}}\" aria-label=\"Go to last page\"><chevronlasticon size=\"{{16}}\" aria-hidden=\"true\" /></button></paginationitem></paginationcontent></pagination></view></view><text class=\"text-muted-foreground mt-4 text-center text-sm\">Example of a more complex table made with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://tanstack.com/table\" target=\"_blank\" rel=\"noopener noreferrer\">TanStack Table\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "table",
          "tanstack",
          "checkbox",
          "sort",
          "flag",
          "badge",
          "chip",
          "pagination",
          "filter",
          "select"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "table-20",
          "group": "table",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "table-20",
              "path": "registry/default/components/table/table-20.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "table-20",
              "path": "registry/default/components/table/table-20.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "table-20",
              "path": "registry/default/components/table/table-20.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "table-20",
              "path": "registry/default/components/table/table-20.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@tanstack/react-table",
              "@timui/core",
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tables",
        "title": "Table · Rows per page"
      },
      "categories": [
        "tables",
        "table"
      ]
    },
    {
      "name": "input-57",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "files": [
        {
          "path": "registry/default/components/input/input-57.tsx",
          "type": "registry:component",
          "target": "components/ui/input-57.tsx",
          "content": "import { useId } from 'react'\nimport { Input, Label } from '@timui/react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label className=\"flex-1\">Range</Label>\n      <div className=\"flex\">\n        <Input\n          id={`${id}-1`}\n          className=\"flex-1 rounded-e-none [-moz-appearance:_textfield] focus:z-10 [&::-webkit-inner-spin-button]:m-0 [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:m-0 [&::-webkit-outer-spin-button]:appearance-none\"\n          placeholder=\"From\"\n          type=\"number\"\n          aria-label=\"Min Value\"\n        />\n        <Input\n          id={`${id}-2`}\n          className=\"-ms-px flex-1 rounded-s-none [-moz-appearance:_textfield] focus:z-10 [&::-webkit-inner-spin-button]:m-0 [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:m-0 [&::-webkit-outer-spin-button]:appearance-none\"\n          placeholder=\"To\"\n          type=\"number\"\n          aria-label=\"Max Value\"\n        />\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/input/input-57.vue",
          "target": "components/ui/input-57.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\n\n\nconst id = 'input-57';\n\n</script>\n\n<template>\n  <div class=\"*:not-first:mt-2\"><Label class=\"flex-1\">Range</Label><div class=\"flex\"><Input :id=\"`${id}-1`\" class=\"flex-1 rounded-e-none [-moz-appearance:_textfield] focus:z-10 [&::-webkit-inner-spin-button]:m-0 [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:m-0 [&::-webkit-outer-spin-button]:appearance-none\" placeholder=\"From\" type=\"number\" aria-label=\"Min Value\" /><Input :id=\"`${id}-2`\" class=\"-ms-px flex-1 rounded-s-none [-moz-appearance:_textfield] focus:z-10 [&::-webkit-inner-spin-button]:m-0 [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:m-0 [&::-webkit-outer-spin-button]:appearance-none\" placeholder=\"To\" type=\"number\" aria-label=\"Max Value\" /></div></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/input/input-57.html",
          "target": "components/ui/input-57.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"*:not-first:mt-2\"><Label class=\"flex-1\">Range</Label><div class=\"flex\"><Input id=\"${`${id}-1`}\" class=\"flex-1 rounded-e-none [-moz-appearance:_textfield] focus:z-10 [&::-webkit-inner-spin-button]:m-0 [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:m-0 [&::-webkit-outer-spin-button]:appearance-none\" placeholder=\"From\" type=\"number\" aria-label=\"Min Value\" /><Input id=\"${`${id}-2`}\" class=\"-ms-px flex-1 rounded-s-none [-moz-appearance:_textfield] focus:z-10 [&::-webkit-inner-spin-button]:m-0 [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:m-0 [&::-webkit-outer-spin-button]:appearance-none\" placeholder=\"To\" type=\"number\" aria-label=\"Max Value\" /></div></div>\n</template>"
        },
        {
          "path": "registry/default/components/input/input-57.wxml",
          "target": "components/ui/input-57/input-57.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"*:not-first:mt-2\"><label class=\"flex-1\">Range</label><view class=\"flex\"><input id=\"{{`${id}-1`}}\" class=\"flex-1 rounded-e-none [-moz-appearance:_textfield] focus:z-10 [&::-webkit-inner-spin-button]:m-0 [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:m-0 [&::-webkit-outer-spin-button]:appearance-none\" placeholder=\"From\" type=\"number\" aria-label=\"Min Value\" /><input id=\"{{`${id}-2`}}\" class=\"-ms-px flex-1 rounded-s-none [-moz-appearance:_textfield] focus:z-10 [&::-webkit-inner-spin-button]:m-0 [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:m-0 [&::-webkit-outer-spin-button]:appearance-none\" placeholder=\"To\" type=\"number\" aria-label=\"Max Value\" /></view></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "input",
          "label",
          "range"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "input-57",
          "group": "input",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "input-57",
              "path": "registry/default/components/input/input-57.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "input-57",
              "path": "registry/default/components/input/input-57.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "input-57",
              "path": "registry/default/components/input/input-57.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "input-57",
              "path": "registry/default/components/input/input-57.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "inputs",
        "title": "Input · With label"
      },
      "categories": [
        "inputs",
        "input"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "calendar-date-picker-01",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/calendar-rac.json"
      ],
      "optionalPeerDependencies": [
        "@internationalized/date"
      ],
      "files": [
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-01.tsx",
          "type": "registry:component",
          "target": "components/ui/calendar-date-picker-01.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Calendar } from '@timui/react'\n\nexport default function Component() {\n  const [date, setDate] = useState<Date | undefined>(new Date())\n\n  return (\n    <div>\n      <Calendar\n        className=\"rounded-md border p-2\"\n        mode=\"single\"\n        selected={date}\n        onSelect={(next) => setDate(next instanceof Date ? next : undefined)}\n      />\n      <p\n        className=\"text-muted-foreground mt-4 text-center text-xs\"\n        role=\"region\"\n        aria-live=\"polite\"\n      >\n        Calendar -{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://react-spectrum.adobe.com/react-aria/DateRangePicker.html\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React Aria\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-01.vue",
          "target": "components/ui/calendar-date-picker-01.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { Calendar } from '@timui/vue'\n\nconst date = ref<Date | undefined>(new Date())\n\nfunction setDate(next: Date | Date[] | { from?: Date; to?: Date } | undefined) {\n  date.value = next instanceof Date || next === undefined ? next : date.value\n}\n</script>\n\n<template>\n  <div>\n    <Calendar\n      class=\"rounded-md border p-2\"\n      mode=\"single\"\n      :selected=\"date\"\n      @update:modelValue=\"setDate\"\n    />\n\n    <p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">\n      Calendar -\n      <a\n        class=\"hover:text-foreground underline\"\n        href=\"https://react-spectrum.adobe.com/react-aria/DateRangePicker.html\"\n        target=\"_blank\"\n        rel=\"noopener nofollow\"\n      >\n        React Aria\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-01.html",
          "target": "components/ui/calendar-date-picker-01.html",
          "type": "registry:component",
          "content": "<template>\n  <div><Calendar class=\"rounded-md border p-2\" mode=\"single\" selected=\"${date as any}\" onSelect=\"${setDate as any}\" /><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Calendar -${' '}<a class=\"hover:text-foreground underline\" href=\"https://react-spectrum.adobe.com/react-aria/DateRangePicker.html\" target=\"_blank\" rel=\"noopener nofollow\">React Aria\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-01.wxml",
          "target": "components/ui/calendar-date-picker-01/calendar-date-picker-01.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><calendar class=\"rounded-md border p-2\" mode=\"single\" selected=\"{{date as any}}\" bindchange=\"setDate as any\" /><text class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Calendar -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://react-spectrum.adobe.com/react-aria/DateRangePicker.html\" target=\"_blank\" rel=\"noopener nofollow\">React Aria\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "calendar",
          "date",
          "react aria"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "calendar-date-picker-01",
          "group": "calendar-date-picker",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-01",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-01.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-01",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-01.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-01",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-01.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-01",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-01.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "calendar",
        "title": "Calendar Date Picker · Interactive State"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "calendar"
      ]
    },
    {
      "name": "calendar-date-picker-02",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/calendar-rac.json"
      ],
      "optionalPeerDependencies": [
        "@internationalized/date"
      ],
      "files": [
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-02.tsx",
          "type": "registry:component",
          "target": "components/ui/calendar-date-picker-02.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { RangeCalendar, type CalendarRangeValue } from '@timui/react'\n\nexport default function Component() {\n  const now = new Date()\n  const [date, setDate] = useState<CalendarRangeValue>({\n    from: now,\n    to: new Date(now.getFullYear(), now.getMonth(), now.getDate() + 3),\n  })\n\n  return (\n    <div>\n      <RangeCalendar\n        className=\"rounded-md border p-2\"\n        selected={date}\n        onSelect={(next) => {\n          if (next && typeof next === 'object' && !Array.isArray(next) && !(next instanceof Date)) {\n            setDate(next as CalendarRangeValue)\n          }\n        }}\n      />\n      <p\n        className=\"text-muted-foreground mt-4 text-center text-xs\"\n        role=\"region\"\n        aria-live=\"polite\"\n      >\n        Range calendar -{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://react-spectrum.adobe.com/react-aria/DateRangePicker.html\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React Aria\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-02.vue",
          "target": "components/ui/calendar-date-picker-02.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { RangeCalendar } from '@timui/vue';\n\ntype CalendarRangeValue = { from?: Date; to?: Date } | undefined;\n\nconst now = new Date();\nconst date = ref<CalendarRangeValue>({\n  from: now,\n  to: new Date(now.getTime() + 3 * 24 * 60 * 60 * 1000),\n});\n\nfunction setDate(next: CalendarRangeValue) {\n  date.value = next;\n}\n</script>\n\n<template>\n  <div>\n    <RangeCalendar class=\"rounded-md border p-2\" :selected=\"date\" @update:modelValue=\"setDate\" />\n    <p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">\n      Range calendar -\n      <a class=\"hover:text-foreground underline\" href=\"https://react-spectrum.adobe.com/react-aria/DateRangePicker.html\" target=\"_blank\" rel=\"noopener nofollow\">React Aria</a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-02.html",
          "target": "components/ui/calendar-date-picker-02.html",
          "type": "registry:component",
          "content": "<template>\n  <div><RangeCalendar class=\"rounded-md border p-2\" value=\"${date}\" onchange=\"${setDate}\" /><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Range calendar -${' '}<a class=\"hover:text-foreground underline\" href=\"https://react-spectrum.adobe.com/react-aria/DateRangePicker.html\" target=\"_blank\" rel=\"noopener nofollow\">React Aria\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-02.wxml",
          "target": "components/ui/calendar-date-picker-02/calendar-date-picker-02.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><rangecalendar class=\"rounded-md border p-2\" value=\"{{date}}\" onchange=\"{{setDate}}\" /><text class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Range calendar -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://react-spectrum.adobe.com/react-aria/DateRangePicker.html\" target=\"_blank\" rel=\"noopener nofollow\">React Aria\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "calendar",
          "range calendar",
          "date",
          "react aria"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "calendar-date-picker-02",
          "group": "calendar-date-picker",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-02",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-02.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-02",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-02.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-02",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-02.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-02",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-02.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "calendar",
        "title": "Calendar Date Picker · Interactive State"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "calendar"
      ]
    },
    {
      "name": "calendar-date-picker-03",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/calendar-rac.json"
      ],
      "optionalPeerDependencies": [
        "@internationalized/date"
      ],
      "files": [
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-03.tsx",
          "type": "registry:component",
          "target": "components/ui/calendar-date-picker-03.tsx",
          "content": "'use client'\n\nimport { RangeCalendar } from '@timui/react'\n\nexport default function Component() {\n  const now = new Date()\n  const today = new Date(now.getFullYear(), now.getMonth(), now.getDate())\n  const disabledRanges = [\n    [new Date(today), new Date(today)],\n    [\n      new Date(today.getFullYear(), today.getMonth(), today.getDate() + 14),\n      new Date(today.getFullYear(), today.getMonth(), today.getDate() + 14),\n    ],\n    [\n      new Date(today.getFullYear(), today.getMonth(), today.getDate() + 23),\n      new Date(today.getFullYear(), today.getMonth(), today.getDate() + 23),\n    ],\n  ]\n\n  const isDateUnavailable = (date: Date) =>\n    date.getDay() === 0 ||\n    date.getDay() === 6 ||\n    disabledRanges.some(\n      (interval) =>\n        date.getTime() >= interval[0].getTime() && date.getTime() <= interval[1].getTime()\n    )\n\n  return (\n    <div>\n      <RangeCalendar\n        className=\"rounded-md border p-2\"\n        disabled={[{ before: today }, isDateUnavailable]}\n      />\n      <p\n        className=\"text-muted-foreground mt-4 text-center text-xs\"\n        role=\"region\"\n        aria-live=\"polite\"\n      >\n        Disabled dates -{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://react-spectrum.adobe.com/react-aria/DateRangePicker.html\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React Aria\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-03.vue",
          "target": "components/ui/calendar-date-picker-03.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { RangeCalendar } from '@timui/vue'\n\nconst startOfDay = (date: Date) => new Date(date.getFullYear(), date.getMonth(), date.getDate())\nconst addDays = (date: Date, days: number) => {\n  const next = new Date(date)\n  next.setDate(next.getDate() + days)\n  return startOfDay(next)\n}\n\nconst now = startOfDay(new Date())\nconst disabledRanges: Array<[Date, Date]> = [\n  [now, now],\n  [addDays(now, 14), addDays(now, 14)],\n  [addDays(now, 23), addDays(now, 23)],\n]\n\nfunction isDateUnavailable(date: Date) {\n  const target = startOfDay(date).getTime()\n  const day = date.getDay()\n  const isWeekend = day === 0 || day === 6\n  return (\n    isWeekend ||\n    disabledRanges.some(\n      ([start, end]) => target >= start.getTime() && target <= end.getTime()\n    )\n  )\n}\n</script>\n\n<template>\n  <div>\n    <RangeCalendar class=\"rounded-md border p-2\" :isDateUnavailable=\"isDateUnavailable\" :minDate=\"now\" />\n\n    <p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">\n      Disabled dates -\n      <a\n        class=\"hover:text-foreground underline\"\n        href=\"https://react-spectrum.adobe.com/react-aria/DateRangePicker.html\"\n        target=\"_blank\"\n        rel=\"noopener nofollow\"\n      >\n        React Aria\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-03.html",
          "target": "components/ui/calendar-date-picker-03.html",
          "type": "registry:component",
          "content": "<template>\n  <div><RangeCalendar class=\"rounded-md border p-2\" isdateunavailable=\"${isDateUnavailable}\" minvalue=\"${today(getLocalTimeZone())}\" /><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Disabled dates -${' '}<a class=\"hover:text-foreground underline\" href=\"https://react-spectrum.adobe.com/react-aria/DateRangePicker.html\" target=\"_blank\" rel=\"noopener nofollow\">React Aria\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-03.wxml",
          "target": "components/ui/calendar-date-picker-03/calendar-date-picker-03.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><rangecalendar class=\"rounded-md border p-2\" isdateunavailable=\"{{isDateUnavailable}}\" minvalue=\"{{today(getLocalTimeZone())}}\" /><text class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Disabled dates -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://react-spectrum.adobe.com/react-aria/DateRangePicker.html\" target=\"_blank\" rel=\"noopener nofollow\">React Aria\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "calendar",
          "range calendar",
          "date",
          "disabled",
          "react aria"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "calendar-date-picker-03",
          "group": "calendar-date-picker",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-03",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-03.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-03",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-03.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-03",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-03.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-03",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-03.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "calendar",
        "title": "Calendar Date Picker · Disabled State"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "calendar"
      ]
    },
    {
      "name": "calendar-date-picker-04",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/calendar.json"
      ],
      "files": [
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-04.tsx",
          "type": "registry:component",
          "target": "components/ui/calendar-date-picker-04.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Calendar } from '@timui/react'\n\nexport default function Component() {\n  const [date, setDate] = useState<Date | undefined>(new Date())\n\n  return (\n    <div>\n      <Calendar\n        mode=\"single\"\n        selected={date}\n        onSelect={setDate}\n        className=\"rounded-md border p-2\"\n      />\n      <p\n        className=\"text-muted-foreground mt-4 text-center text-xs\"\n        role=\"region\"\n        aria-live=\"polite\"\n      >\n        Calendar -{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://daypicker.dev/\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React DayPicker\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-04.vue",
          "target": "components/ui/calendar-date-picker-04.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Calendar } from '@timui/vue';\n\n\n\nconst date = ref<Date | undefined>(new Date());\n\n\nfunction setDate(next: typeof date.value | ((prev: typeof date.value) => typeof date.value)) {\n  date.value = typeof next === 'function'\n    ? (next as (prev: typeof date.value) => typeof date.value)(date.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <div><Calendar mode=\"single\" :selected=\"date\" @update:modelValue=\"setDate\" class=\"rounded-md border p-2\" /><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Calendar -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-04.html",
          "target": "components/ui/calendar-date-picker-04.html",
          "type": "registry:component",
          "content": "<template>\n  <div><Calendar mode=\"single\" selected=\"${date}\" onSelect=\"${setDate}\" class=\"rounded-md border p-2\" /><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Calendar -${' '}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-04.wxml",
          "target": "components/ui/calendar-date-picker-04/calendar-date-picker-04.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><calendar mode=\"single\" selected=\"{{date}}\" bindchange=\"setDate\" class=\"rounded-md border p-2\" /><text class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Calendar -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "calendar",
          "date",
          "react daypicker"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "calendar-date-picker-04",
          "group": "calendar-date-picker",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-04",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-04.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-04",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-04.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-04",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-04.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-04",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-04.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "calendar",
        "title": "Calendar Date Picker · Interactive State"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "calendar"
      ]
    },
    {
      "name": "calendar-date-picker-05",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/calendar.json"
      ],
      "files": [
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-05.tsx",
          "type": "registry:component",
          "target": "components/ui/calendar-date-picker-05.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Calendar } from '@timui/react'\nimport { addDays } from 'date-fns'\n\ntype CalendarRangeValue = { from: Date | undefined; to?: Date }\ntype CalendarSelectedValue = Date | Date[] | CalendarRangeValue | undefined\n\nexport default function Component() {\n  const today = new Date()\n  const [date, setDate] = useState<CalendarRangeValue | undefined>({\n    from: today,\n    to: addDays(today, 3),\n  })\n\n  return (\n    <div>\n      <Calendar\n        mode=\"range\"\n        selected={date}\n        onSelect={(next: CalendarSelectedValue) => setDate(next as CalendarRangeValue | undefined)}\n        className=\"rounded-md border p-2\"\n      />\n      <p\n        className=\"text-muted-foreground mt-4 text-center text-xs\"\n        role=\"region\"\n        aria-live=\"polite\"\n      >\n        Range calendar -{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://daypicker.dev/\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React DayPicker\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-05.vue",
          "target": "components/ui/calendar-date-picker-05.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Calendar } from '@timui/vue';\nimport { addDays } from 'date-fns';\n\n\nconst date = ref<CalendarRangeValue | undefined>({\n    from: today,\n    to: addDays(today, 3),\n  });\n\n\nfunction setDate(next: typeof date.value | ((prev: typeof date.value) => typeof date.value)) {\n  date.value = typeof next === 'function'\n    ? (next as (prev: typeof date.value) => typeof date.value)(date.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <div><Calendar mode=\"range\" :selected=\"date\" @update:modelValue=\"setDate(next as CalendarRangeValue | undefined)\" class=\"rounded-md border p-2\" /><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Range calendar -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-05.html",
          "target": "components/ui/calendar-date-picker-05.html",
          "type": "registry:component",
          "content": "<template>\n  <div><Calendar mode=\"range\" selected=\"${date}\" onSelect=\"${(next: CalendarSelectedValue) => setDate(next as CalendarRangeValue | undefined)}\" class=\"rounded-md border p-2\" /><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Range calendar -${' '}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-05.wxml",
          "target": "components/ui/calendar-date-picker-05/calendar-date-picker-05.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><calendar mode=\"range\" selected=\"{{date}}\" bindchange=\"setDate(next as CalendarRangeValue | undefined)\" class=\"rounded-md border p-2\" /><text class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Range calendar -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "calendar",
          "range calendar",
          "date",
          "react daypicker"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "calendar-date-picker-05",
          "group": "calendar-date-picker",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-05",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-05.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-05",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-05.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-05",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-05.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-05",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-05.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react",
              "date-fns"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue",
              "date-fns"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "calendar",
        "title": "Calendar Date Picker · Interactive State"
      },
      "dependencies": [
        "@timui/react",
        "date-fns"
      ],
      "categories": [
        "calendar"
      ]
    },
    {
      "name": "calendar-date-picker-06",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/calendar.json"
      ],
      "files": [
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-06.tsx",
          "type": "registry:component",
          "target": "components/ui/calendar-date-picker-06.tsx",
          "content": "import { Calendar } from '@timui/react'\nimport { addDays } from 'date-fns'\n\nexport default function Component() {\n  const today = new Date()\n\n  return (\n    <div>\n      <Calendar\n        mode=\"range\"\n        disabled={[\n          { before: new Date() }, // Dates before today\n          new Date(), // Today\n          { dayOfWeek: [0, 6] }, // Weekends\n          {\n            from: addDays(today, 14), // 14th day from now\n            to: addDays(today, 16), // 16th day from now\n          },\n          {\n            from: addDays(today, 23), // 23th day from now\n            to: addDays(today, 24), // 24th day from now\n          },\n        ]}\n        excludeDisabled\n        className=\"rounded-md border p-2\"\n      />\n      <p\n        className=\"text-muted-foreground mt-4 text-center text-xs\"\n        role=\"region\"\n        aria-live=\"polite\"\n      >\n        Disabled dates -{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://daypicker.dev/\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React DayPicker\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-06.vue",
          "target": "components/ui/calendar-date-picker-06.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Calendar } from '@timui/vue';\nimport { addDays } from 'date-fns';\n\n\n\n</script>\n\n<template>\n  <div><Calendar mode=\"range\" :disabled=\"[\n          { before: new Date() }, // Dates before today\n          new Date(), // Today\n          { dayOfWeek: [0, 6] }, // Weekends\n          {\n            from: addDays(today, 14), // 14th day from now\n            to: addDays(today, 16), // 16th day from now\n          },\n          {\n            from: addDays(today, 23), // 23th day from now\n            to: addDays(today, 24), // 24th day from now\n          },\n        ]\" excludeDisabled class=\"rounded-md border p-2\" /><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Disabled dates -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-06.html",
          "target": "components/ui/calendar-date-picker-06.html",
          "type": "registry:component",
          "content": "<template>\n  <div><Calendar mode=\"range\" disabled=\"${[\n          { before: new Date() }, // Dates before today\n          new Date(), // Today\n          { dayOfWeek: [0, 6] }, // Weekends\n          {\n            from: addDays(today, 14), // 14th day from now\n            to: addDays(today, 16), // 16th day from now\n          },\n          {\n            from: addDays(today, 23), // 23th day from now\n            to: addDays(today, 24), // 24th day from now\n          },\n        ]}\" excludedisabled class=\"rounded-md border p-2\" /><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Disabled dates -${' '}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-06.wxml",
          "target": "components/ui/calendar-date-picker-06/calendar-date-picker-06.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><calendar mode=\"range\" disabled=\"{{[\n          { before: new Date() }, // Dates before today\n          new Date(), // Today\n          { dayOfWeek: [0, 6] }, // Weekends\n          {\n            from: addDays(today, 14), // 14th day from now\n            to: addDays(today, 16), // 16th day from now\n          },\n          {\n            from: addDays(today, 23), // 23th day from now\n            to: addDays(today, 24), // 24th day from now\n          },\n        ]}}\" excludedisabled class=\"rounded-md border p-2\" /><text class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Disabled dates -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "calendar",
          "range calendar",
          "date",
          "disabled",
          "react daypicker"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "calendar-date-picker-06",
          "group": "calendar-date-picker",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-06",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-06.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-06",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-06.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-06",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-06.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-06",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-06.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react",
              "date-fns"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue",
              "date-fns"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "calendar",
        "title": "Calendar Date Picker · Disabled State"
      },
      "dependencies": [
        "@timui/react",
        "date-fns"
      ],
      "categories": [
        "calendar"
      ]
    },
    {
      "name": "calendar-date-picker-07",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/calendar.json"
      ],
      "files": [
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-07.tsx",
          "type": "registry:component",
          "target": "components/ui/calendar-date-picker-07.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Calendar } from '@timui/react'\nimport { addDays, subDays } from 'date-fns'\n\nexport default function Component() {\n  const today = new Date()\n  const [date, setDate] = useState<Date[] | undefined>([\n    subDays(today, 17),\n    addDays(today, 2),\n    addDays(today, 6),\n    addDays(today, 8),\n  ])\n\n  return (\n    <div>\n      <Calendar\n        mode=\"multiple\"\n        selected={date}\n        onSelect={setDate}\n        className=\"rounded-md border p-2\"\n      />\n      <p\n        className=\"text-muted-foreground mt-4 text-center text-xs\"\n        role=\"region\"\n        aria-live=\"polite\"\n      >\n        Multiple day selection -{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://daypicker.dev/\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React DayPicker\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-07.vue",
          "target": "components/ui/calendar-date-picker-07.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Calendar } from '@timui/vue';\nimport { addDays, subDays } from 'date-fns';\n\n\nconst date = ref<Date[] | undefined>([\n    subDays(today, 17),\n    addDays(today, 2),\n    addDays(today, 6),\n    addDays(today, 8),\n  ]);\n\n\nfunction setDate(next: typeof date.value | ((prev: typeof date.value) => typeof date.value)) {\n  date.value = typeof next === 'function'\n    ? (next as (prev: typeof date.value) => typeof date.value)(date.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <div><Calendar mode=\"multiple\" :selected=\"date\" @update:modelValue=\"setDate\" class=\"rounded-md border p-2\" /><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Multiple day selection -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-07.html",
          "target": "components/ui/calendar-date-picker-07.html",
          "type": "registry:component",
          "content": "<template>\n  <div><Calendar mode=\"multiple\" selected=\"${date}\" onSelect=\"${setDate}\" class=\"rounded-md border p-2\" /><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Multiple day selection -${' '}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-07.wxml",
          "target": "components/ui/calendar-date-picker-07/calendar-date-picker-07.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><calendar mode=\"multiple\" selected=\"{{date}}\" bindchange=\"setDate\" class=\"rounded-md border p-2\" /><text class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Multiple day selection -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "calendar",
          "date",
          "react daypicker"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "calendar-date-picker-07",
          "group": "calendar-date-picker",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-07",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-07.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-07",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-07.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-07",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-07.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-07",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-07.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react",
              "date-fns"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue",
              "date-fns"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "calendar",
        "title": "Calendar Date Picker · Interactive State"
      },
      "dependencies": [
        "@timui/react",
        "date-fns"
      ],
      "categories": [
        "calendar"
      ]
    },
    {
      "name": "calendar-date-picker-08",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/calendar.json"
      ],
      "files": [
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-08.tsx",
          "type": "registry:component",
          "target": "components/ui/calendar-date-picker-08.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Calendar } from '@timui/react'\n\nexport default function Component() {\n  const [date, setDate] = useState<Date | undefined>(new Date())\n\n  return (\n    <div>\n      <Calendar\n        mode=\"single\"\n        selected={date}\n        onSelect={setDate}\n        className=\"rounded-md border p-2\"\n        classNames={{\n          day_button: 'rounded-full',\n        }}\n      />\n      <p\n        className=\"text-muted-foreground mt-4 text-center text-xs\"\n        role=\"region\"\n        aria-live=\"polite\"\n      >\n        Custom select day style -{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://daypicker.dev/\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React DayPicker\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-08.vue",
          "target": "components/ui/calendar-date-picker-08.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Calendar } from '@timui/vue';\n\n\n\nconst date = ref<Date | undefined>(new Date());\n\n\nfunction setDate(next: typeof date.value | ((prev: typeof date.value) => typeof date.value)) {\n  date.value = typeof next === 'function'\n    ? (next as (prev: typeof date.value) => typeof date.value)(date.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <div><Calendar mode=\"single\" :selected=\"date\" @update:modelValue=\"setDate\" class=\"rounded-md border p-2\" :classNames=\"{\n          day_button: 'rounded-full',\n        }\" /><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Custom select day style -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-08.html",
          "target": "components/ui/calendar-date-picker-08.html",
          "type": "registry:component",
          "content": "<template>\n  <div><Calendar mode=\"single\" selected=\"${date}\" onSelect=\"${setDate}\" class=\"rounded-md border p-2\" classnames=\"${{\n          day_button: 'rounded-full',\n        }}\" /><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Custom select day style -${' '}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-08.wxml",
          "target": "components/ui/calendar-date-picker-08/calendar-date-picker-08.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><calendar mode=\"single\" selected=\"{{date}}\" bindchange=\"setDate\" class=\"rounded-md border p-2\" classnames=\"{{{\n          day_button: 'rounded-full',\n        }}}\" /><text class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Custom select day style -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "calendar",
          "date",
          "react daypicker"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "calendar-date-picker-08",
          "group": "calendar-date-picker",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-08",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-08.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-08",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-08.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-08",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-08.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-08",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-08.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "calendar",
        "title": "Calendar Date Picker · Interactive State"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "calendar"
      ]
    },
    {
      "name": "calendar-date-picker-09",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/calendar.json"
      ],
      "files": [
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-09.tsx",
          "type": "registry:component",
          "target": "components/ui/calendar-date-picker-09.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Calendar } from '@timui/react'\nimport { addDays } from 'date-fns'\n\ntype CalendarRangeValue = { from: Date | undefined; to?: Date }\ntype CalendarSelectedValue = Date | Date[] | CalendarRangeValue | undefined\n\nexport default function Component() {\n  const today = new Date()\n  const [date, setDate] = useState<CalendarRangeValue | undefined>({\n    from: today,\n    to: addDays(today, 3),\n  })\n\n  return (\n    <div>\n      <Calendar\n        mode=\"range\"\n        selected={date}\n        onSelect={(next: CalendarSelectedValue) => setDate(next as CalendarRangeValue | undefined)}\n        className=\"rounded-md border p-2\"\n        classNames={{\n          day: 'relative before:absolute before:inset-y-px before:inset-x-0 [&.range-start:not(.range-end):before]:bg-linear-to-r before:from-transparent before:from-50% before:to-accent before:to-50% [&.range-end:not(.range-start):before]:bg-linear-to-l',\n          day_button:\n            'rounded-full group-[.range-start:not(.range-end)]:rounded-e-full group-[.range-end:not(.range-start)]:rounded-s-full',\n        }}\n      />\n      <p\n        className=\"text-muted-foreground mt-4 text-center text-xs\"\n        role=\"region\"\n        aria-live=\"polite\"\n      >\n        Custom select range style -{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://daypicker.dev/\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React DayPicker\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-09.vue",
          "target": "components/ui/calendar-date-picker-09.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Calendar } from '@timui/vue';\nimport { addDays } from 'date-fns';\n\n\nconst date = ref<CalendarRangeValue | undefined>({\n    from: today,\n    to: addDays(today, 3),\n  });\n\n\nfunction setDate(next: typeof date.value | ((prev: typeof date.value) => typeof date.value)) {\n  date.value = typeof next === 'function'\n    ? (next as (prev: typeof date.value) => typeof date.value)(date.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <div><Calendar mode=\"range\" :selected=\"date\" @update:modelValue=\"setDate(next as CalendarRangeValue | undefined)\" class=\"rounded-md border p-2\" :classNames=\"{\n          day: 'relative before:absolute before:inset-y-px before:inset-x-0 [&.range-start:not(.range-end):before]:bg-linear-to-r before:from-transparent before:from-50% before:to-accent before:to-50% [&.range-end:not(.range-start):before]:bg-linear-to-l',\n          day_button:\n            'rounded-full group-[.range-start:not(.range-end)]:rounded-e-full group-[.range-end:not(.range-start)]:rounded-s-full',\n        }\" /><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Custom select range style -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-09.html",
          "target": "components/ui/calendar-date-picker-09.html",
          "type": "registry:component",
          "content": "<template>\n  <div><Calendar mode=\"range\" selected=\"${date}\" onSelect=\"${(next: CalendarSelectedValue) => setDate(next as CalendarRangeValue | undefined)}\" class=\"rounded-md border p-2\" classnames=\"${{\n          day: 'relative before:absolute before:inset-y-px before:inset-x-0 [&.range-start:not(.range-end):before]:bg-linear-to-r before:from-transparent before:from-50% before:to-accent before:to-50% [&.range-end:not(.range-start):before]:bg-linear-to-l',\n          day_button:\n            'rounded-full group-[.range-start:not(.range-end)]:rounded-e-full group-[.range-end:not(.range-start)]:rounded-s-full',\n        }}\" /><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Custom select range style -${' '}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-09.wxml",
          "target": "components/ui/calendar-date-picker-09/calendar-date-picker-09.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><calendar mode=\"range\" selected=\"{{date}}\" bindchange=\"setDate(next as CalendarRangeValue | undefined)\" class=\"rounded-md border p-2\" classnames=\"{{{\n          day: 'relative before:absolute before:inset-y-px before:inset-x-0 [&.range-start:not(.range-end):before]:bg-linear-to-r before:from-transparent before:from-50% before:to-accent before:to-50% [&.range-end:not(.range-start):before]:bg-linear-to-l',\n          day_button:\n            'rounded-full group-[.range-start:not(.range-end)]:rounded-e-full group-[.range-end:not(.range-start)]:rounded-s-full',\n        }}}\" /><text class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Custom select range style -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "calendar",
          "range calendar",
          "date",
          "react daypicker"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "calendar-date-picker-09",
          "group": "calendar-date-picker",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-09",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-09.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-09",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-09.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-09",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-09.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-09",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-09.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react",
              "date-fns"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue",
              "date-fns"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "calendar",
        "title": "Calendar Date Picker · Interactive State"
      },
      "dependencies": [
        "@timui/react",
        "date-fns"
      ],
      "categories": [
        "calendar"
      ]
    },
    {
      "name": "calendar-date-picker-10",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/calendar.json"
      ],
      "files": [
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-10.tsx",
          "type": "registry:component",
          "target": "components/ui/calendar-date-picker-10.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Calendar } from '@timui/react'\n\nexport default function Component() {\n  const [date, setDate] = useState<Date | undefined>(new Date())\n\n  return (\n    <div>\n      <Calendar\n        mode=\"single\"\n        selected={date}\n        onSelect={setDate}\n        className=\"rounded-md border p-2\"\n        classNames={{\n          month_caption: 'ms-2.5 me-20 justify-start',\n          nav: 'justify-end',\n        }}\n      />\n      <p\n        className=\"text-muted-foreground mt-4 text-center text-xs\"\n        role=\"region\"\n        aria-live=\"polite\"\n      >\n        Right navigation -{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://daypicker.dev/\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React DayPicker\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-10.vue",
          "target": "components/ui/calendar-date-picker-10.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Calendar } from '@timui/vue';\n\n\n\nconst date = ref<Date | undefined>(new Date());\n\n\nfunction setDate(next: typeof date.value | ((prev: typeof date.value) => typeof date.value)) {\n  date.value = typeof next === 'function'\n    ? (next as (prev: typeof date.value) => typeof date.value)(date.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <div><Calendar mode=\"single\" :selected=\"date\" @update:modelValue=\"setDate\" class=\"rounded-md border p-2\" :classNames=\"{\n          month_caption: 'ms-2.5 me-20 justify-start',\n          nav: 'justify-end',\n        }\" /><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Right navigation -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-10.html",
          "target": "components/ui/calendar-date-picker-10.html",
          "type": "registry:component",
          "content": "<template>\n  <div><Calendar mode=\"single\" selected=\"${date}\" onSelect=\"${setDate}\" class=\"rounded-md border p-2\" classnames=\"${{\n          month_caption: 'ms-2.5 me-20 justify-start',\n          nav: 'justify-end',\n        }}\" /><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Right navigation -${' '}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-10.wxml",
          "target": "components/ui/calendar-date-picker-10/calendar-date-picker-10.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><calendar mode=\"single\" selected=\"{{date}}\" bindchange=\"setDate\" class=\"rounded-md border p-2\" classnames=\"{{{\n          month_caption: 'ms-2.5 me-20 justify-start',\n          nav: 'justify-end',\n        }}}\" /><text class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Right navigation -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "calendar",
          "date",
          "react daypicker"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "calendar-date-picker-10",
          "group": "calendar-date-picker",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-10",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-10.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-10",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-10.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-10",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-10.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-10",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-10.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "calendar",
        "title": "Calendar Date Picker · Interactive State"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "calendar"
      ]
    },
    {
      "name": "calendar-date-picker-11",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/calendar.json",
        "https://ui.timkit.cn/r/select.json"
      ],
      "files": [
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-11.tsx",
          "type": "registry:component",
          "target": "components/ui/calendar-date-picker-11.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport {\n  Calendar,\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from '@timui/react'\n\ntype DropdownOption = { value: string | number; label: string; disabled?: boolean }\ntype DropdownNavProps = { children?: React.ReactNode }\ntype DropdownProps = {\n  value?: string | number\n  options?: DropdownOption[]\n  onChange?: React.ChangeEventHandler<HTMLSelectElement>\n}\n\nexport default function Component() {\n  const [date, setDate] = useState<Date | undefined>(new Date())\n\n  const handleCalendarChange = (\n    _value: string | number,\n    _e: React.ChangeEventHandler<HTMLSelectElement>\n  ) => {\n    const _event = {\n      target: {\n        value: String(_value),\n      },\n    } as React.ChangeEvent<HTMLSelectElement>\n    _e(_event)\n  }\n\n  return (\n    <div>\n      <Calendar\n        mode=\"single\"\n        selected={date}\n        onSelect={setDate}\n        className=\"rounded-md border p-2\"\n        classNames={{\n          month_caption: 'mx-0',\n        }}\n        captionLayout=\"dropdown\"\n        defaultMonth={new Date()}\n        startMonth={new Date(1980, 6)}\n        hideNavigation\n        components={{\n          DropdownNav: (props: DropdownNavProps) => {\n            return <div className=\"flex w-full items-center gap-2\">{props.children}</div>\n          },\n          Dropdown: (props: DropdownProps) => {\n            return (\n              <Select\n                value={String(props.value)}\n                onValueChange={(value: string) => {\n                  if (props.onChange) {\n                    handleCalendarChange(value, props.onChange)\n                  }\n                }}\n              >\n                <SelectTrigger className=\"h-8 w-fit font-medium first:grow\">\n                  <SelectValue />\n                </SelectTrigger>\n                <SelectContent className=\"max-h-[min(26rem,var(--radix-select-content-available-height))]\">\n                  {props.options?.map((option) => (\n                    <SelectItem\n                      key={option.value}\n                      value={String(option.value)}\n                      disabled={option.disabled}\n                    >\n                      {option.label}\n                    </SelectItem>\n                  ))}\n                </SelectContent>\n              </Select>\n            )\n          },\n        }}\n      />\n      <p\n        className=\"text-muted-foreground mt-4 text-center text-xs\"\n        role=\"region\"\n        aria-live=\"polite\"\n      >\n        Monthly / yearly selects -{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://daypicker.dev/\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React DayPicker\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-11.vue",
          "target": "components/ui/calendar-date-picker-11.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { Calendar } from '@timui/vue'\n\nconst date = ref<Date | undefined>(new Date())\n\nfunction setDate(next: Date | undefined) {\n  date.value = next\n}\n</script>\n\n<template>\n  <div>\n    <Calendar\n      mode=\"single\"\n      :selected=\"date\"\n      @update:modelValue=\"setDate\"\n      class=\"rounded-md border p-2\"\n      :classNames=\"{ month_caption: 'mx-0' }\"\n      captionLayout=\"dropdown\"\n      :defaultMonth=\"new Date()\"\n      :startMonth=\"new Date(1980, 6)\"\n      hideNavigation\n    />\n    <p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">\n      Monthly / yearly selects -\n      <a\n        class=\"hover:text-foreground underline\"\n        href=\"https://daypicker.dev/\"\n        target=\"_blank\"\n        rel=\"noopener nofollow\"\n      >\n        React DayPicker\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-11.html",
          "target": "components/ui/calendar-date-picker-11.html",
          "type": "registry:component",
          "content": "<template>\n  <div><Calendar mode=\"single\" selected=\"${date}\" onSelect=\"${setDate}\" class=\"rounded-md border p-2\" classnames=\"${{\n          month_caption: 'mx-0',\n        }}\" captionlayout=\"dropdown\" defaultmonth=\"${new Date()}\" startmonth=\"${new Date(1980, 6)}\" hidenavigation components=\"${{\n          DropdownNav: (props: DropdownNavProps) => {\n            return <div className=\"flex w-full items-center gap-2\">{props.children}</div>\n          },\n          Dropdown: (props: DropdownProps) => {\n            return (\n              <Select\n                value={String(props.value)}\n                onValueChange={(value: string) => {\n                  if (props.onChange) {\n                    handleCalendarChange(value, props.onChange)\n                  }\n                }}\n              >\n                <SelectTrigger className=\"h-8 w-fit font-medium first:grow\">\n                  <SelectValue />\n                </SelectTrigger>\n                <SelectContent className=\"max-h-[min(26rem,var(--radix-select-content-available-height))]\">\n                  {props.options?.map((option) => (\n                    <SelectItem\n                      key={option.value}\n                      value={String(option.value)}\n                      disabled={option.disabled}\n                    >\n                      {option.label}\n                    </SelectItem>\n                  ))}\n                </SelectContent>\n              </Select>\n            )\n          },\n        }}\" /><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Monthly / yearly selects -${' '}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-11.wxml",
          "target": "components/ui/calendar-date-picker-11/calendar-date-picker-11.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><calendar mode=\"single\" selected=\"{{date}}\" bindchange=\"setDate\" class=\"rounded-md border p-2\" classnames=\"{{{\n          month_caption: 'mx-0',\n        }}}\" captionlayout=\"dropdown\" defaultmonth=\"{{new Date()}}\" startmonth=\"{{new Date(1980, 6)}}\" hidenavigation components=\"{{{\n          DropdownNav: (props: DropdownNavProps) => {\n            return <div className=\"flex w-full items-center gap-2\">{props.children}</div>\n          },\n          Dropdown: (props: DropdownProps) => {\n            return (\n              <Select\n                value={String(props.value)}\n                onValueChange={(value: string) => {\n                  if (props.onChange) {\n                    handleCalendarChange(value, props.onChange)\n                  }\n                }}\n              >\n                <SelectTrigger className=\"h-8 w-fit font-medium first:grow\">\n                  <SelectValue />\n                </SelectTrigger>\n                <SelectContent className=\"max-h-[min(26rem,var(--radix-select-content-available-height))]\">\n                  {props.options?.map((option) => (\n                    <SelectItem\n                      key={option.value}\n                      value={String(option.value)}\n                      disabled={option.disabled}\n                    >\n                      {option.label}\n                    </SelectItem>\n                  ))}\n                </SelectContent>\n              </Select>\n            )\n          },\n        }}}\" /><text class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Monthly / yearly selects -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "calendar",
          "date",
          "react daypicker"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "calendar-date-picker-11",
          "group": "calendar-date-picker",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-11",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-11.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-11",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-11.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-11",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-11.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-11",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-11.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "calendar",
        "title": "Calendar Date Picker · Disabled State"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "calendar"
      ]
    },
    {
      "name": "calendar-date-picker-12",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/calendar.json",
        "https://ui.timkit.cn/r/select.json"
      ],
      "files": [
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-12.tsx",
          "type": "registry:component",
          "target": "components/ui/calendar-date-picker-12.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport {\n  Calendar,\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from '@timui/react'\n\ntype DropdownOption = { value: string | number; label: string; disabled?: boolean }\ntype DropdownNavProps = { children?: React.ReactNode }\ntype DropdownProps = {\n  value?: string | number\n  options?: DropdownOption[]\n  onChange?: React.ChangeEventHandler<HTMLSelectElement>\n}\n\nexport default function Component() {\n  const [date, setDate] = useState<Date | undefined>(new Date())\n\n  const handleCalendarChange = (\n    _value: string | number,\n    _e: React.ChangeEventHandler<HTMLSelectElement>\n  ) => {\n    const _event = {\n      target: {\n        value: String(_value),\n      },\n    } as React.ChangeEvent<HTMLSelectElement>\n    _e(_event)\n  }\n\n  return (\n    <div>\n      <Calendar\n        mode=\"single\"\n        selected={date}\n        onSelect={setDate}\n        className=\"rounded-md border p-2\"\n        captionLayout=\"dropdown-years\"\n        defaultMonth={new Date()}\n        startMonth={new Date(1980, 6)}\n        components={{\n          DropdownNav: (props: DropdownNavProps) => {\n            return (\n              <div className=\"flex w-full items-center justify-center gap-3 [&>span]:text-sm [&>span]:font-medium\">\n                {props.children}\n              </div>\n            )\n          },\n          YearsDropdown: (props: DropdownProps) => {\n            return (\n              <Select\n                value={String(props.value)}\n                onValueChange={(value: string) => {\n                  if (props.onChange) {\n                    handleCalendarChange(value, props.onChange)\n                  }\n                }}\n              >\n                <SelectTrigger className=\"h-8 w-fit font-medium\">\n                  <SelectValue />\n                </SelectTrigger>\n                <SelectContent className=\"max-h-[min(26rem,var(--radix-select-content-available-height))]\">\n                  {props.options?.map((option) => (\n                    <SelectItem\n                      key={option.value}\n                      value={String(option.value)}\n                      disabled={option.disabled}\n                    >\n                      {option.label}\n                    </SelectItem>\n                  ))}\n                </SelectContent>\n              </Select>\n            )\n          },\n        }}\n      />\n      <p\n        className=\"text-muted-foreground mt-4 text-center text-xs\"\n        role=\"region\"\n        aria-live=\"polite\"\n      >\n        Yearly select + nav -{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://daypicker.dev/\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React DayPicker\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-12.vue",
          "target": "components/ui/calendar-date-picker-12.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { Calendar } from '@timui/vue'\n\nconst date = ref<Date | undefined>(new Date())\n\nfunction setDate(next: Date | undefined) {\n  date.value = next\n}\n</script>\n\n<template>\n  <div>\n    <Calendar\n      mode=\"single\"\n      :selected=\"date\"\n      @update:modelValue=\"setDate\"\n      class=\"rounded-md border p-2\"\n      captionLayout=\"dropdown-years\"\n      :defaultMonth=\"new Date()\"\n      :startMonth=\"new Date(1980, 6)\"\n      :classNames=\"{ nav: 'justify-center' }\"\n    />\n    <p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">\n      Yearly select + nav -\n      <a\n        class=\"hover:text-foreground underline\"\n        href=\"https://daypicker.dev/\"\n        target=\"_blank\"\n        rel=\"noopener nofollow\"\n      >\n        React DayPicker\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-12.html",
          "target": "components/ui/calendar-date-picker-12.html",
          "type": "registry:component",
          "content": "<template>\n  <div><Calendar mode=\"single\" selected=\"${date}\" onSelect=\"${setDate}\" class=\"rounded-md border p-2\" captionlayout=\"dropdown-years\" defaultmonth=\"${new Date()}\" startmonth=\"${new Date(1980, 6)}\" components=\"${{\n          DropdownNav: (props: DropdownNavProps) => {\n            return (\n              <div className=\"flex w-full items-center justify-center gap-3 [&>span]:text-sm [&>span]:font-medium\">\n                {props.children}\n              </div>\n            )\n          },\n          YearsDropdown: (props: DropdownProps) => {\n            return (\n              <Select\n                value={String(props.value)}\n                onValueChange={(value: string) => {\n                  if (props.onChange) {\n                    handleCalendarChange(value, props.onChange)\n                  }\n                }}\n              >\n                <SelectTrigger className=\"h-8 w-fit font-medium\">\n                  <SelectValue />\n                </SelectTrigger>\n                <SelectContent className=\"max-h-[min(26rem,var(--radix-select-content-available-height))]\">\n                  {props.options?.map((option) => (\n                    <SelectItem\n                      key={option.value}\n                      value={String(option.value)}\n                      disabled={option.disabled}\n                    >\n                      {option.label}\n                    </SelectItem>\n                  ))}\n                </SelectContent>\n              </Select>\n            )\n          },\n        }}\" /><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Yearly select + nav -${' '}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-12.wxml",
          "target": "components/ui/calendar-date-picker-12/calendar-date-picker-12.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><calendar mode=\"single\" selected=\"{{date}}\" bindchange=\"setDate\" class=\"rounded-md border p-2\" captionlayout=\"dropdown-years\" defaultmonth=\"{{new Date()}}\" startmonth=\"{{new Date(1980, 6)}}\" components=\"{{{\n          DropdownNav: (props: DropdownNavProps) => {\n            return (\n              <div className=\"flex w-full items-center justify-center gap-3 [&>span]:text-sm [&>span]:font-medium\">\n                {props.children}\n              </div>\n            )\n          },\n          YearsDropdown: (props: DropdownProps) => {\n            return (\n              <Select\n                value={String(props.value)}\n                onValueChange={(value: string) => {\n                  if (props.onChange) {\n                    handleCalendarChange(value, props.onChange)\n                  }\n                }}\n              >\n                <SelectTrigger className=\"h-8 w-fit font-medium\">\n                  <SelectValue />\n                </SelectTrigger>\n                <SelectContent className=\"max-h-[min(26rem,var(--radix-select-content-available-height))]\">\n                  {props.options?.map((option) => (\n                    <SelectItem\n                      key={option.value}\n                      value={String(option.value)}\n                      disabled={option.disabled}\n                    >\n                      {option.label}\n                    </SelectItem>\n                  ))}\n                </SelectContent>\n              </Select>\n            )\n          },\n        }}}\" /><text class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Yearly select + nav -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "calendar",
          "date",
          "react daypicker"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "calendar-date-picker-12",
          "group": "calendar-date-picker",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-12",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-12.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-12",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-12.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-12",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-12.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-12",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-12.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "calendar",
        "title": "Calendar Date Picker · Disabled State"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "calendar"
      ]
    },
    {
      "name": "calendar-date-picker-13",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/calendar.json"
      ],
      "files": [
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-13.tsx",
          "type": "registry:component",
          "target": "components/ui/calendar-date-picker-13.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Calendar } from '@timui/react'\n\ntype CalendarWeekNumberProps = React.ThHTMLAttributes<HTMLTableCellElement> & {\n  week: { weekNumber: number }\n}\n\nexport default function Component() {\n  const [date, setDate] = useState<Date | undefined>(new Date())\n\n  return (\n    <div>\n      <Calendar\n        mode=\"single\"\n        selected={date}\n        onSelect={setDate}\n        className=\"rounded-md border p-2\"\n        fixedWeeks\n        showWeekNumber\n        components={{\n          WeekNumber: ({ week, ...props }: CalendarWeekNumberProps) => {\n            return (\n              <th {...props}>\n                <span className=\"inline-flex size-9 items-center justify-center\">\n                  {week.weekNumber}\n                </span>\n              </th>\n            )\n          },\n        }}\n      />\n      <p\n        className=\"text-muted-foreground mt-4 text-center text-xs\"\n        role=\"region\"\n        aria-live=\"polite\"\n      >\n        Weekly numbers -{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://daypicker.dev/\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React DayPicker\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-13.vue",
          "target": "components/ui/calendar-date-picker-13.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Calendar } from '@timui/vue';\n\n\n\nconst date = ref<Date | undefined>(new Date());\n\n\nfunction setDate(next: typeof date.value | ((prev: typeof date.value) => typeof date.value)) {\n  date.value = typeof next === 'function'\n    ? (next as (prev: typeof date.value) => typeof date.value)(date.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <div><Calendar mode=\"single\" :selected=\"date\" @update:modelValue=\"setDate\" class=\"rounded-md border p-2\" fixedWeeks showWeekNumber /><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Weekly numbers -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-13.html",
          "target": "components/ui/calendar-date-picker-13.html",
          "type": "registry:component",
          "content": "<template>\n  <div><Calendar mode=\"single\" selected=\"${date}\" onSelect=\"${setDate}\" class=\"rounded-md border p-2\" fixedweeks showweeknumber components=\"${{\n          WeekNumber: ({ week, ...props }: CalendarWeekNumberProps) => {\n            return (\n              <th {...props}>\n                <span className=\"inline-flex size-9 items-center justify-center\">\n                  {week.weekNumber}\n                </span>\n              </th>\n            )\n          },\n        }}\" /><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Weekly numbers -${' '}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-13.wxml",
          "target": "components/ui/calendar-date-picker-13/calendar-date-picker-13.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><calendar mode=\"single\" selected=\"{{date}}\" bindchange=\"setDate\" class=\"rounded-md border p-2\" fixedweeks showweeknumber components=\"{{{\n          WeekNumber: ({ week, ...props }: CalendarWeekNumberProps) => {\n            return (\n              <th {...props}>\n                <span className=\"inline-flex size-9 items-center justify-center\">\n                  {week.weekNumber}\n                </span>\n              </th>\n            )\n          },\n        }}}\" /><text class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Weekly numbers -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "calendar",
          "date",
          "week",
          "react daypicker"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "calendar-date-picker-13",
          "group": "calendar-date-picker",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-13",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-13.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-13",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-13.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-13",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-13.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-13",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-13.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "calendar",
        "title": "Calendar Date Picker · Interactive State"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "calendar"
      ]
    },
    {
      "name": "calendar-date-picker-14",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/calendar.json"
      ],
      "files": [
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-14.tsx",
          "type": "registry:component",
          "target": "components/ui/calendar-date-picker-14.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Button, Calendar } from '@timui/react'\nimport { addDays } from 'date-fns'\n\nexport default function Component() {\n  const today = new Date()\n  const selectedDay = addDays(today, -28)\n  const [month, setMonth] = useState(selectedDay)\n  const [date, setDate] = useState<Date | undefined>(selectedDay)\n\n  return (\n    <div>\n      <div className=\"rounded-md border p-2\">\n        <Calendar\n          mode=\"single\"\n          selected={date}\n          onSelect={setDate}\n          month={month}\n          onMonthChange={setMonth}\n        />\n        <Button variant=\"outline\" size=\"sm\" className=\"mt-2 mb-1\" onClick={() => setMonth(today)}>\n          Current month\n        </Button>\n      </div>\n      <p\n        className=\"text-muted-foreground mt-4 text-center text-xs\"\n        role=\"region\"\n        aria-live=\"polite\"\n      >\n        With button -{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://daypicker.dev/\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React DayPicker\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-14.vue",
          "target": "components/ui/calendar-date-picker-14.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Button } from '@timui/vue';\nimport { Calendar } from '@timui/vue';\nimport { addDays } from 'date-fns';\n\n\nconst month = ref(selectedDay);\nconst date = ref<Date | undefined>(selectedDay);\n\n\nfunction setMonth(next: typeof month.value | ((prev: typeof month.value) => typeof month.value)) {\n  month.value = typeof next === 'function'\n    ? (next as (prev: typeof month.value) => typeof month.value)(month.value)\n    : next;\n}\n\n\nfunction setDate(next: typeof date.value | ((prev: typeof date.value) => typeof date.value)) {\n  date.value = typeof next === 'function'\n    ? (next as (prev: typeof date.value) => typeof date.value)(date.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <div><div class=\"rounded-md border p-2\"><Calendar mode=\"single\" :selected=\"date\" @update:modelValue=\"setDate\" :month=\"month\" :onMonthChange=\"setMonth\" /><Button variant=\"outline\" size=\"sm\" class=\"mt-2 mb-1\" @click=\"setMonth(today)\">Current month\n        </Button></div><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">With button -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-14.html",
          "target": "components/ui/calendar-date-picker-14.html",
          "type": "registry:component",
          "content": "<template>\n  <div><div class=\"rounded-md border p-2\"><Calendar mode=\"single\" selected=\"${date}\" onSelect=\"${setDate}\" month=\"${month}\" onmonthchange=\"${setMonth}\" /><Button variant=\"outline\" size=\"sm\" class=\"mt-2 mb-1\" on-click=\"${() => setMonth(today)}\">Current month\n        </Button></div><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">With button -${' '}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-14.wxml",
          "target": "components/ui/calendar-date-picker-14/calendar-date-picker-14.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><view class=\"rounded-md border p-2\"><calendar mode=\"single\" selected=\"{{date}}\" bindchange=\"setDate\" month=\"{{month}}\" onmonthchange=\"{{setMonth}}\" /><button variant=\"outline\" size=\"sm\" class=\"mt-2 mb-1\" bindtap=\"setMonth(today)\">Current month\n        </button></view><text class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">With button -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "calendar",
          "date",
          "button",
          "react daypicker"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "calendar-date-picker-14",
          "group": "calendar-date-picker",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-14",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-14.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-14",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-14.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-14",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-14.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-14",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-14.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react",
              "date-fns"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue",
              "date-fns"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "calendar",
        "title": "Calendar Date Picker · Interactive State"
      },
      "dependencies": [
        "@timui/react",
        "date-fns"
      ],
      "categories": [
        "calendar"
      ]
    },
    {
      "name": "calendar-date-picker-15",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/calendar.json"
      ],
      "files": [
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-15.tsx",
          "type": "registry:component",
          "target": "components/ui/calendar-date-picker-15.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Button, Calendar } from '@timui/react'\nimport { addDays } from 'date-fns'\n\nexport default function Component() {\n  const today = new Date()\n  const selectedDay = addDays(today, -28)\n  const [month, setMonth] = useState(selectedDay)\n  const [date, setDate] = useState<Date | undefined>(selectedDay)\n\n  return (\n    <div>\n      <div className=\"rounded-md border p-2\">\n        <Calendar\n          mode=\"single\"\n          selected={date}\n          onSelect={setDate}\n          month={month}\n          onMonthChange={setMonth}\n        />\n        <Button\n          variant=\"outline\"\n          size=\"sm\"\n          className=\"mt-2 mb-1\"\n          onClick={() => {\n            setDate(today)\n            setMonth(today)\n          }}\n        >\n          Today\n        </Button>\n      </div>\n      <p\n        className=\"text-muted-foreground mt-4 text-center text-xs\"\n        role=\"region\"\n        aria-live=\"polite\"\n      >\n        With button -{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://daypicker.dev/\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React DayPicker\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-15.vue",
          "target": "components/ui/calendar-date-picker-15.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { Button } from '@timui/vue'\nimport { Calendar } from '@timui/vue'\nimport { addDays } from 'date-fns'\n\nconst today = new Date()\nconst selectedDay = addDays(today, -2)\n\nconst month = ref<Date>(selectedDay)\nconst date = ref<Date | undefined>(selectedDay)\n\nconst setDate = (next?: Date) => {\n  date.value = next\n}\n\nconst setMonth = (next: Date) => {\n  month.value = next\n}\n\nconst goToday = () => {\n  setDate(today)\n  setMonth(today)\n}\n</script>\n\n<template>\n  <div>\n    <div class=\"rounded-md border p-2\">\n      <Calendar\n        mode=\"single\"\n        :selected=\"date\"\n        :month=\"month\"\n        :onMonthChange=\"setMonth\"\n        @update:modelValue=\"setDate\"\n      />\n      <Button variant=\"outline\" size=\"sm\" class=\"mt-2 mb-1\" @click=\"goToday\">Today</Button>\n    </div>\n    <p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">\n      With button -\n      <a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">\n        React DayPicker\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-15.html",
          "target": "components/ui/calendar-date-picker-15.html",
          "type": "registry:component",
          "content": "<template>\n  <div><div class=\"rounded-md border p-2\"><Calendar mode=\"single\" selected=\"${date}\" onSelect=\"${setDate}\" month=\"${month}\" onmonthchange=\"${setMonth}\" /><Button variant=\"outline\" size=\"sm\" class=\"mt-2 mb-1\" on-click=\"${() => {\n            setDate(today)\n            setMonth(today)\n          }}\">Today\n        </Button></div><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">With button -${' '}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-15.wxml",
          "target": "components/ui/calendar-date-picker-15/calendar-date-picker-15.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><view class=\"rounded-md border p-2\"><calendar mode=\"single\" selected=\"{{date}}\" bindchange=\"setDate\" month=\"{{month}}\" onmonthchange=\"{{setMonth}}\" /><button variant=\"outline\" size=\"sm\" class=\"mt-2 mb-1\" bindtap=\"{\n            setDate(today)\n            setMonth(today)\n          }\">Today\n        </button></view><text class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">With button -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "calendar",
          "date",
          "button",
          "react daypicker"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "calendar-date-picker-15",
          "group": "calendar-date-picker",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-15",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-15.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-15",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-15.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-15",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-15.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-15",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-15.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react",
              "date-fns"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue",
              "date-fns"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "calendar",
        "title": "Calendar Date Picker · Interactive State"
      },
      "dependencies": [
        "@timui/react",
        "date-fns"
      ],
      "categories": [
        "calendar"
      ]
    },
    {
      "name": "calendar-date-picker-16",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/calendar.json",
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-16.tsx",
          "type": "registry:component",
          "target": "components/ui/calendar-date-picker-16.tsx",
          "content": "'use client'\n\nimport { useEffect, useId, useState } from 'react'\nimport { Calendar, Input, Label } from '@timui/react'\nimport { format } from 'date-fns'\nimport { CalendarIcon } from 'lucide-react'\n\nexport default function Component() {\n  const id = useId()\n  const today = new Date()\n  const [month, setMonth] = useState(today)\n  const [date, setDate] = useState<Date | undefined>(today)\n  const [inputValue, setInputValue] = useState('')\n\n  const handleDayPickerSelect = (date: Date | undefined) => {\n    if (!date) {\n      setInputValue('')\n      setDate(undefined)\n    } else {\n      setDate(date)\n      setMonth(date)\n      setInputValue(format(date, 'yyyy-MM-dd'))\n    }\n  }\n\n  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n    const value = e.target.value\n    setInputValue(value)\n\n    if (value) {\n      const parsedDate = new Date(value)\n      setDate(parsedDate)\n      setMonth(parsedDate)\n    } else {\n      setDate(undefined)\n    }\n  }\n\n  useEffect(() => {\n    setInputValue(format(today, 'yyyy-MM-dd'))\n  }, [])\n\n  return (\n    <div>\n      <div className=\"rounded-md border\">\n        <Calendar\n          mode=\"single\"\n          className=\"p-2\"\n          selected={date}\n          onSelect={handleDayPickerSelect}\n          month={month}\n          onMonthChange={setMonth}\n        />\n        <div className=\"border-t p-3\">\n          <div className=\"flex items-center gap-3\">\n            <Label htmlFor={id} className=\"text-xs\">\n              Enter date\n            </Label>\n            <div className=\"relative grow\">\n              <Input\n                id={id}\n                type=\"date\"\n                value={inputValue}\n                onChange={handleInputChange}\n                className=\"peer appearance-none ps-9 [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none\"\n                aria-label=\"Select date\"\n              />\n              <div className=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\">\n                <CalendarIcon size={16} aria-hidden=\"true\" />\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n      <p\n        className=\"text-muted-foreground mt-4 text-center text-xs\"\n        role=\"region\"\n        aria-live=\"polite\"\n      >\n        Date input -{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://daypicker.dev/\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React DayPicker\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-16.vue",
          "target": "components/ui/calendar-date-picker-16.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { onMounted, ref } from 'vue';\nimport { CalendarIcon } from 'lucide-vue-next';\nimport { Calendar } from '@timui/vue';\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\nimport { format } from 'date-fns';\n\nconst id = 'calendar-date-picker-16';\nconst today = new Date();\n\nconst month = ref<Date>(today);\nconst date = ref<Date | undefined>(today);\nconst inputValue = ref('');\n\nfunction setMonth(next: Date) {\n  month.value = next;\n}\n\nfunction handleDayPickerSelect(nextDate?: Date) {\n  if (!nextDate) {\n    inputValue.value = '';\n    date.value = undefined;\n    return;\n  }\n\n  date.value = nextDate;\n  month.value = nextDate;\n  inputValue.value = format(nextDate, 'yyyy-MM-dd');\n}\n\nfunction handleInputValueChange(nextValue: string) {\n  inputValue.value = nextValue;\n\n  if (!nextValue) {\n    date.value = undefined;\n    return;\n  }\n\n  const parsedDate = new Date(nextValue);\n  if (Number.isNaN(parsedDate.getTime())) {\n    return;\n  }\n\n  date.value = parsedDate;\n  month.value = parsedDate;\n}\n\nonMounted(() => {\n  inputValue.value = format(today, 'yyyy-MM-dd');\n});\n</script>\n\n<template>\n  <div>\n    <div class=\"rounded-md border\">\n      <Calendar\n        mode=\"single\"\n        class=\"p-2\"\n        :selected=\"date\"\n        @update:modelValue=\"handleDayPickerSelect\"\n        :month=\"month\"\n        :onMonthChange=\"setMonth\"\n      />\n      <div class=\"border-t p-3\">\n        <div class=\"flex items-center gap-3\">\n          <Label :htmlFor=\"id\" class=\"text-xs\">Enter date</Label>\n          <div class=\"relative grow\">\n            <Input\n              :id=\"id\"\n              type=\"date\"\n              :model-value=\"inputValue\"\n              @update:modelValue=\"(value) => handleInputValueChange(String(value ?? ''))\"\n              class=\"peer appearance-none ps-9 [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none\"\n              aria-label=\"Select date\"\n            />\n            <div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\">\n              <CalendarIcon :size=\"16\" aria-hidden=\"true\" />\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">\n      Date input -\n      <a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker</a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-16.html",
          "target": "components/ui/calendar-date-picker-16.html",
          "type": "registry:component",
          "content": "<template>\n  <div><div class=\"rounded-md border\"><Calendar mode=\"single\" class=\"p-2\" selected=\"${date}\" onSelect=\"${handleDayPickerSelect}\" month=\"${month}\" onmonthchange=\"${setMonth}\" /><div class=\"border-t p-3\"><div class=\"flex items-center gap-3\"><Label htmlfor=\"${id}\" class=\"text-xs\">Enter date\n            </Label><div class=\"relative grow\"><Input id=\"${id}\" type=\"date\" value=\"${inputValue}\" onchange=\"${handleInputChange}\" class=\"peer appearance-none ps-9 [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none\" aria-label=\"Select date\" /><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\"><CalendarIcon size=\"${16}\" aria-hidden=\"true\" /></div></div></div></div></div><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Date input -${' '}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-16.wxml",
          "target": "components/ui/calendar-date-picker-16/calendar-date-picker-16.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><view class=\"rounded-md border\"><calendar mode=\"single\" class=\"p-2\" selected=\"{{date}}\" bindchange=\"handleDayPickerSelect\" month=\"{{month}}\" onmonthchange=\"{{setMonth}}\" /><view class=\"border-t p-3\"><view class=\"flex items-center gap-3\"><label htmlfor=\"{{id}}\" class=\"text-xs\">Enter date\n            </label><view class=\"relative grow\"><input id=\"{{id}}\" type=\"date\" value=\"{{inputValue}}\" onchange=\"{{handleInputChange}}\" class=\"peer appearance-none ps-9 [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none\" aria-label=\"Select date\" /><view class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\"><calendaricon size=\"{{16}}\" aria-hidden=\"true\" /></view></view></view></view></view><text class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Date input -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "calendar",
          "date",
          "input",
          "react daypicker"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "calendar-date-picker-16",
          "group": "calendar-date-picker",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-16",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-16.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-16",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-16.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-16",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-16.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-16",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-16.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react",
              "date-fns"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue",
              "date-fns"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "calendar",
        "title": "Calendar Date Picker · Enter date"
      },
      "dependencies": [
        "@timui/react",
        "date-fns"
      ],
      "categories": [
        "calendar"
      ]
    },
    {
      "name": "calendar-date-picker-17",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/calendar.json",
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-17.tsx",
          "type": "registry:component",
          "target": "components/ui/calendar-date-picker-17.tsx",
          "content": "'use client'\n\nimport { useId, useState } from 'react'\nimport { Calendar, Input, Label } from '@timui/react'\nimport { ClockIcon } from 'lucide-react'\n\nexport default function Component() {\n  const id = useId()\n  const [date, setDate] = useState<Date | undefined>(new Date())\n\n  return (\n    <div>\n      <div className=\"rounded-md border\">\n        <Calendar mode=\"single\" className=\"p-2\" selected={date} onSelect={setDate} />\n        <div className=\"border-t p-3\">\n          <div className=\"flex items-center gap-3\">\n            <Label htmlFor={id} className=\"text-xs\">\n              Enter time\n            </Label>\n            <div className=\"relative grow\">\n              <Input\n                id={id}\n                type=\"time\"\n                step=\"1\"\n                defaultValue=\"12:00:00\"\n                className=\"peer appearance-none ps-9 [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none\"\n              />\n              <div className=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\">\n                <ClockIcon size={16} aria-hidden=\"true\" />\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n      <p\n        className=\"text-muted-foreground mt-4 text-center text-xs\"\n        role=\"region\"\n        aria-live=\"polite\"\n      >\n        Time input -{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://daypicker.dev/\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React DayPicker\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-17.vue",
          "target": "components/ui/calendar-date-picker-17.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { ClockIcon } from 'lucide-vue-next';\nimport { Calendar } from '@timui/vue';\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\n\n\n\nconst date = ref<Date | undefined>(new Date());\n\n\nconst id = 'calendar-date-picker-17';\n\n\nfunction setDate(next: typeof date.value | ((prev: typeof date.value) => typeof date.value)) {\n  date.value = typeof next === 'function'\n    ? (next as (prev: typeof date.value) => typeof date.value)(date.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <div><div class=\"rounded-md border\"><Calendar mode=\"single\" class=\"p-2\" :selected=\"date\" @update:modelValue=\"setDate\" /><div class=\"border-t p-3\"><div class=\"flex items-center gap-3\"><Label :htmlFor=\"id\" class=\"text-xs\">Enter time\n            </Label><div class=\"relative grow\"><Input :id=\"id\" type=\"time\" step=\"1\" default-value=\"12:00:00\" class=\"peer appearance-none ps-9 [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none\" /><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\"><ClockIcon :size=\"16\" aria-hidden=\"true\" /></div></div></div></div></div><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Time input -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-17.html",
          "target": "components/ui/calendar-date-picker-17.html",
          "type": "registry:component",
          "content": "<template>\n  <div><div class=\"rounded-md border\"><Calendar mode=\"single\" class=\"p-2\" selected=\"${date}\" onSelect=\"${setDate}\" /><div class=\"border-t p-3\"><div class=\"flex items-center gap-3\"><Label htmlfor=\"${id}\" class=\"text-xs\">Enter time\n            </Label><div class=\"relative grow\"><Input id=\"${id}\" type=\"time\" step=\"1\" default-value=\"12:00:00\" class=\"peer appearance-none ps-9 [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none\" /><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\"><ClockIcon size=\"${16}\" aria-hidden=\"true\" /></div></div></div></div></div><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Time input -${' '}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-17.wxml",
          "target": "components/ui/calendar-date-picker-17/calendar-date-picker-17.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><view class=\"rounded-md border\"><calendar mode=\"single\" class=\"p-2\" selected=\"{{date}}\" bindchange=\"setDate\" /><view class=\"border-t p-3\"><view class=\"flex items-center gap-3\"><label htmlfor=\"{{id}}\" class=\"text-xs\">Enter time\n            </label><view class=\"relative grow\"><input id=\"{{id}}\" type=\"time\" step=\"1\" default-value=\"12:00:00\" class=\"peer appearance-none ps-9 [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none\" /><view class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\"><clockicon size=\"{{16}}\" aria-hidden=\"true\" /></view></view></view></view></view><text class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Time input -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "calendar",
          "date",
          "input",
          "time",
          "react daypicker"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "calendar-date-picker-17",
          "group": "calendar-date-picker",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-17",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-17.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-17",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-17.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-17",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-17.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-17",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-17.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "calendar",
        "title": "Calendar Date Picker · Enter time"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "calendar"
      ]
    },
    {
      "name": "calendar-date-picker-18",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/calendar.json",
        "https://ui.timkit.cn/r/collapsible.json",
        "https://ui.timkit.cn/r/scroll-area.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-18.tsx",
          "type": "registry:component",
          "target": "components/ui/calendar-date-picker-18.tsx",
          "content": "'use client'\n\nimport { useEffect, useRef, useState } from 'react'\nimport {\n  Button,\n  Calendar,\n  Collapsible,\n  CollapsibleContent,\n  CollapsibleTrigger,\n  ScrollArea,\n} from '@timui/react'\nimport {\n  eachMonthOfInterval,\n  eachYearOfInterval,\n  endOfYear,\n  format,\n  isAfter,\n  isBefore,\n  startOfYear,\n} from 'date-fns'\nimport { ChevronDownIcon } from 'lucide-react'\n\ntype CaptionLabelProps = React.HTMLAttributes<HTMLElement>\ntype MonthGridProps = React.TableHTMLAttributes<HTMLTableElement>\n\nexport default function Component() {\n  const today = new Date()\n  const [month, setMonth] = useState(today)\n  const [date, setDate] = useState<Date | undefined>(today)\n  const [isYearView, setIsYearView] = useState(false)\n  const startDate = new Date(1980, 6)\n  const endDate = new Date(2030, 6)\n\n  const years = eachYearOfInterval({\n    start: startOfYear(startDate),\n    end: endOfYear(endDate),\n  })\n\n  return (\n    <div>\n      <Calendar\n        mode=\"single\"\n        selected={date}\n        onSelect={setDate}\n        month={month}\n        onMonthChange={setMonth}\n        defaultMonth={new Date()}\n        startMonth={startDate}\n        endMonth={endDate}\n        className=\"overflow-hidden rounded-md border p-2\"\n        classNames={{\n          month_caption: 'ms-2.5 me-20 justify-start',\n          nav: 'justify-end',\n        }}\n        components={{\n          CaptionLabel: (props: CaptionLabelProps) => (\n            <CaptionLabel isYearView={isYearView} setIsYearView={setIsYearView} {...props} />\n          ),\n          MonthGrid: (props: MonthGridProps) => {\n            return (\n              <MonthGrid\n                className={props.className}\n                isYearView={isYearView}\n                setIsYearView={setIsYearView}\n                startDate={startDate}\n                endDate={endDate}\n                years={years}\n                currentYear={month.getFullYear()}\n                currentMonth={month.getMonth()}\n                onMonthSelect={(selectedMonth: Date) => {\n                  setMonth(selectedMonth)\n                  setIsYearView(false)\n                }}\n              >\n                {props.children}\n              </MonthGrid>\n            )\n          },\n        }}\n      />\n      <p\n        className=\"text-muted-foreground mt-4 text-center text-xs\"\n        role=\"region\"\n        aria-live=\"polite\"\n      >\n        Advanced selection -{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://daypicker.dev/\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React DayPicker\n        </a>\n      </p>\n    </div>\n  )\n}\n\nfunction MonthGrid({\n  className,\n  children,\n  isYearView,\n  startDate,\n  endDate,\n  years,\n  currentYear,\n  currentMonth,\n  onMonthSelect,\n}: {\n  className?: string\n  children: React.ReactNode\n  isYearView: boolean\n  setIsYearView: React.Dispatch<React.SetStateAction<boolean>>\n  startDate: Date\n  endDate: Date\n  years: Date[]\n  currentYear: number\n  currentMonth: number\n  onMonthSelect: (date: Date) => void\n}) {\n  const currentYearRef = useRef<HTMLDivElement>(null)\n  const currentMonthButtonRef = useRef<HTMLButtonElement>(null)\n  const scrollAreaRef = useRef<HTMLDivElement>(null)\n\n  useEffect(() => {\n    if (isYearView && currentYearRef.current && scrollAreaRef.current) {\n      const viewport = scrollAreaRef.current.querySelector(\n        '[data-radix-scroll-area-viewport]'\n      ) as HTMLElement\n      if (viewport) {\n        const yearTop = currentYearRef.current.offsetTop\n        viewport.scrollTop = yearTop\n      }\n      setTimeout(() => {\n        currentMonthButtonRef.current?.focus()\n      }, 100)\n    }\n  }, [isYearView])\n\n  return (\n    <div className=\"relative\">\n      <table className={className}>{children}</table>\n      {isYearView && (\n        <div className=\"bg-background absolute inset-0 z-20 -mx-2 -mb-2\">\n          <ScrollArea ref={scrollAreaRef} className=\"h-full\">\n            {years.map((year) => {\n              const months = eachMonthOfInterval({\n                start: startOfYear(year),\n                end: endOfYear(year),\n              })\n              const isCurrentYear = year.getFullYear() === currentYear\n\n              return (\n                <div key={year.getFullYear()} ref={isCurrentYear ? currentYearRef : undefined}>\n                  <CollapsibleYear title={year.getFullYear().toString()} open={isCurrentYear}>\n                    <div className=\"grid grid-cols-3 gap-2\">\n                      {months.map((month) => {\n                        const isDisabled = isBefore(month, startDate) || isAfter(month, endDate)\n                        const isCurrentMonth =\n                          month.getMonth() === currentMonth && year.getFullYear() === currentYear\n\n                        return (\n                          <Button\n                            key={month.getTime()}\n                            ref={isCurrentMonth ? currentMonthButtonRef : undefined}\n                            variant={isCurrentMonth ? 'default' : 'outline'}\n                            size=\"sm\"\n                            className=\"h-7\"\n                            disabled={isDisabled}\n                            onClick={() => onMonthSelect(month)}\n                          >\n                            {format(month, 'MMM')}\n                          </Button>\n                        )\n                      })}\n                    </div>\n                  </CollapsibleYear>\n                </div>\n              )\n            })}\n          </ScrollArea>\n        </div>\n      )}\n    </div>\n  )\n}\n\nfunction CaptionLabel({\n  children,\n  isYearView,\n  setIsYearView,\n}: {\n  isYearView: boolean\n  setIsYearView: React.Dispatch<React.SetStateAction<boolean>>\n} & React.HTMLAttributes<HTMLSpanElement>) {\n  return (\n    <Button\n      className=\"data-[state=open]:text-muted-foreground/80 -ms-2 flex items-center gap-2 text-sm font-medium hover:bg-transparent [&[data-state=open]>svg]:rotate-180\"\n      variant=\"ghost\"\n      size=\"sm\"\n      onClick={() => setIsYearView((prev) => !prev)}\n      data-state={isYearView ? 'open' : 'closed'}\n    >\n      {children}\n      <ChevronDownIcon\n        size={16}\n        className=\"text-muted-foreground/80 shrink-0 transition-transform duration-200\"\n        aria-hidden=\"true\"\n      />\n    </Button>\n  )\n}\n\nfunction CollapsibleYear({\n  title,\n  children,\n  open,\n}: {\n  title: string\n  children: React.ReactNode\n  open?: boolean\n}) {\n  return (\n    <Collapsible className=\"border-t px-2 py-1.5\" defaultOpen={open}>\n      <CollapsibleTrigger asChild>\n        <Button\n          className=\"flex w-full justify-start gap-2 text-sm font-medium hover:bg-transparent [&[data-state=open]>svg]:rotate-180\"\n          variant=\"ghost\"\n          size=\"sm\"\n        >\n          <ChevronDownIcon\n            size={16}\n            className=\"text-muted-foreground/80 shrink-0 transition-transform duration-200\"\n            aria-hidden=\"true\"\n          />\n          {title}\n        </Button>\n      </CollapsibleTrigger>\n      <CollapsibleContent className=\"data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down overflow-hidden px-3 py-1 text-sm transition-all\">\n        {children}\n      </CollapsibleContent>\n    </Collapsible>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-18.vue",
          "target": "components/ui/calendar-date-picker-18.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport { format } from 'date-fns'\nimport { Calendar } from '@timui/vue'\n\nconst today = new Date()\nconst startDate = new Date(1980, 6)\nconst endDate = new Date(2030, 6)\n\nconst month = ref<Date>(today)\nconst date = ref<Date | undefined>(today)\n\nconst yearOptions = computed(() => {\n  const years: number[] = []\n  for (let y = startDate.getFullYear(); y <= endDate.getFullYear(); y += 1) {\n    years.push(y)\n  }\n  return years\n})\n\nconst monthOptions = computed(() =>\n  Array.from({ length: 12 }, (_, index) => ({\n    value: index,\n    label: format(new Date(2000, index, 1), 'MMM'),\n  }))\n)\n\nfunction setMonth(next: Date) {\n  month.value = next\n}\n\nfunction setDate(next: Date | undefined) {\n  date.value = next\n  if (next) {\n    month.value = next\n  }\n}\n\nfunction handleYearChange(event: Event) {\n  const target = event.target as HTMLSelectElement\n  const year = Number(target.value)\n  if (Number.isNaN(year)) return\n  month.value = new Date(year, month.value.getMonth(), 1)\n}\n\nfunction handleMonthChange(event: Event) {\n  const target = event.target as HTMLSelectElement\n  const selectedMonth = Number(target.value)\n  if (Number.isNaN(selectedMonth)) return\n  month.value = new Date(month.value.getFullYear(), selectedMonth, 1)\n}\n</script>\n\n<template>\n  <div class=\"space-y-3\">\n    <div class=\"flex items-center gap-2\">\n      <select\n        class=\"border-input bg-background h-8 rounded-md border px-2 text-sm\"\n        :value=\"month.getMonth()\"\n        @change=\"handleMonthChange\"\n      >\n        <option v-for=\"option in monthOptions\" :key=\"option.value\" :value=\"option.value\">\n          {{ option.label }}\n        </option>\n      </select>\n      <select\n        class=\"border-input bg-background h-8 rounded-md border px-2 text-sm\"\n        :value=\"month.getFullYear()\"\n        @change=\"handleYearChange\"\n      >\n        <option v-for=\"year in yearOptions\" :key=\"year\" :value=\"year\">\n          {{ year }}\n        </option>\n      </select>\n    </div>\n\n    <Calendar\n      mode=\"single\"\n      :selected=\"date\"\n      @update:modelValue=\"setDate\"\n      :month=\"month\"\n      :onMonthChange=\"setMonth\"\n      :defaultMonth=\"today\"\n      :startMonth=\"startDate\"\n      :endMonth=\"endDate\"\n      class=\"overflow-hidden rounded-md border p-2\"\n      :classNames=\"{ month_caption: 'ms-2.5 me-20 justify-start', nav: 'justify-end' }\"\n    />\n\n    <p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">\n      Advanced selection -\n      <a\n        class=\"hover:text-foreground underline\"\n        href=\"https://daypicker.dev/\"\n        target=\"_blank\"\n        rel=\"noopener nofollow\"\n      >\n        React DayPicker\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-18.html",
          "target": "components/ui/calendar-date-picker-18.html",
          "type": "registry:component",
          "content": "<template>\n  <div><Calendar mode=\"single\" selected=\"${date}\" onSelect=\"${setDate}\" month=\"${month}\" onmonthchange=\"${setMonth}\" defaultmonth=\"${new Date()}\" startmonth=\"${startDate}\" endmonth=\"${endDate}\" class=\"overflow-hidden rounded-md border p-2\" classnames=\"${{\n          month_caption: 'ms-2.5 me-20 justify-start',\n          nav: 'justify-end',\n        }}\" components=\"${{\n          CaptionLabel: (props: CaptionLabelProps) => (\n            <CaptionLabel isYearView={isYearView} setIsYearView={setIsYearView} {...props} />\n          ),\n          MonthGrid: (props: MonthGridProps) => {\n            return (\n              <MonthGrid\n                className={props.className}\n                isYearView={isYearView}\n                setIsYearView={setIsYearView}\n                startDate={startDate}\n                endDate={endDate}\n                years={years}\n                currentYear={month.getFullYear()}\n                currentMonth={month.getMonth()}\n                onMonthSelect={(selectedMonth: Date) => {\n                  setMonth(selectedMonth)\n                  setIsYearView(false)\n                }}\n              >\n                {props.children}\n              </MonthGrid>\n            )\n          },\n        }}\" /><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Advanced selection -${' '}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-18.wxml",
          "target": "components/ui/calendar-date-picker-18/calendar-date-picker-18.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><calendar mode=\"single\" selected=\"{{date}}\" bindchange=\"setDate\" month=\"{{month}}\" onmonthchange=\"{{setMonth}}\" defaultmonth=\"{{new Date()}}\" startmonth=\"{{startDate}}\" endmonth=\"{{endDate}}\" class=\"overflow-hidden rounded-md border p-2\" classnames=\"{{{\n          month_caption: 'ms-2.5 me-20 justify-start',\n          nav: 'justify-end',\n        }}}\" components=\"{{{\n          CaptionLabel: (props: CaptionLabelProps) => (\n            <CaptionLabel isYearView={isYearView} setIsYearView={setIsYearView} {...props} />\n          ),\n          MonthGrid: (props: MonthGridProps) => {\n            return (\n              <MonthGrid\n                className={props.className}\n                isYearView={isYearView}\n                setIsYearView={setIsYearView}\n                startDate={startDate}\n                endDate={endDate}\n                years={years}\n                currentYear={month.getFullYear()}\n                currentMonth={month.getMonth()}\n                onMonthSelect={(selectedMonth: Date) => {\n                  setMonth(selectedMonth)\n                  setIsYearView(false)\n                }}\n              >\n                {props.children}\n              </MonthGrid>\n            )\n          },\n        }}}\" /><text class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Advanced selection -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "calendar",
          "date",
          "collapsible",
          "react daypicker",
          "radix"
        ],
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "calendar-date-picker-18",
          "group": "calendar-date-picker",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-18",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-18.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-18",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-18.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-18",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-18.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-18",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-18.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react",
              "date-fns"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue",
              "date-fns"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "calendar",
        "title": "Calendar Date Picker · Dismissible"
      },
      "dependencies": [
        "@timui/react",
        "date-fns"
      ],
      "categories": [
        "calendar"
      ]
    },
    {
      "name": "calendar-date-picker-19",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/calendar.json",
        "https://ui.timkit.cn/r/scroll-area.json"
      ],
      "files": [
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-19.tsx",
          "type": "registry:component",
          "target": "components/ui/calendar-date-picker-19.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Button, Calendar, ScrollArea } from '@timui/react'\nimport { format } from 'date-fns'\n\nexport default function Component() {\n  const today = new Date()\n  const [date, setDate] = useState<Date>(today)\n  const [time, setTime] = useState<string | null>(null)\n\n  // Mock time slots data\n  const timeSlots = [\n    { time: '09:00', available: false },\n    { time: '09:30', available: false },\n    { time: '10:00', available: true },\n    { time: '10:30', available: true },\n    { time: '11:00', available: true },\n    { time: '11:30', available: true },\n    { time: '12:00', available: false },\n    { time: '12:30', available: true },\n    { time: '13:00', available: true },\n    { time: '13:30', available: true },\n    { time: '14:00', available: true },\n    { time: '14:30', available: false },\n    { time: '15:00', available: false },\n    { time: '15:30', available: true },\n    { time: '16:00', available: true },\n    { time: '16:30', available: true },\n    { time: '17:00', available: true },\n    { time: '17:30', available: true },\n  ]\n\n  return (\n    <div>\n      <div className=\"rounded-md border\">\n        <div className=\"flex max-sm:flex-col\">\n          <Calendar\n            mode=\"single\"\n            selected={date}\n            onSelect={(newDate) => {\n              if (newDate) {\n                setDate(newDate)\n                setTime(null)\n              }\n            }}\n            className=\"p-2 sm:pe-5\"\n            disabled={[\n              { before: today }, // Dates before today\n            ]}\n          />\n          <div className=\"relative w-full max-sm:h-48 sm:w-40\">\n            <div className=\"absolute inset-0 py-4 max-sm:border-t\">\n              <ScrollArea className=\"h-full sm:border-s\">\n                <div className=\"space-y-3\">\n                  <div className=\"flex h-5 shrink-0 items-center px-5\">\n                    <p className=\"text-sm font-medium\">{format(date, 'EEEE, d')}</p>\n                  </div>\n                  <div className=\"grid gap-1.5 px-5 max-sm:grid-cols-2\">\n                    {timeSlots.map(({ time: timeSlot, available }) => (\n                      <Button\n                        key={timeSlot}\n                        variant={time === timeSlot ? 'default' : 'outline'}\n                        size=\"sm\"\n                        className=\"w-full\"\n                        onClick={() => setTime(timeSlot)}\n                        disabled={!available}\n                      >\n                        {timeSlot}\n                      </Button>\n                    ))}\n                  </div>\n                </div>\n              </ScrollArea>\n            </div>\n          </div>\n        </div>\n      </div>\n      <p\n        className=\"text-muted-foreground mt-4 text-center text-xs\"\n        role=\"region\"\n        aria-live=\"polite\"\n      >\n        Appointment picker -{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://daypicker.dev/\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React DayPicker\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-19.vue",
          "target": "components/ui/calendar-date-picker-19.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Button } from '@timui/vue';\nimport { Calendar } from '@timui/vue';\nimport { ScrollArea } from '@timui/vue';\nimport { format } from 'date-fns';\n\n\nconst date = ref<Date>(today);\nconst time = ref<string | null>(null);\n\n\nfunction setDate(next: typeof date.value | ((prev: typeof date.value) => typeof date.value)) {\n  date.value = typeof next === 'function'\n    ? (next as (prev: typeof date.value) => typeof date.value)(date.value)\n    : next;\n}\n\nfunction setTime(next: typeof time.value | ((prev: typeof time.value) => typeof time.value)) {\n  time.value = typeof next === 'function'\n    ? (next as (prev: typeof time.value) => typeof time.value)(time.value)\n    : next;\n}\n\n\nconst timeSlots = [\n    { time: '09:00', available: false },\n    { time: '09:30', available: false },\n    { time: '10:00', available: true },\n    { time: '10:30', available: true },\n    { time: '11:00', available: true },\n    { time: '11:30', available: true },\n    { time: '12:00', available: false },\n    { time: '12:30', available: true },\n    { time: '13:00', available: true },\n    { time: '13:30', available: true },\n    { time: '14:00', available: true },\n    { time: '14:30', available: false },\n    { time: '15:00', available: false },\n    { time: '15:30', available: true },\n    { time: '16:00', available: true },\n    { time: '16:30', available: true },\n    { time: '17:00', available: true },\n    { time: '17:30', available: true },\n  ]\n\n</script>\n\n<template>\n  <div><div class=\"rounded-md border\"><div class=\"flex max-sm:flex-col\"><Calendar mode=\"single\" :selected=\"date\" @update:modelValue=\"{\n              if (newDate) {\n                setDate(newDate)\n                setTime(null)\n              }\n            }\" class=\"p-2 sm:pe-5\" :disabled=\"[\n              { before: today }, // Dates before today\n            ]\" /><div class=\"relative w-full max-sm:h-48 sm:w-40\"><div class=\"absolute inset-0 py-4 max-sm:border-t\"><ScrollArea class=\"h-full sm:border-s\"><div class=\"space-y-3\"><div class=\"flex h-5 shrink-0 items-center px-5\"><p class=\"text-sm font-medium\">{{ format(date, 'EEEE, d') }}</p></div><div class=\"grid gap-1.5 px-5 max-sm:grid-cols-2\"><Button v-for=\"({ time: timeSlot, available }, index) in timeSlots\" :key=\"timeSlot\" :variant=\"time === timeSlot ? 'default' : 'outline'\" size=\"sm\" class=\"w-full\" @click=\"setTime(timeSlot)\" :disabled=\"!available\">{{ timeSlot }}</Button></div></div></ScrollArea></div></div></div></div><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Appointment picker -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-19.html",
          "target": "components/ui/calendar-date-picker-19.html",
          "type": "registry:component",
          "content": "<template>\n  <div><div class=\"rounded-md border\"><div class=\"flex max-sm:flex-col\"><Calendar mode=\"single\" selected=\"${date}\" onSelect=\"${(newDate) => {\n              if (newDate) {\n                setDate(newDate)\n                setTime(null)\n              }\n            }}\" class=\"p-2 sm:pe-5\" disabled=\"${[\n              { before: today }, // Dates before today\n            ]}\" /><div class=\"relative w-full max-sm:h-48 sm:w-40\"><div class=\"absolute inset-0 py-4 max-sm:border-t\"><ScrollArea class=\"h-full sm:border-s\"><div class=\"space-y-3\"><div class=\"flex h-5 shrink-0 items-center px-5\"><p class=\"text-sm font-medium\">${format(date, 'EEEE, d')}</p></div><div class=\"grid gap-1.5 px-5 max-sm:grid-cols-2\"><!-- Loop timeSlots -->\n<Button key=\"${timeSlot}\" variant=\"${time === timeSlot ? 'default' : 'outline'}\" size=\"sm\" class=\"w-full\" on-click=\"${() => setTime(timeSlot)}\" disabled=\"${!available}\">${timeSlot}</Button>\n<!-- End Loop --></div></div></ScrollArea></div></div></div></div><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Appointment picker -${' '}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-19.wxml",
          "target": "components/ui/calendar-date-picker-19/calendar-date-picker-19.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><view class=\"rounded-md border\"><view class=\"flex max-sm:flex-col\"><calendar mode=\"single\" selected=\"{{date}}\" bindchange=\"{\n              if (newDate) {\n                setDate(newDate)\n                setTime(null)\n              }\n            }\" class=\"p-2 sm:pe-5\" disabled=\"{{[\n              { before: today }, // Dates before today\n            ]}}\" /><view class=\"relative w-full max-sm:h-48 sm:w-40\"><view class=\"absolute inset-0 py-4 max-sm:border-t\"><scrollarea class=\"h-full sm:border-s\"><view class=\"space-y-3\"><view class=\"flex h-5 shrink-0 items-center px-5\"><text class=\"text-sm font-medium\">{{ format(date, 'EEEE, d') }}</text></view><view class=\"grid gap-1.5 px-5 max-sm:grid-cols-2\"><button wx:for=\"{{timeSlots}}\" wx:for-item=\"{ time: timeSlot, available }\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{timeSlot}}\" variant=\"{{time === timeSlot ? 'default' : 'outline'}}\" size=\"sm\" class=\"w-full\" bindtap=\"setTime(timeSlot)\" disabled=\"{{!available}}\">{{ timeSlot }}</button></view></view></scrollarea></view></view></view></view><text class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Appointment picker -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "calendar",
          "date",
          "time",
          "button",
          "react daypicker"
        ],
        "colSpan": 3,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "calendar-date-picker-19",
          "group": "calendar-date-picker",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-19",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-19.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-19",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-19.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-19",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-19.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-19",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-19.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react",
              "date-fns"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue",
              "date-fns"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "calendar",
        "title": "Calendar Date Picker · Disabled State"
      },
      "dependencies": [
        "@timui/react",
        "date-fns"
      ],
      "categories": [
        "calendar"
      ]
    },
    {
      "name": "calendar-date-picker-20",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/calendar.json"
      ],
      "files": [
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-20.tsx",
          "type": "registry:component",
          "target": "components/ui/calendar-date-picker-20.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Button, Calendar } from '@timui/react'\nimport { subDays, subMonths, subYears } from 'date-fns'\n\nexport default function Component() {\n  const today = new Date()\n  const yesterday = subDays(today, 1)\n  const lastWeek = subDays(today, 7)\n  const lastMonth = subMonths(today, 1)\n  const lastYear = subYears(today, 1)\n  const [month, setMonth] = useState(today)\n  const [date, setDate] = useState<Date>(today)\n\n  return (\n    <div>\n      <div className=\"rounded-md border\">\n        <div className=\"flex max-sm:flex-col\">\n          <div className=\"relative py-4 max-sm:order-1 max-sm:border-t sm:w-32\">\n            <div className=\"h-full sm:border-e\">\n              <div className=\"flex flex-col px-2\">\n                <Button\n                  variant=\"ghost\"\n                  size=\"sm\"\n                  className=\"w-full justify-start\"\n                  onClick={() => {\n                    setDate(today)\n                    setMonth(today)\n                  }}\n                >\n                  Today\n                </Button>\n                <Button\n                  variant=\"ghost\"\n                  size=\"sm\"\n                  className=\"w-full justify-start\"\n                  onClick={() => {\n                    setDate(yesterday)\n                    setMonth(yesterday)\n                  }}\n                >\n                  Yesterday\n                </Button>\n                <Button\n                  variant=\"ghost\"\n                  size=\"sm\"\n                  className=\"w-full justify-start\"\n                  onClick={() => {\n                    setDate(lastWeek)\n                    setMonth(lastWeek)\n                  }}\n                >\n                  Last week\n                </Button>\n                <Button\n                  variant=\"ghost\"\n                  size=\"sm\"\n                  className=\"w-full justify-start\"\n                  onClick={() => {\n                    setDate(lastMonth)\n                    setMonth(lastMonth)\n                  }}\n                >\n                  Last month\n                </Button>\n                <Button\n                  variant=\"ghost\"\n                  size=\"sm\"\n                  className=\"w-full justify-start\"\n                  onClick={() => {\n                    setDate(lastYear)\n                    setMonth(lastYear)\n                  }}\n                >\n                  Last year\n                </Button>\n              </div>\n            </div>\n          </div>\n          <Calendar\n            mode=\"single\"\n            selected={date}\n            onSelect={(newDate) => {\n              if (newDate) {\n                setDate(newDate)\n              }\n            }}\n            month={month}\n            onMonthChange={setMonth}\n            className=\"p-2\"\n            disabled={[\n              { after: today }, // Dates before today\n            ]}\n          />\n        </div>\n      </div>\n      <p\n        className=\"text-muted-foreground mt-4 text-center text-xs\"\n        role=\"region\"\n        aria-live=\"polite\"\n      >\n        Calendar with presets -{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://daypicker.dev/\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React DayPicker\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-20.vue",
          "target": "components/ui/calendar-date-picker-20.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { Button } from '@timui/vue'\nimport { Calendar } from '@timui/vue'\nimport { subDays, subMonths, subYears } from 'date-fns'\n\nconst today = new Date()\nconst yesterday = subDays(today, 1)\nconst lastWeek = subDays(today, 7)\nconst lastMonth = subMonths(today, 1)\nconst lastYear = subYears(today, 1)\n\nconst month = ref<Date>(today)\nconst date = ref<Date | undefined>(today)\n\nconst setDate = (next?: Date) => {\n  date.value = next\n}\n\nconst setMonth = (next: Date) => {\n  month.value = next\n}\n\nconst applyPreset = (presetDate: Date) => {\n  setDate(presetDate)\n  setMonth(presetDate)\n}\n\nconst onCalendarChange = (newDate?: Date) => {\n  if (!newDate) return\n  setDate(newDate)\n}\n</script>\n\n<template>\n  <div>\n    <div class=\"rounded-md border\">\n      <div class=\"flex max-sm:flex-col\">\n        <div class=\"relative py-4 max-sm:order-1 max-sm:border-t sm:w-32\">\n          <div class=\"h-full sm:border-e\">\n            <div class=\"flex flex-col px-2\">\n              <Button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" @click=\"applyPreset(today)\">Today</Button>\n              <Button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" @click=\"applyPreset(yesterday)\">Yesterday</Button>\n              <Button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" @click=\"applyPreset(lastWeek)\">Last week</Button>\n              <Button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" @click=\"applyPreset(lastMonth)\">Last month</Button>\n              <Button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" @click=\"applyPreset(lastYear)\">Last year</Button>\n            </div>\n          </div>\n        </div>\n        <Calendar\n          mode=\"single\"\n          class=\"p-2\"\n          :selected=\"date\"\n          :month=\"month\"\n          :onMonthChange=\"setMonth\"\n          :disabled=\"[{ after: today }]\"\n          @update:modelValue=\"onCalendarChange\"\n        />\n      </div>\n    </div>\n    <p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">\n      Calendar with presets -\n      <a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">\n        React DayPicker\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-20.html",
          "target": "components/ui/calendar-date-picker-20.html",
          "type": "registry:component",
          "content": "<template>\n  <div><div class=\"rounded-md border\"><div class=\"flex max-sm:flex-col\"><div class=\"relative py-4 max-sm:order-1 max-sm:border-t sm:w-32\"><div class=\"h-full sm:border-e\"><div class=\"flex flex-col px-2\"><Button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" on-click=\"${() => {\n                    setDate(today)\n                    setMonth(today)\n                  }}\">Today\n                </Button><Button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" on-click=\"${() => {\n                    setDate(yesterday)\n                    setMonth(yesterday)\n                  }}\">Yesterday\n                </Button><Button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" on-click=\"${() => {\n                    setDate(lastWeek)\n                    setMonth(lastWeek)\n                  }}\">Last week\n                </Button><Button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" on-click=\"${() => {\n                    setDate(lastMonth)\n                    setMonth(lastMonth)\n                  }}\">Last month\n                </Button><Button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" on-click=\"${() => {\n                    setDate(lastYear)\n                    setMonth(lastYear)\n                  }}\">Last year\n                </Button></div></div></div><Calendar mode=\"single\" selected=\"${date}\" onSelect=\"${(newDate) => {\n              if (newDate) {\n                setDate(newDate)\n              }\n            }}\" month=\"${month}\" onmonthchange=\"${setMonth}\" class=\"p-2\" disabled=\"${[\n              { after: today }, // Dates before today\n            ]}\" /></div></div><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Calendar with presets -${' '}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-20.wxml",
          "target": "components/ui/calendar-date-picker-20/calendar-date-picker-20.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><view class=\"rounded-md border\"><view class=\"flex max-sm:flex-col\"><view class=\"relative py-4 max-sm:order-1 max-sm:border-t sm:w-32\"><view class=\"h-full sm:border-e\"><view class=\"flex flex-col px-2\"><button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" bindtap=\"{\n                    setDate(today)\n                    setMonth(today)\n                  }\">Today\n                </button><button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" bindtap=\"{\n                    setDate(yesterday)\n                    setMonth(yesterday)\n                  }\">Yesterday\n                </button><button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" bindtap=\"{\n                    setDate(lastWeek)\n                    setMonth(lastWeek)\n                  }\">Last week\n                </button><button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" bindtap=\"{\n                    setDate(lastMonth)\n                    setMonth(lastMonth)\n                  }\">Last month\n                </button><button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" bindtap=\"{\n                    setDate(lastYear)\n                    setMonth(lastYear)\n                  }\">Last year\n                </button></view></view></view><calendar mode=\"single\" selected=\"{{date}}\" bindchange=\"{\n              if (newDate) {\n                setDate(newDate)\n              }\n            }\" month=\"{{month}}\" onmonthchange=\"{{setMonth}}\" class=\"p-2\" disabled=\"{{[\n              { after: today }, // Dates before today\n            ]}}\" /></view></view><text class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Calendar with presets -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "calendar",
          "date",
          "button",
          "react daypicker"
        ],
        "colSpan": 3,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "calendar-date-picker-20",
          "group": "calendar-date-picker",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-20",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-20.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-20",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-20.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-20",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-20.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-20",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-20.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react",
              "date-fns"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue",
              "date-fns"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "calendar",
        "title": "Calendar Date Picker · Disabled State"
      },
      "dependencies": [
        "@timui/react",
        "date-fns"
      ],
      "categories": [
        "calendar"
      ]
    },
    {
      "name": "calendar-date-picker-21",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/calendar.json"
      ],
      "files": [
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-21.tsx",
          "type": "registry:component",
          "target": "components/ui/calendar-date-picker-21.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Button, Calendar } from '@timui/react'\nimport {\n  endOfMonth,\n  endOfYear,\n  startOfMonth,\n  startOfYear,\n  subDays,\n  subMonths,\n  subYears,\n} from 'date-fns'\n\ntype CalendarRangeValue = { from: Date | undefined; to?: Date }\ntype CalendarSelectedValue = Date | Date[] | CalendarRangeValue | undefined\n\nexport default function Component() {\n  const today = new Date()\n  const yesterday = {\n    from: subDays(today, 1),\n    to: subDays(today, 1),\n  }\n  const last7Days = {\n    from: subDays(today, 6),\n    to: today,\n  }\n  const last30Days = {\n    from: subDays(today, 29),\n    to: today,\n  }\n  const monthToDate = {\n    from: startOfMonth(today),\n    to: today,\n  }\n  const lastMonth = {\n    from: startOfMonth(subMonths(today, 1)),\n    to: endOfMonth(subMonths(today, 1)),\n  }\n  const yearToDate = {\n    from: startOfYear(today),\n    to: today,\n  }\n  const lastYear = {\n    from: startOfYear(subYears(today, 1)),\n    to: endOfYear(subYears(today, 1)),\n  }\n  const [month, setMonth] = useState(today)\n  const [date, setDate] = useState<CalendarRangeValue | undefined>(last7Days)\n\n  return (\n    <div>\n      <div className=\"rounded-md border\">\n        <div className=\"flex max-sm:flex-col\">\n          <div className=\"relative py-4 max-sm:order-1 max-sm:border-t sm:w-32\">\n            <div className=\"h-full sm:border-e\">\n              <div className=\"flex flex-col px-2\">\n                <Button\n                  variant=\"ghost\"\n                  size=\"sm\"\n                  className=\"w-full justify-start\"\n                  onClick={() => {\n                    setDate({\n                      from: today,\n                      to: today,\n                    })\n                    setMonth(today)\n                  }}\n                >\n                  Today\n                </Button>\n                <Button\n                  variant=\"ghost\"\n                  size=\"sm\"\n                  className=\"w-full justify-start\"\n                  onClick={() => {\n                    setDate(yesterday)\n                    setMonth(yesterday.to)\n                  }}\n                >\n                  Yesterday\n                </Button>\n                <Button\n                  variant=\"ghost\"\n                  size=\"sm\"\n                  className=\"w-full justify-start\"\n                  onClick={() => {\n                    setDate(last7Days)\n                    setMonth(last7Days.to)\n                  }}\n                >\n                  Last 7 days\n                </Button>\n                <Button\n                  variant=\"ghost\"\n                  size=\"sm\"\n                  className=\"w-full justify-start\"\n                  onClick={() => {\n                    setDate(last30Days)\n                    setMonth(last30Days.to)\n                  }}\n                >\n                  Last 30 days\n                </Button>\n                <Button\n                  variant=\"ghost\"\n                  size=\"sm\"\n                  className=\"w-full justify-start\"\n                  onClick={() => {\n                    setDate(monthToDate)\n                    setMonth(monthToDate.to)\n                  }}\n                >\n                  Month to date\n                </Button>\n                <Button\n                  variant=\"ghost\"\n                  size=\"sm\"\n                  className=\"w-full justify-start\"\n                  onClick={() => {\n                    setDate(lastMonth)\n                    setMonth(lastMonth.to)\n                  }}\n                >\n                  Last month\n                </Button>\n                <Button\n                  variant=\"ghost\"\n                  size=\"sm\"\n                  className=\"w-full justify-start\"\n                  onClick={() => {\n                    setDate(yearToDate)\n                    setMonth(yearToDate.to)\n                  }}\n                >\n                  Year to date\n                </Button>\n                <Button\n                  variant=\"ghost\"\n                  size=\"sm\"\n                  className=\"w-full justify-start\"\n                  onClick={() => {\n                    setDate(lastYear)\n                    setMonth(lastYear.to)\n                  }}\n                >\n                  Last year\n                </Button>\n              </div>\n            </div>\n          </div>\n          <Calendar\n            mode=\"range\"\n            selected={date}\n            onSelect={(newDate: CalendarSelectedValue) => {\n              if (newDate) {\n                setDate(newDate as CalendarRangeValue)\n              }\n            }}\n            month={month}\n            onMonthChange={setMonth}\n            className=\"p-2\"\n            disabled={[\n              { after: today }, // Dates before today\n            ]}\n          />\n        </div>\n      </div>\n      <p\n        className=\"text-muted-foreground mt-4 text-center text-xs\"\n        role=\"region\"\n        aria-live=\"polite\"\n      >\n        Range calendar with presets -{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://daypicker.dev/\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React DayPicker\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-21.vue",
          "target": "components/ui/calendar-date-picker-21.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { Button } from '@timui/vue'\nimport { Calendar } from '@timui/vue'\nimport {\n  endOfMonth,\n  endOfYear,\n  startOfMonth,\n  startOfYear,\n  subDays,\n  subMonths,\n  subYears,\n} from 'date-fns'\n\ntype CalendarRangeValue = { from?: Date; to?: Date } | undefined\n\nconst today = new Date()\nconst yesterday = { from: subDays(today, 1), to: subDays(today, 1) }\nconst last7Days = { from: subDays(today, 6), to: today }\nconst last30Days = { from: subDays(today, 29), to: today }\nconst monthToDate = { from: startOfMonth(today), to: today }\nconst lastMonthDate = subMonths(today, 1)\nconst lastMonth = { from: startOfMonth(lastMonthDate), to: endOfMonth(lastMonthDate) }\nconst yearToDate = { from: startOfYear(today), to: today }\nconst lastYearDate = subYears(today, 1)\nconst lastYear = { from: startOfYear(lastYearDate), to: endOfYear(lastYearDate) }\n\nconst month = ref<Date>(today)\nconst date = ref<CalendarRangeValue>(last7Days)\n\nconst setDate = (next: CalendarRangeValue) => {\n  date.value = next\n}\n\nconst setMonth = (next: Date) => {\n  month.value = next\n}\n\nconst applyRange = (range: Exclude<CalendarRangeValue, undefined>) => {\n  setDate(range)\n  if (range.to) setMonth(range.to)\n}\n\nconst onCalendarChange = (newDate?: Date | Date[] | CalendarRangeValue) => {\n  if (!newDate || Array.isArray(newDate) || newDate instanceof Date) return\n  setDate(newDate)\n}\n</script>\n\n<template>\n  <div>\n    <div class=\"rounded-md border\">\n      <div class=\"flex max-sm:flex-col\">\n        <div class=\"relative py-4 max-sm:order-1 max-sm:border-t sm:w-32\">\n          <div class=\"h-full sm:border-e\">\n            <div class=\"flex flex-col px-2\">\n              <Button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" @click=\"applyRange({ from: today, to: today })\">Today</Button>\n              <Button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" @click=\"applyRange(yesterday)\">Yesterday</Button>\n              <Button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" @click=\"applyRange(last7Days)\">Last 7 days</Button>\n              <Button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" @click=\"applyRange(last30Days)\">Last 30 days</Button>\n              <Button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" @click=\"applyRange(monthToDate)\">Month to date</Button>\n              <Button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" @click=\"applyRange(lastMonth)\">Last month</Button>\n              <Button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" @click=\"applyRange(yearToDate)\">Year to date</Button>\n              <Button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" @click=\"applyRange(lastYear)\">Last year</Button>\n            </div>\n          </div>\n        </div>\n        <Calendar\n          mode=\"range\"\n          class=\"p-2\"\n          :selected=\"date\"\n          :month=\"month\"\n          :onMonthChange=\"setMonth\"\n          :disabled=\"[{ after: today }]\"\n          @update:modelValue=\"onCalendarChange\"\n        />\n      </div>\n    </div>\n    <p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">\n      Range calendar with presets -\n      <a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">\n        React DayPicker\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-21.html",
          "target": "components/ui/calendar-date-picker-21.html",
          "type": "registry:component",
          "content": "<template>\n  <div><div class=\"rounded-md border\"><div class=\"flex max-sm:flex-col\"><div class=\"relative py-4 max-sm:order-1 max-sm:border-t sm:w-32\"><div class=\"h-full sm:border-e\"><div class=\"flex flex-col px-2\"><Button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" on-click=\"${() => {\n                    setDate({\n                      from: today,\n                      to: today,\n                    })\n                    setMonth(today)\n                  }}\">Today\n                </Button><Button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" on-click=\"${() => {\n                    setDate(yesterday)\n                    setMonth(yesterday.to)\n                  }}\">Yesterday\n                </Button><Button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" on-click=\"${() => {\n                    setDate(last7Days)\n                    setMonth(last7Days.to)\n                  }}\">Last 7 days\n                </Button><Button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" on-click=\"${() => {\n                    setDate(last30Days)\n                    setMonth(last30Days.to)\n                  }}\">Last 30 days\n                </Button><Button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" on-click=\"${() => {\n                    setDate(monthToDate)\n                    setMonth(monthToDate.to)\n                  }}\">Month to date\n                </Button><Button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" on-click=\"${() => {\n                    setDate(lastMonth)\n                    setMonth(lastMonth.to)\n                  }}\">Last month\n                </Button><Button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" on-click=\"${() => {\n                    setDate(yearToDate)\n                    setMonth(yearToDate.to)\n                  }}\">Year to date\n                </Button><Button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" on-click=\"${() => {\n                    setDate(lastYear)\n                    setMonth(lastYear.to)\n                  }}\">Last year\n                </Button></div></div></div><Calendar mode=\"range\" selected=\"${date}\" onSelect=\"${(newDate: CalendarSelectedValue) => {\n              if (newDate) {\n                setDate(newDate as CalendarRangeValue)\n              }\n            }}\" month=\"${month}\" onmonthchange=\"${setMonth}\" class=\"p-2\" disabled=\"${[\n              { after: today }, // Dates before today\n            ]}\" /></div></div><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Range calendar with presets -${' '}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-21.wxml",
          "target": "components/ui/calendar-date-picker-21/calendar-date-picker-21.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><view class=\"rounded-md border\"><view class=\"flex max-sm:flex-col\"><view class=\"relative py-4 max-sm:order-1 max-sm:border-t sm:w-32\"><view class=\"h-full sm:border-e\"><view class=\"flex flex-col px-2\"><button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" bindtap=\"{\n                    setDate({\n                      from: today,\n                      to: today,\n                    })\n                    setMonth(today)\n                  }\">Today\n                </button><button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" bindtap=\"{\n                    setDate(yesterday)\n                    setMonth(yesterday.to)\n                  }\">Yesterday\n                </button><button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" bindtap=\"{\n                    setDate(last7Days)\n                    setMonth(last7Days.to)\n                  }\">Last 7 days\n                </button><button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" bindtap=\"{\n                    setDate(last30Days)\n                    setMonth(last30Days.to)\n                  }\">Last 30 days\n                </button><button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" bindtap=\"{\n                    setDate(monthToDate)\n                    setMonth(monthToDate.to)\n                  }\">Month to date\n                </button><button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" bindtap=\"{\n                    setDate(lastMonth)\n                    setMonth(lastMonth.to)\n                  }\">Last month\n                </button><button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" bindtap=\"{\n                    setDate(yearToDate)\n                    setMonth(yearToDate.to)\n                  }\">Year to date\n                </button><button variant=\"ghost\" size=\"sm\" class=\"w-full justify-start\" bindtap=\"{\n                    setDate(lastYear)\n                    setMonth(lastYear.to)\n                  }\">Last year\n                </button></view></view></view><calendar mode=\"range\" selected=\"{{date}}\" bindchange=\"{\n              if (newDate) {\n                setDate(newDate as CalendarRangeValue)\n              }\n            }\" month=\"{{month}}\" onmonthchange=\"{{setMonth}}\" class=\"p-2\" disabled=\"{{[\n              { after: today }, // Dates before today\n            ]}}\" /></view></view><text class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Range calendar with presets -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "calendar",
          "range calendar",
          "date",
          "button",
          "react daypicker"
        ],
        "colSpan": 3,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "calendar-date-picker-21",
          "group": "calendar-date-picker",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-21",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-21.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-21",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-21.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-21",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-21.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-21",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-21.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react",
              "date-fns"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue",
              "date-fns"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "calendar",
        "title": "Calendar Date Picker · Disabled State"
      },
      "dependencies": [
        "@timui/react",
        "date-fns"
      ],
      "categories": [
        "calendar"
      ]
    },
    {
      "name": "calendar-date-picker-22",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/calendar.json"
      ],
      "files": [
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-22.tsx",
          "type": "registry:component",
          "target": "components/ui/calendar-date-picker-22.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Calendar } from '@timui/react'\nimport { addDays } from 'date-fns'\n\ntype CalendarRangeValue = { from: Date | undefined; to?: Date }\ntype CalendarSelectedValue = Date | Date[] | CalendarRangeValue | undefined\n\nexport default function Component() {\n  const today = new Date()\n  const [date, setDate] = useState<CalendarRangeValue | undefined>({\n    from: today,\n    to: addDays(today, 25),\n  })\n\n  return (\n    <div>\n      <Calendar\n        mode=\"range\"\n        selected={date}\n        onSelect={(next: CalendarSelectedValue) => setDate(next as CalendarRangeValue | undefined)}\n        numberOfMonths={2}\n        pagedNavigation\n        showOutsideDays={false}\n        className=\"rounded-md border p-2\"\n        classNames={{\n          months: 'gap-8',\n          month:\n            'relative first-of-type:before:hidden before:absolute max-sm:before:inset-x-2 max-sm:before:h-px max-sm:before:-top-2 sm:before:inset-y-2 sm:before:w-px before:bg-border sm:before:-left-4',\n        }}\n      />\n      <p\n        className=\"text-muted-foreground mt-4 text-center text-xs\"\n        role=\"region\"\n        aria-live=\"polite\"\n      >\n        Two months calendar -{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://daypicker.dev/\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React DayPicker\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-22.vue",
          "target": "components/ui/calendar-date-picker-22.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Calendar } from '@timui/vue';\nimport { addDays } from 'date-fns';\n\n\nconst date = ref<CalendarRangeValue | undefined>({\n    from: today,\n    to: addDays(today, 25),\n  });\n\n\nfunction setDate(next: typeof date.value | ((prev: typeof date.value) => typeof date.value)) {\n  date.value = typeof next === 'function'\n    ? (next as (prev: typeof date.value) => typeof date.value)(date.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <div><Calendar mode=\"range\" :selected=\"date\" @update:modelValue=\"setDate(next as CalendarRangeValue | undefined)\" :numberOfMonths=\"2\" pagedNavigation :showOutsideDays=\"false\" class=\"rounded-md border p-2\" :classNames=\"{\n          months: 'gap-8',\n          month:\n            'relative first-of-type:before:hidden before:absolute max-sm:before:inset-x-2 max-sm:before:h-px max-sm:before:-top-2 sm:before:inset-y-2 sm:before:w-px before:bg-border sm:before:-left-4',\n        }\" /><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Two months calendar -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-22.html",
          "target": "components/ui/calendar-date-picker-22.html",
          "type": "registry:component",
          "content": "<template>\n  <div><Calendar mode=\"range\" selected=\"${date}\" onSelect=\"${(next: CalendarSelectedValue) => setDate(next as CalendarRangeValue | undefined)}\" numberofmonths=\"${2}\" pagednavigation showoutsidedays=\"${false}\" class=\"rounded-md border p-2\" classnames=\"${{\n          months: 'gap-8',\n          month:\n            'relative first-of-type:before:hidden before:absolute max-sm:before:inset-x-2 max-sm:before:h-px max-sm:before:-top-2 sm:before:inset-y-2 sm:before:w-px before:bg-border sm:before:-left-4',\n        }}\" /><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Two months calendar -${' '}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-22.wxml",
          "target": "components/ui/calendar-date-picker-22/calendar-date-picker-22.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><calendar mode=\"range\" selected=\"{{date}}\" bindchange=\"setDate(next as CalendarRangeValue | undefined)\" numberofmonths=\"{{2}}\" pagednavigation showoutsidedays=\"{{false}}\" class=\"rounded-md border p-2\" classnames=\"{{{\n          months: 'gap-8',\n          month:\n            'relative first-of-type:before:hidden before:absolute max-sm:before:inset-x-2 max-sm:before:h-px max-sm:before:-top-2 sm:before:inset-y-2 sm:before:w-px before:bg-border sm:before:-left-4',\n        }}}\" /><text class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Two months calendar -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "calendar",
          "range calendar",
          "date",
          "react daypicker"
        ],
        "colSpan": 3,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "calendar-date-picker-22",
          "group": "calendar-date-picker",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-22",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-22.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-22",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-22.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-22",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-22.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-22",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-22.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react",
              "date-fns"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue",
              "date-fns"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "calendar",
        "title": "Calendar Date Picker · Interactive State"
      },
      "dependencies": [
        "@timui/react",
        "date-fns"
      ],
      "categories": [
        "calendar"
      ]
    },
    {
      "name": "calendar-date-picker-23",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/calendar.json"
      ],
      "files": [
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-23.tsx",
          "type": "registry:component",
          "target": "components/ui/calendar-date-picker-23.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Calendar } from '@timui/react'\nimport { addDays } from 'date-fns'\n\ntype CalendarRangeValue = { from: Date | undefined; to?: Date }\ntype CalendarSelectedValue = Date | Date[] | CalendarRangeValue | undefined\n\nexport default function Component() {\n  const today = new Date()\n  const [date, setDate] = useState<CalendarRangeValue | undefined>({\n    from: today,\n    to: addDays(today, 48),\n  })\n\n  return (\n    <div>\n      <Calendar\n        mode=\"range\"\n        selected={date}\n        onSelect={(next: CalendarSelectedValue) => setDate(next as CalendarRangeValue | undefined)}\n        numberOfMonths={3}\n        pagedNavigation\n        showOutsideDays={false}\n        className=\"rounded-md border p-2\"\n        classNames={{\n          months: 'sm:flex-col md:flex-row gap-8',\n          month:\n            'relative first-of-type:before:hidden before:absolute max-md:before:inset-x-2 max-md:before:h-px max-md:before:-top-4 md:before:inset-y-2 md:before:w-px before:bg-border md:before:-left-4',\n        }}\n      />\n      <p\n        className=\"text-muted-foreground mt-4 text-center text-xs\"\n        role=\"region\"\n        aria-live=\"polite\"\n      >\n        Three months calendar -{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://daypicker.dev/\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React DayPicker\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-23.vue",
          "target": "components/ui/calendar-date-picker-23.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Calendar } from '@timui/vue';\nimport { addDays } from 'date-fns';\n\n\nconst date = ref<CalendarRangeValue | undefined>({\n    from: today,\n    to: addDays(today, 48),\n  });\n\n\nfunction setDate(next: typeof date.value | ((prev: typeof date.value) => typeof date.value)) {\n  date.value = typeof next === 'function'\n    ? (next as (prev: typeof date.value) => typeof date.value)(date.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <div><Calendar mode=\"range\" :selected=\"date\" @update:modelValue=\"setDate(next as CalendarRangeValue | undefined)\" :numberOfMonths=\"3\" pagedNavigation :showOutsideDays=\"false\" class=\"rounded-md border p-2\" :classNames=\"{\n          months: 'sm:flex-col md:flex-row gap-8',\n          month:\n            'relative first-of-type:before:hidden before:absolute max-md:before:inset-x-2 max-md:before:h-px max-md:before:-top-4 md:before:inset-y-2 md:before:w-px before:bg-border md:before:-left-4',\n        }\" /><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Three months calendar -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-23.html",
          "target": "components/ui/calendar-date-picker-23.html",
          "type": "registry:component",
          "content": "<template>\n  <div><Calendar mode=\"range\" selected=\"${date}\" onSelect=\"${(next: CalendarSelectedValue) => setDate(next as CalendarRangeValue | undefined)}\" numberofmonths=\"${3}\" pagednavigation showoutsidedays=\"${false}\" class=\"rounded-md border p-2\" classnames=\"${{\n          months: 'sm:flex-col md:flex-row gap-8',\n          month:\n            'relative first-of-type:before:hidden before:absolute max-md:before:inset-x-2 max-md:before:h-px max-md:before:-top-4 md:before:inset-y-2 md:before:w-px before:bg-border md:before:-left-4',\n        }}\" /><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Three months calendar -${' '}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-23.wxml",
          "target": "components/ui/calendar-date-picker-23/calendar-date-picker-23.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><calendar mode=\"range\" selected=\"{{date}}\" bindchange=\"setDate(next as CalendarRangeValue | undefined)\" numberofmonths=\"{{3}}\" pagednavigation showoutsidedays=\"{{false}}\" class=\"rounded-md border p-2\" classnames=\"{{{\n          months: 'sm:flex-col md:flex-row gap-8',\n          month:\n            'relative first-of-type:before:hidden before:absolute max-md:before:inset-x-2 max-md:before:h-px max-md:before:-top-4 md:before:inset-y-2 md:before:w-px before:bg-border md:before:-left-4',\n        }}}\" /><text class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Three months calendar -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "calendar",
          "range calendar",
          "date",
          "react daypicker"
        ],
        "colSpan": 3,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "calendar-date-picker-23",
          "group": "calendar-date-picker",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-23",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-23.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-23",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-23.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-23",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-23.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-23",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-23.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react",
              "date-fns"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue",
              "date-fns"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "calendar",
        "title": "Calendar Date Picker · Interactive State"
      },
      "dependencies": [
        "@timui/react",
        "date-fns"
      ],
      "categories": [
        "calendar"
      ]
    },
    {
      "name": "calendar-date-picker-24",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/calendar.json"
      ],
      "files": [
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-24.tsx",
          "type": "registry:component",
          "target": "components/ui/calendar-date-picker-24.tsx",
          "content": "'use client'\n\nimport { useEffect, useState } from 'react'\nimport { cn } from '@timui/core'\nimport { Calendar } from '@timui/react'\nimport { format } from 'date-fns'\n\nconst GOOD_PRICE_THRESHOLD = 100\ntype CalendarDayButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {\n  day: { date: Date }\n  modifiers: Record<string, boolean>\n  children?: React.ReactNode\n}\n\nexport default function Component() {\n  const today = new Date()\n  const [date, setDate] = useState<Date | undefined>(today)\n\n  // Mock price data\n  const [mockPriceData, setMockPriceData] = useState<Record<string, number>>({})\n  useEffect(() => {\n    const generateMockPriceData = () => {\n      const data: Record<string, number> = {}\n\n      for (let i = 0; i < 180; i++) {\n        const date = new Date(today)\n        date.setDate(today.getDate() + i)\n        const dateKey = format(date, 'yyyy-MM-dd')\n        const randomPrice = Math.floor(Math.random() * (200 - 80 + 1)) + 80\n        data[dateKey] = randomPrice\n      }\n      return data\n    }\n    setMockPriceData(generateMockPriceData())\n  }, [])\n\n  const isDateDisabled = (date: Date) => {\n    return !mockPriceData[format(date, 'yyyy-MM-dd')]\n  }\n\n  return (\n    <div>\n      <Calendar\n        mode=\"single\"\n        selected={date}\n        onSelect={setDate}\n        numberOfMonths={2}\n        pagedNavigation\n        showOutsideDays={false}\n        className=\"rounded-md border p-2\"\n        classNames={{\n          months: 'sm:flex-col md:flex-row gap-8',\n          month:\n            'relative first-of-type:before:hidden before:absolute max-md:before:inset-x-2 max-md:before:h-px max-md:before:-top-4 md:before:inset-y-2 md:before:w-px before:bg-border md:before:-left-4',\n          weekday: 'w-12',\n          day_button: 'size-12',\n          today: '*:after:hidden',\n        }}\n        components={{\n          DayButton: (props: CalendarDayButtonProps) => (\n            <DayButton {...props} prices={mockPriceData} />\n          ),\n        }}\n        disabled={isDateDisabled}\n      />\n      <p\n        className=\"text-muted-foreground mt-4 text-center text-xs\"\n        role=\"region\"\n        aria-live=\"polite\"\n      >\n        Pricing calendar -{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://daypicker.dev/\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React DayPicker\n        </a>\n      </p>\n    </div>\n  )\n}\n\nfunction DayButton(props: CalendarDayButtonProps & { prices: Record<string, number> }) {\n  const { day, modifiers, prices, ...buttonProps } = props\n  const price = prices[format(day.date, 'yyyy-MM-dd')]\n  const isGoodPrice = price < GOOD_PRICE_THRESHOLD\n\n  return (\n    <button {...buttonProps}>\n      <span className=\"flex flex-col\">\n        {props.children}\n        {price && (\n          <span\n            className={cn(\n              'text-[10px] font-medium',\n              isGoodPrice\n                ? 'text-emerald-500'\n                : 'text-muted-foreground group-data-selected:text-primary-foreground/70'\n            )}\n          >\n            ${price}\n          </span>\n        )}\n      </span>\n    </button>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-24.vue",
          "target": "components/ui/calendar-date-picker-24.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, onMounted, ref } from 'vue'\nimport { Calendar } from '@timui/vue'\nimport { format } from 'date-fns'\n\nconst today = new Date()\nconst date = ref<Date | undefined>(today)\nconst mockPriceData = ref<Record<string, number>>({})\n\nfunction setDate(next: Date | undefined) {\n  date.value = next\n}\n\nonMounted(() => {\n  const data: Record<string, number> = {}\n  for (let i = 0; i < 180; i += 1) {\n    const nextDate = new Date(today)\n    nextDate.setDate(today.getDate() + i)\n    const dateKey = format(nextDate, 'yyyy-MM-dd')\n    data[dateKey] = Math.floor(Math.random() * (200 - 80 + 1)) + 80\n  }\n  mockPriceData.value = data\n})\n\nfunction isDateDisabled(targetDate: Date) {\n  return !mockPriceData.value[format(targetDate, 'yyyy-MM-dd')]\n}\n\nconst selectedPrice = computed(() => {\n  if (!date.value) return undefined\n  return mockPriceData.value[format(date.value, 'yyyy-MM-dd')]\n})\n</script>\n\n<template>\n  <div>\n    <Calendar\n      mode=\"single\"\n      :selected=\"date\"\n      @update:modelValue=\"setDate\"\n      :numberOfMonths=\"2\"\n      pagedNavigation\n      :showOutsideDays=\"false\"\n      class=\"rounded-md border p-2\"\n      :classNames=\"{\n        months: 'sm:flex-col md:flex-row gap-8',\n        month:\n          'relative first-of-type:before:hidden before:absolute max-md:before:inset-x-2 max-md:before:h-px max-md:before:-top-4 md:before:inset-y-2 md:before:w-px before:bg-border md:before:-left-4',\n        weekday: 'w-12',\n        day_button: 'size-12',\n        today: '*:after:hidden',\n      }\"\n      :disabled=\"isDateDisabled\"\n    />\n\n    <p class=\"text-foreground mt-3 text-center text-sm\" role=\"status\" aria-live=\"polite\">\n      <template v-if=\"date && selectedPrice\">\n        {{ format(date, 'yyyy-MM-dd') }} · ${{ selectedPrice }}\n      </template>\n      <template v-else>No price selected</template>\n    </p>\n\n    <p class=\"text-muted-foreground mt-2 text-center text-xs\" role=\"region\" aria-live=\"polite\">\n      Pricing calendar -\n      <a\n        class=\"hover:text-foreground underline\"\n        href=\"https://daypicker.dev/\"\n        target=\"_blank\"\n        rel=\"noopener nofollow\"\n      >\n        React DayPicker\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-24.html",
          "target": "components/ui/calendar-date-picker-24.html",
          "type": "registry:component",
          "content": "<template>\n  <div><Calendar mode=\"single\" selected=\"${date}\" onSelect=\"${setDate}\" numberofmonths=\"${2}\" pagednavigation showoutsidedays=\"${false}\" class=\"rounded-md border p-2\" classnames=\"${{\n          months: 'sm:flex-col md:flex-row gap-8',\n          month:\n            'relative first-of-type:before:hidden before:absolute max-md:before:inset-x-2 max-md:before:h-px max-md:before:-top-4 md:before:inset-y-2 md:before:w-px before:bg-border md:before:-left-4',\n          weekday: 'w-12',\n          day_button: 'size-12',\n          today: '*:after:hidden',\n        }}\" components=\"${{\n          DayButton: (props: CalendarDayButtonProps) => (\n            <DayButton {...props} prices={mockPriceData} />\n          ),\n        }}\" disabled=\"${isDateDisabled}\" /><p class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Pricing calendar -${' '}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-24.wxml",
          "target": "components/ui/calendar-date-picker-24/calendar-date-picker-24.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><calendar mode=\"single\" selected=\"{{date}}\" bindchange=\"setDate\" numberofmonths=\"{{2}}\" pagednavigation showoutsidedays=\"{{false}}\" class=\"rounded-md border p-2\" classnames=\"{{{\n          months: 'sm:flex-col md:flex-row gap-8',\n          month:\n            'relative first-of-type:before:hidden before:absolute max-md:before:inset-x-2 max-md:before:h-px max-md:before:-top-4 md:before:inset-y-2 md:before:w-px before:bg-border md:before:-left-4',\n          weekday: 'w-12',\n          day_button: 'size-12',\n          today: '*:after:hidden',\n        }}}\" components=\"{{{\n          DayButton: (props: CalendarDayButtonProps) => (\n            <DayButton {...props} prices={mockPriceData} />\n          ),\n        }}}\" disabled=\"{{isDateDisabled}}\" /><text class=\"text-muted-foreground mt-4 text-center text-xs\" role=\"region\" aria-live=\"polite\">Pricing calendar -{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "calendar",
          "date",
          "react daypicker"
        ],
        "colSpan": 3,
        "style": 1,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "calendar-date-picker-24",
          "group": "calendar-date-picker",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-24",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-24.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-24",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-24.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-24",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-24.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-24",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-24.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@timui/react",
              "date-fns"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue",
              "date-fns"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "calendar",
        "title": "Calendar Date Picker · Disabled State"
      },
      "dependencies": [
        "@timui/core",
        "@timui/react",
        "date-fns"
      ],
      "categories": [
        "calendar"
      ]
    },
    {
      "name": "calendar-date-picker-27",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/calendar.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/popover.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-27.tsx",
          "type": "registry:component",
          "target": "components/ui/calendar-date-picker-27.tsx",
          "content": "'use client'\n\nimport { useId, useState } from 'react'\nimport { cn } from '@timui/core'\nimport { Button, Calendar, Label, Popover, PopoverContent, PopoverTrigger } from '@timui/react'\nimport { format } from 'date-fns'\nimport { CalendarIcon } from 'lucide-react'\n\nexport default function Component() {\n  const id = useId()\n  const [date, setDate] = useState<Date | undefined>()\n\n  return (\n    <div>\n      <div className=\"*:not-first:mt-2\">\n        <Label htmlFor={id}>Date picker</Label>\n        <Popover ids={{ trigger: id }}>\n          <PopoverTrigger asChild>\n            <Button\n              id={id}\n              variant={'outline'}\n              className=\"group bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]\"\n            >\n              <span className={cn('truncate', !date && 'text-muted-foreground')}>\n                {date ? format(date, 'PPP') : 'Pick a date'}\n              </span>\n              <CalendarIcon\n                size={16}\n                className=\"text-muted-foreground/80 group-hover:text-foreground shrink-0 transition-colors\"\n                aria-hidden=\"true\"\n              />\n            </Button>\n          </PopoverTrigger>\n          <PopoverContent className=\"w-auto p-2\" align=\"start\">\n            <Calendar mode=\"single\" selected={date} onSelect={setDate} />\n          </PopoverContent>\n        </Popover>\n      </div>\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Built with{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://daypicker.dev/\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React DayPicker\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-27.vue",
          "target": "components/ui/calendar-date-picker-27.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { cn } from '@timui/core';\nimport { CalendarIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { Calendar } from '@timui/vue';\nimport { Label } from '@timui/vue';\nimport { Popover, PopoverContent, PopoverTrigger } from '@timui/vue';\nimport { format } from 'date-fns';\n\n\nconst date = ref<Date | undefined>(undefined);\n\n\nconst id = 'calendar-date-picker-27';\n\n\nfunction setDate(next: typeof date.value | ((prev: typeof date.value) => typeof date.value)) {\n  date.value = typeof next === 'function'\n    ? (next as (prev: typeof date.value) => typeof date.value)(date.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <div><div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Date picker</Label><Popover :ids=\"{ trigger: id }\"><PopoverTrigger as-child><Button :id=\"id\" :variant=\"'outline'\" class=\"group bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]\"><span :class=\"cn('truncate', !date && 'text-muted-foreground')\"><template v-if=\"date\">\n{{ format(date, 'PPP') }}\n</template>\n<template v-else>\n{{ 'Pick a date' }}\n</template></span><CalendarIcon :size=\"16\" class=\"text-muted-foreground/80 group-hover:text-foreground shrink-0 transition-colors\" aria-hidden=\"true\" /></Button></PopoverTrigger><PopoverContent class=\"w-auto p-2\" align=\"start\"><Calendar mode=\"single\" :selected=\"date\" @update:modelValue=\"setDate\" /></PopoverContent></Popover></div><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-27.html",
          "target": "components/ui/calendar-date-picker-27.html",
          "type": "registry:component",
          "content": "<template>\n  <div><div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Date picker</Label><Popover ids=\"${{ trigger: id }}\"><PopoverTrigger aschild><Button id=\"${id}\" variant=\"${'outline'}\" class=\"group bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]\"><span class=\"${cn('truncate', !date && 'text-muted-foreground')}\"><!-- if date -->\n${format(date, 'PPP')}\n<!-- else -->\n${'Pick a date'}\n<!-- endif --></span><CalendarIcon size=\"${16}\" class=\"text-muted-foreground/80 group-hover:text-foreground shrink-0 transition-colors\" aria-hidden=\"true\" /></Button></PopoverTrigger><PopoverContent class=\"w-auto p-2\" align=\"start\"><Calendar mode=\"single\" selected=\"${date}\" onSelect=\"${setDate}\" /></PopoverContent></Popover></div><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with${' '}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-27.wxml",
          "target": "components/ui/calendar-date-picker-27/calendar-date-picker-27.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Date picker</label><popover ids=\"{{{ trigger: id }}}\"><popovertrigger aschild><button id=\"{{id}}\" variant=\"{{'outline'}}\" class=\"group bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]\"><text class=\"{{cn('truncate', !date && 'text-muted-foreground')}}\"><block wx:if=\"{{date}}\">\n{{ format(date, 'PPP') }}\n</block>\n<block wx:else>\n{{ 'Pick a date' }}\n</block></text><calendaricon size=\"{{16}}\" class=\"text-muted-foreground/80 group-hover:text-foreground shrink-0 transition-colors\" aria-hidden=\"true\" /></button></popovertrigger><popovercontent class=\"w-auto p-2\" align=\"start\"><calendar mode=\"single\" selected=\"{{date}}\" bindchange=\"setDate\" /></popovercontent></popover></view><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "calendar",
          "date",
          "button",
          "picker",
          "react daypicker"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "calendar-date-picker-27",
          "group": "calendar-date-picker",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-27",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-27.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-27",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-27.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-27",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-27.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-27",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-27.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@timui/react",
              "date-fns"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@timui/vue",
              "date-fns"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "date-picker",
        "title": "Calendar Date Picker · Date picker"
      },
      "dependencies": [
        "@timui/core",
        "@timui/react",
        "date-fns"
      ],
      "categories": [
        "date-picker"
      ]
    },
    {
      "name": "calendar-date-picker-28",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/calendar.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/popover.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-28.tsx",
          "type": "registry:component",
          "target": "components/ui/calendar-date-picker-28.tsx",
          "content": "'use client'\n\nimport { useId, useState } from 'react'\nimport { cn } from '@timui/core'\nimport { Button, Calendar, Label, Popover, PopoverContent, PopoverTrigger } from '@timui/react'\nimport { format } from 'date-fns'\nimport { CalendarIcon } from 'lucide-react'\n\ntype CalendarRangeValue = { from: Date | undefined; to?: Date }\ntype CalendarSelectedValue = Date | Date[] | CalendarRangeValue | undefined\n\nexport default function Component() {\n  const id = useId()\n  const [date, setDate] = useState<CalendarRangeValue | undefined>()\n\n  return (\n    <div>\n      <div className=\"*:not-first:mt-2\">\n        <Label htmlFor={id}>Date range picker</Label>\n        <Popover ids={{ trigger: id }}>\n          <PopoverTrigger asChild>\n            <Button\n              id={id}\n              variant=\"outline\"\n              className=\"group bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]\"\n            >\n              <span className={cn('truncate', !date && 'text-muted-foreground')}>\n                {date?.from ? (\n                  date.to ? (\n                    <>\n                      {format(date.from, 'LLL dd, y')} - {format(date.to, 'LLL dd, y')}\n                    </>\n                  ) : (\n                    format(date.from, 'LLL dd, y')\n                  )\n                ) : (\n                  'Pick a date range'\n                )}\n              </span>\n              <CalendarIcon\n                size={16}\n                className=\"text-muted-foreground/80 group-hover:text-foreground shrink-0 transition-colors\"\n                aria-hidden=\"true\"\n              />\n            </Button>\n          </PopoverTrigger>\n          <PopoverContent className=\"w-auto p-2\" align=\"start\">\n            <Calendar\n              mode=\"range\"\n              selected={date}\n              onSelect={(next: CalendarSelectedValue) =>\n                setDate(next as CalendarRangeValue | undefined)\n              }\n            />\n          </PopoverContent>\n        </Popover>\n      </div>\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Built with{' '}\n        <a\n          className=\"hover:text-foreground underline\"\n          href=\"https://daypicker.dev/\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n        >\n          React DayPicker\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-28.vue",
          "target": "components/ui/calendar-date-picker-28.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { cn } from '@timui/core';\nimport { CalendarIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { Calendar } from '@timui/vue';\nimport { Label } from '@timui/vue';\nimport { Popover, PopoverContent, PopoverTrigger } from '@timui/vue';\nimport { format } from 'date-fns';\n\ntype CalendarRangeValue = { from?: Date; to?: Date } | undefined\n\nconst date = ref<CalendarRangeValue | undefined>(undefined);\n\n\nfunction setDate(next: typeof date.value | ((prev: typeof date.value) => typeof date.value)) {\n  date.value = typeof next === 'function'\n    ? (next as (prev: typeof date.value) => typeof date.value)(date.value)\n    : next;\n}\n\n\nconst id = 'calendar-date-picker-28';\n\n</script>\n\n<template>\n  <div><div class=\"*:not-first:mt-2\"><Label :htmlFor=\"id\">Date range picker</Label><Popover :ids=\"{ trigger: id }\"><PopoverTrigger as-child><Button :id=\"id\" variant=\"outline\" class=\"group bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]\"><span :class=\"cn('truncate', !date && 'text-muted-foreground')\"><template v-if=\"date?.from\"><template v-if=\"date?.to\">{{ format(date.from, 'LLL dd, y') }} - {{ format(date.to, 'LLL dd, y') }}</template><template v-else>{{ format(date.from, 'LLL dd, y') }}</template></template><template v-else>\n{{ 'Pick a date range' }}\n</template></span><CalendarIcon :size=\"16\" class=\"text-muted-foreground/80 group-hover:text-foreground shrink-0 transition-colors\" aria-hidden=\"true\" /></Button></PopoverTrigger><PopoverContent class=\"w-auto p-2\" align=\"start\"><Calendar mode=\"range\" :selected=\"date\" @update:modelValue=\"setDate\" /></PopoverContent></Popover></div><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-28.html",
          "target": "components/ui/calendar-date-picker-28.html",
          "type": "registry:component",
          "content": "<template>\n  <div><div class=\"*:not-first:mt-2\"><Label htmlfor=\"${id}\">Date range picker</Label><Popover ids=\"${{ trigger: id }}\"><PopoverTrigger aschild><Button id=\"${id}\" variant=\"outline\" class=\"group bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]\"><span class=\"${cn('truncate', !date && 'text-muted-foreground')}\"><!-- if date?.from -->\n${date.to ? (\n                    <>\n                      {format(date.from, 'LLL dd, y')} - {format(date.to, 'LLL dd, y')}\n                    </>\n                  ) : (\n                    format(date.from, 'LLL dd, y')\n                  )}\n<!-- else -->\n${'Pick a date range'}\n<!-- endif --></span><CalendarIcon size=\"${16}\" class=\"text-muted-foreground/80 group-hover:text-foreground shrink-0 transition-colors\" aria-hidden=\"true\" /></Button></PopoverTrigger><PopoverContent class=\"w-auto p-2\" align=\"start\"><Calendar mode=\"range\" selected=\"${date}\" onSelect=\"${(next: CalendarSelectedValue) =>\n                setDate(next as CalendarRangeValue | undefined)}\" /></PopoverContent></Popover></div><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with${' '}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/calendar-date-picker/calendar-date-picker-28.wxml",
          "target": "components/ui/calendar-date-picker-28/calendar-date-picker-28.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view><view class=\"*:not-first:mt-2\"><label htmlfor=\"{{id}}\">Date range picker</label><popover ids=\"{{{ trigger: id }}}\"><popovertrigger aschild><button id=\"{{id}}\" variant=\"outline\" class=\"group bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]\"><text class=\"{{cn('truncate', !date && 'text-muted-foreground')}}\"><block wx:if=\"{{date?.from}}\">\n{{ date.to ? (\n                    <>\n                      {format(date.from, 'LLL dd, y')} - {format(date.to, 'LLL dd, y')}\n                    </>\n                  ) : (\n                    format(date.from, 'LLL dd, y')\n                  ) }}\n</block>\n<block wx:else>\n{{ 'Pick a date range' }}\n</block></text><calendaricon size=\"{{16}}\" class=\"text-muted-foreground/80 group-hover:text-foreground shrink-0 transition-colors\" aria-hidden=\"true\" /></button></popovertrigger><popovercontent class=\"w-auto p-2\" align=\"start\"><calendar mode=\"range\" selected=\"{{date}}\" bindchange=\"setDate(next as CalendarRangeValue | undefined)\" /></popovercontent></popover></view><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Built with{{ ' ' }}<a class=\"hover:text-foreground underline\" href=\"https://daypicker.dev/\" target=\"_blank\" rel=\"noopener nofollow\">React DayPicker\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "calendar",
          "date",
          "button",
          "picker",
          "react daypicker"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "calendar-date-picker-28",
          "group": "calendar-date-picker",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-28",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-28.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-28",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-28.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-28",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-28.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "calendar-date-picker-28",
              "path": "registry/default/components/calendar-date-picker/calendar-date-picker-28.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@timui/react",
              "date-fns"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@timui/vue",
              "date-fns"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "date-picker",
        "title": "Calendar Date Picker · Date range picker"
      },
      "dependencies": [
        "@timui/core",
        "@timui/react",
        "date-fns"
      ],
      "categories": [
        "date-picker"
      ]
    },
    {
      "name": "stepper-01",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/stepper.json"
      ],
      "files": [
        {
          "path": "registry/default/components/stepper/stepper-01.tsx",
          "type": "registry:component",
          "target": "components/ui/stepper-01.tsx",
          "content": "import {\n  Stepper,\n  StepperIndicator,\n  StepperItem,\n  StepperSeparator,\n  StepperTrigger,\n} from '@timui/react'\n\nconst steps = [1, 2, 3, 4]\n\nexport default function Component() {\n  return (\n    <div className=\"mx-auto max-w-xl space-y-8 text-center\">\n      <Stepper defaultValue={2}>\n        {steps.map((step) => (\n          <StepperItem key={step} step={step} className=\"not-last:flex-1\">\n            <StepperTrigger>\n              <StepperIndicator asChild>{step}</StepperIndicator>\n            </StepperTrigger>\n            {step < steps.length && <StepperSeparator />}\n          </StepperItem>\n        ))}\n      </Stepper>\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Stepper with numbers only\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-01.vue",
          "target": "components/ui/stepper-01.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Stepper } from '@timui/vue';\nimport { StepperIndicator } from '@timui/vue';\nimport { StepperItem } from '@timui/vue';\nimport { StepperSeparator } from '@timui/vue';\nimport { StepperTrigger } from '@timui/vue';\n\n\n\n\n\nconst steps = [1, 2, 3, 4]\n\n</script>\n\n<template>\n  <div class=\"mx-auto max-w-xl space-y-8 text-center\"><Stepper :default-value=\"2\"><StepperItem v-for=\"(step, index) in steps\" :key=\"step\" :step=\"step\" class=\"not-last:flex-1\"><StepperTrigger><StepperIndicator as-child>{{ step }}</StepperIndicator></StepperTrigger><StepperSeparator v-if=\"step < steps.length\" /></StepperItem></Stepper><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Stepper with numbers only\n      </p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-01.html",
          "target": "components/ui/stepper-01.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"mx-auto max-w-xl space-y-8 text-center\"><Stepper default-value=\"${2}\"><!-- Loop steps -->\n<StepperItem key=\"${step}\" step=\"${step}\" class=\"not-last:flex-1\"><StepperTrigger><StepperIndicator aschild>${step}</StepperIndicator></StepperTrigger><!-- if step < steps.length -->\n<StepperSeparator />\n<!-- endif --></StepperItem>\n<!-- End Loop --></Stepper><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Stepper with numbers only\n      </p></div>\n</template>"
        },
        {
          "path": "registry/default/components/stepper/stepper-01.wxml",
          "target": "components/ui/stepper-01/stepper-01.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"mx-auto max-w-xl space-y-8 text-center\"><stepper default-value=\"{{2}}\"><stepperitem wx:for=\"{{steps}}\" wx:for-item=\"step\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{step}}\" step=\"{{step}}\" class=\"not-last:flex-1\"><steppertrigger><stepperindicator aschild>{{ step }}</stepperindicator></steppertrigger><stepperseparator wx:if=\"{{step < steps.length}}\" /></stepperitem></stepper><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Stepper with numbers only\n      </text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "stepper"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "stepper-01",
          "group": "stepper",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "stepper-01",
              "path": "registry/default/components/stepper/stepper-01.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "stepper-01",
              "path": "registry/default/components/stepper/stepper-01.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "stepper-01",
              "path": "registry/default/components/stepper/stepper-01.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "stepper-01",
              "path": "registry/default/components/stepper/stepper-01.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "stepper",
        "title": "Stepper · Numeric indicators"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "stepper"
      ]
    },
    {
      "name": "stepper-02",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/stepper.json"
      ],
      "files": [
        {
          "path": "registry/default/components/stepper/stepper-02.tsx",
          "type": "registry:component",
          "target": "components/ui/stepper-02.tsx",
          "content": "import {\n  Stepper,\n  StepperIndicator,\n  StepperItem,\n  StepperSeparator,\n  StepperTrigger,\n} from '@timui/react'\n\nconst steps = [1, 2, 3, 4]\n\nexport default function Component() {\n  return (\n    <div className=\"mx-auto max-w-xl space-y-8 text-center\">\n      <Stepper defaultValue={2}>\n        {steps.map((step) => (\n          <StepperItem key={step} step={step} className=\"not-last:flex-1\">\n            <StepperTrigger>\n              <StepperIndicator />\n            </StepperTrigger>\n            {step < steps.length && <StepperSeparator />}\n          </StepperItem>\n        ))}\n      </Stepper>\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Stepper with numbers and checkmarks\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-02.vue",
          "target": "components/ui/stepper-02.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Stepper } from '@timui/vue';\nimport { StepperIndicator } from '@timui/vue';\nimport { StepperItem } from '@timui/vue';\nimport { StepperSeparator } from '@timui/vue';\nimport { StepperTrigger } from '@timui/vue';\n\n\n\n\n\nconst steps = [1, 2, 3, 4]\n\n</script>\n\n<template>\n  <div class=\"mx-auto max-w-xl space-y-8 text-center\"><Stepper :default-value=\"2\"><StepperItem v-for=\"(step, index) in steps\" :key=\"step\" :step=\"step\" class=\"not-last:flex-1\"><StepperTrigger><StepperIndicator /></StepperTrigger><StepperSeparator v-if=\"step < steps.length\" /></StepperItem></Stepper><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Stepper with numbers and checkmarks\n      </p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-02.html",
          "target": "components/ui/stepper-02.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"mx-auto max-w-xl space-y-8 text-center\"><Stepper default-value=\"${2}\"><!-- Loop steps -->\n<StepperItem key=\"${step}\" step=\"${step}\" class=\"not-last:flex-1\"><StepperTrigger><StepperIndicator /></StepperTrigger><!-- if step < steps.length -->\n<StepperSeparator />\n<!-- endif --></StepperItem>\n<!-- End Loop --></Stepper><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Stepper with numbers and checkmarks\n      </p></div>\n</template>"
        },
        {
          "path": "registry/default/components/stepper/stepper-02.wxml",
          "target": "components/ui/stepper-02/stepper-02.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"mx-auto max-w-xl space-y-8 text-center\"><stepper default-value=\"{{2}}\"><stepperitem wx:for=\"{{steps}}\" wx:for-item=\"step\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{step}}\" step=\"{{step}}\" class=\"not-last:flex-1\"><steppertrigger><stepperindicator /></steppertrigger><stepperseparator wx:if=\"{{step < steps.length}}\" /></stepperitem></stepper><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Stepper with numbers and checkmarks\n      </text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "stepper"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "stepper-02",
          "group": "stepper",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "stepper-02",
              "path": "registry/default/components/stepper/stepper-02.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "stepper-02",
              "path": "registry/default/components/stepper/stepper-02.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "stepper-02",
              "path": "registry/default/components/stepper/stepper-02.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "stepper-02",
              "path": "registry/default/components/stepper/stepper-02.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "stepper",
        "title": "Stepper · Dot indicators"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "stepper"
      ]
    },
    {
      "name": "stepper-03",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/stepper.json"
      ],
      "files": [
        {
          "path": "registry/default/components/stepper/stepper-03.tsx",
          "type": "registry:component",
          "target": "components/ui/stepper-03.tsx",
          "content": "import {\n  Stepper,\n  StepperIndicator,\n  StepperItem,\n  StepperSeparator,\n  StepperTrigger,\n} from '@timui/react'\n\nconst steps = [1, 2, 3, 4]\n\nexport default function Component() {\n  return (\n    <div className=\"mx-auto max-w-xl space-y-8 text-center\">\n      <Stepper defaultValue={2}>\n        {steps.map((step) => (\n          <StepperItem key={step} step={step} className=\"not-last:flex-1\">\n            <StepperTrigger>\n              <StepperIndicator className=\"data-[state=active]:border-primary size-4 data-[state=active]:border-2 data-[state=active]:bg-transparent [&_span]:sr-only [&_svg]:size-3\" />\n            </StepperTrigger>\n            {step < steps.length && <StepperSeparator />}\n          </StepperItem>\n        ))}\n      </Stepper>\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Stepper with tiny buttons and checkmarks\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-03.vue",
          "target": "components/ui/stepper-03.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Stepper } from '@timui/vue';\nimport { StepperIndicator } from '@timui/vue';\nimport { StepperItem } from '@timui/vue';\nimport { StepperSeparator } from '@timui/vue';\nimport { StepperTrigger } from '@timui/vue';\n\n\n\n\n\nconst steps = [1, 2, 3, 4]\n\n</script>\n\n<template>\n  <div class=\"mx-auto max-w-xl space-y-8 text-center\"><Stepper :default-value=\"2\"><StepperItem v-for=\"(step, index) in steps\" :key=\"step\" :step=\"step\" class=\"not-last:flex-1\"><StepperTrigger><StepperIndicator class=\"data-[state=active]:border-primary size-4 data-[state=active]:border-2 data-[state=active]:bg-transparent [&_span]:sr-only [&_svg]:size-3\" /></StepperTrigger><StepperSeparator v-if=\"step < steps.length\" /></StepperItem></Stepper><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Stepper with tiny buttons and checkmarks\n      </p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-03.html",
          "target": "components/ui/stepper-03.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"mx-auto max-w-xl space-y-8 text-center\"><Stepper default-value=\"${2}\"><!-- Loop steps -->\n<StepperItem key=\"${step}\" step=\"${step}\" class=\"not-last:flex-1\"><StepperTrigger><StepperIndicator class=\"data-[state=active]:border-primary size-4 data-[state=active]:border-2 data-[state=active]:bg-transparent [&_span]:sr-only [&_svg]:size-3\" /></StepperTrigger><!-- if step < steps.length -->\n<StepperSeparator />\n<!-- endif --></StepperItem>\n<!-- End Loop --></Stepper><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Stepper with tiny buttons and checkmarks\n      </p></div>\n</template>"
        },
        {
          "path": "registry/default/components/stepper/stepper-03.wxml",
          "target": "components/ui/stepper-03/stepper-03.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"mx-auto max-w-xl space-y-8 text-center\"><stepper default-value=\"{{2}}\"><stepperitem wx:for=\"{{steps}}\" wx:for-item=\"step\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{step}}\" step=\"{{step}}\" class=\"not-last:flex-1\"><steppertrigger><stepperindicator class=\"data-[state=active]:border-primary size-4 data-[state=active]:border-2 data-[state=active]:bg-transparent [&_span]:sr-only [&_svg]:size-3\" /></steppertrigger><stepperseparator wx:if=\"{{step < steps.length}}\" /></stepperitem></stepper><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Stepper with tiny buttons and checkmarks\n      </text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "stepper"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "stepper-03",
          "group": "stepper",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "stepper-03",
              "path": "registry/default/components/stepper/stepper-03.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "stepper-03",
              "path": "registry/default/components/stepper/stepper-03.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "stepper-03",
              "path": "registry/default/components/stepper/stepper-03.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "stepper-03",
              "path": "registry/default/components/stepper/stepper-03.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "stepper",
        "title": "Stepper · Interactive State"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "stepper"
      ]
    },
    {
      "name": "stepper-04",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/stepper.json"
      ],
      "files": [
        {
          "path": "registry/default/components/stepper/stepper-04.tsx",
          "type": "registry:component",
          "target": "components/ui/stepper-04.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport {\n  Button,\n  Stepper,\n  StepperIndicator,\n  StepperItem,\n  StepperSeparator,\n  StepperTrigger,\n} from '@timui/react'\n\nconst steps = [1, 2, 3, 4]\n\nexport default function Component() {\n  const [currentStep, setCurrentStep] = useState(2)\n\n  return (\n    <div className=\"mx-auto max-w-xl space-y-8 text-center\">\n      <Stepper value={currentStep} onValueChange={setCurrentStep}>\n        {steps.map((step) => (\n          <StepperItem key={step} step={step} className=\"not-last:flex-1\">\n            <StepperTrigger asChild>\n              <StepperIndicator />\n            </StepperTrigger>\n            {step < steps.length && <StepperSeparator />}\n          </StepperItem>\n        ))}\n      </Stepper>\n      <div className=\"flex justify-center space-x-4\">\n        <Button\n          variant=\"outline\"\n          className=\"w-32\"\n          onClick={() => setCurrentStep((prev) => prev - 1)}\n          disabled={currentStep === 1}\n        >\n          Prev step\n        </Button>\n        <Button\n          variant=\"outline\"\n          className=\"w-32\"\n          onClick={() => setCurrentStep((prev) => prev + 1)}\n          disabled={currentStep > steps.length}\n        >\n          Next step\n        </Button>\n      </div>\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Controlled stepper with checkmarks\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-04.vue",
          "target": "components/ui/stepper-04.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Button } from '@timui/vue';\nimport { Stepper } from '@timui/vue';\nimport { StepperIndicator } from '@timui/vue';\nimport { StepperItem } from '@timui/vue';\nimport { StepperSeparator } from '@timui/vue';\nimport { StepperTrigger } from '@timui/vue';\n\n\n\nconst currentStep = ref(2);\n\n\nfunction setCurrentStep(next: typeof currentStep.value | ((prev: typeof currentStep.value) => typeof currentStep.value)) {\n  currentStep.value = typeof next === 'function'\n    ? (next as (prev: typeof currentStep.value) => typeof currentStep.value)(currentStep.value)\n    : next;\n}\n\n\nconst steps = [1, 2, 3, 4]\n\n</script>\n\n<template>\n  <div class=\"mx-auto max-w-xl space-y-8 text-center\"><Stepper :value=\"currentStep\" @update:modelValue=\"setCurrentStep\"><StepperItem v-for=\"(step, index) in steps\" :key=\"step\" :step=\"step\" class=\"not-last:flex-1\"><StepperTrigger as-child><StepperIndicator /></StepperTrigger><StepperSeparator v-if=\"step < steps.length\" /></StepperItem></Stepper><div class=\"flex justify-center space-x-4\"><Button variant=\"outline\" class=\"w-32\" @click=\"setCurrentStep((prev) => prev - 1)\" :disabled=\"currentStep === 1\">Prev step\n        </Button><Button variant=\"outline\" class=\"w-32\" @click=\"setCurrentStep((prev) => prev + 1)\" :disabled=\"currentStep > steps.length\">Next step\n        </Button></div><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Controlled stepper with checkmarks\n      </p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-04.html",
          "target": "components/ui/stepper-04.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"mx-auto max-w-xl space-y-8 text-center\"><Stepper value=\"${currentStep}\" on-value-change=\"${setCurrentStep}\"><!-- Loop steps -->\n<StepperItem key=\"${step}\" step=\"${step}\" class=\"not-last:flex-1\"><StepperTrigger aschild><StepperIndicator /></StepperTrigger><!-- if step < steps.length -->\n<StepperSeparator />\n<!-- endif --></StepperItem>\n<!-- End Loop --></Stepper><div class=\"flex justify-center space-x-4\"><Button variant=\"outline\" class=\"w-32\" on-click=\"${() => setCurrentStep((prev) => prev - 1)}\" disabled=\"${currentStep === 1}\">Prev step\n        </Button><Button variant=\"outline\" class=\"w-32\" on-click=\"${() => setCurrentStep((prev) => prev + 1)}\" disabled=\"${currentStep > steps.length}\">Next step\n        </Button></div><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Controlled stepper with checkmarks\n      </p></div>\n</template>"
        },
        {
          "path": "registry/default/components/stepper/stepper-04.wxml",
          "target": "components/ui/stepper-04/stepper-04.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"mx-auto max-w-xl space-y-8 text-center\"><stepper value=\"{{currentStep}}\" bindchange=\"setCurrentStep\"><stepperitem wx:for=\"{{steps}}\" wx:for-item=\"step\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{step}}\" step=\"{{step}}\" class=\"not-last:flex-1\"><steppertrigger aschild><stepperindicator /></steppertrigger><stepperseparator wx:if=\"{{step < steps.length}}\" /></stepperitem></stepper><view class=\"flex justify-center space-x-4\"><button variant=\"outline\" class=\"w-32\" bindtap=\"setCurrentStep((prev) => prev - 1)\" disabled=\"{{currentStep === 1}}\">Prev step\n        </button><button variant=\"outline\" class=\"w-32\" bindtap=\"setCurrentStep((prev) => prev + 1)\" disabled=\"{{currentStep > steps.length}}\">Next step\n        </button></view><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Controlled stepper with checkmarks\n      </text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "stepper"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "stepper-04",
          "group": "stepper",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "stepper-04",
              "path": "registry/default/components/stepper/stepper-04.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "stepper-04",
              "path": "registry/default/components/stepper/stepper-04.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "stepper-04",
              "path": "registry/default/components/stepper/stepper-04.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "stepper-04",
              "path": "registry/default/components/stepper/stepper-04.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "stepper",
        "title": "Stepper · Numeric indicators"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "stepper"
      ]
    },
    {
      "name": "stepper-05",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/stepper.json"
      ],
      "files": [
        {
          "path": "registry/default/components/stepper/stepper-05.tsx",
          "type": "registry:component",
          "target": "components/ui/stepper-05.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport {\n  Button,\n  Stepper,\n  StepperIndicator,\n  StepperItem,\n  StepperSeparator,\n  StepperTrigger,\n} from '@timui/react'\n\nconst steps = [1, 2, 3, 4]\n\nexport default function Component() {\n  const [currentStep, setCurrentStep] = useState(2)\n  const [isLoading, setIsLoading] = useState(false)\n\n  const handleNextStep = () => {\n    setIsLoading(true)\n    setTimeout(() => {\n      setCurrentStep((prev) => prev + 1)\n      setIsLoading(false)\n    }, 1000)\n  }\n\n  return (\n    <div className=\"mx-auto max-w-xl space-y-8 text-center\">\n      <Stepper value={currentStep} onValueChange={setCurrentStep}>\n        {steps.map((step) => (\n          <StepperItem key={step} step={step} className=\"not-last:flex-1\" loading={isLoading}>\n            <StepperTrigger asChild>\n              <StepperIndicator />\n            </StepperTrigger>\n            {step < steps.length && <StepperSeparator />}\n          </StepperItem>\n        ))}\n      </Stepper>\n      <div className=\"flex justify-center space-x-4\">\n        <Button\n          variant=\"outline\"\n          className=\"w-32\"\n          onClick={() => setCurrentStep((prev) => prev - 1)}\n          disabled={currentStep === 1}\n        >\n          Prev step\n        </Button>\n        <Button\n          variant=\"outline\"\n          className=\"w-32\"\n          onClick={handleNextStep}\n          disabled={currentStep > steps.length}\n        >\n          Next step\n        </Button>\n      </div>\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Controlled stepper with checkmarks and loading state\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-05.vue",
          "target": "components/ui/stepper-05.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Button } from '@timui/vue';\nimport { Stepper } from '@timui/vue';\nimport { StepperIndicator } from '@timui/vue';\nimport { StepperItem } from '@timui/vue';\nimport { StepperSeparator } from '@timui/vue';\nimport { StepperTrigger } from '@timui/vue';\n\n\n\nconst currentStep = ref(2);\nconst isLoading = ref(false);\n\n\nfunction setCurrentStep(next: typeof currentStep.value | ((prev: typeof currentStep.value) => typeof currentStep.value)) {\n  currentStep.value = typeof next === 'function'\n    ? (next as (prev: typeof currentStep.value) => typeof currentStep.value)(currentStep.value)\n    : next;\n}\n\n\nconst steps = [1, 2, 3, 4]\n\n</script>\n\n<template>\n  <div class=\"mx-auto max-w-xl space-y-8 text-center\"><Stepper :value=\"currentStep\" @update:modelValue=\"setCurrentStep\"><StepperItem v-for=\"(step, index) in steps\" :key=\"step\" :step=\"step\" class=\"not-last:flex-1\" :loading=\"isLoading\"><StepperTrigger as-child><StepperIndicator /></StepperTrigger><StepperSeparator v-if=\"step < steps.length\" /></StepperItem></Stepper><div class=\"flex justify-center space-x-4\"><Button variant=\"outline\" class=\"w-32\" @click=\"setCurrentStep((prev) => prev - 1)\" :disabled=\"currentStep === 1\">Prev step\n        </Button><Button variant=\"outline\" class=\"w-32\" @click=\"handleNextStep\" :disabled=\"currentStep > steps.length\">Next step\n        </Button></div><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Controlled stepper with checkmarks and loading state\n      </p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-05.html",
          "target": "components/ui/stepper-05.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"mx-auto max-w-xl space-y-8 text-center\"><Stepper value=\"${currentStep}\" on-value-change=\"${setCurrentStep}\"><!-- Loop steps -->\n<StepperItem key=\"${step}\" step=\"${step}\" class=\"not-last:flex-1\" loading=\"${isLoading}\"><StepperTrigger aschild><StepperIndicator /></StepperTrigger><!-- if step < steps.length -->\n<StepperSeparator />\n<!-- endif --></StepperItem>\n<!-- End Loop --></Stepper><div class=\"flex justify-center space-x-4\"><Button variant=\"outline\" class=\"w-32\" on-click=\"${() => setCurrentStep((prev) => prev - 1)}\" disabled=\"${currentStep === 1}\">Prev step\n        </Button><Button variant=\"outline\" class=\"w-32\" on-click=\"${handleNextStep}\" disabled=\"${currentStep > steps.length}\">Next step\n        </Button></div><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Controlled stepper with checkmarks and loading state\n      </p></div>\n</template>"
        },
        {
          "path": "registry/default/components/stepper/stepper-05.wxml",
          "target": "components/ui/stepper-05/stepper-05.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"mx-auto max-w-xl space-y-8 text-center\"><stepper value=\"{{currentStep}}\" bindchange=\"setCurrentStep\"><stepperitem wx:for=\"{{steps}}\" wx:for-item=\"step\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{step}}\" step=\"{{step}}\" class=\"not-last:flex-1\" loading=\"{{isLoading}}\"><steppertrigger aschild><stepperindicator /></steppertrigger><stepperseparator wx:if=\"{{step < steps.length}}\" /></stepperitem></stepper><view class=\"flex justify-center space-x-4\"><button variant=\"outline\" class=\"w-32\" bindtap=\"setCurrentStep((prev) => prev - 1)\" disabled=\"{{currentStep === 1}}\">Prev step\n        </button><button variant=\"outline\" class=\"w-32\" bindtap=\"handleNextStep\" disabled=\"{{currentStep > steps.length}}\">Next step\n        </button></view><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Controlled stepper with checkmarks and loading state\n      </text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "stepper"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "stepper-05",
          "group": "stepper",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "stepper-05",
              "path": "registry/default/components/stepper/stepper-05.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "stepper-05",
              "path": "registry/default/components/stepper/stepper-05.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "stepper-05",
              "path": "registry/default/components/stepper/stepper-05.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "stepper-05",
              "path": "registry/default/components/stepper/stepper-05.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "stepper",
        "title": "Stepper · Numeric indicators"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "stepper"
      ]
    },
    {
      "name": "stepper-06",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/stepper.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/stepper/stepper-06.tsx",
          "type": "registry:component",
          "target": "components/ui/stepper-06.tsx",
          "content": "import {\n  Stepper,\n  StepperIndicator,\n  StepperItem,\n  StepperSeparator,\n  StepperTrigger,\n} from '@timui/react'\nimport { Shuffle } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <div className=\"mx-auto max-w-xl space-y-8 text-center\">\n      <Stepper defaultValue={2}>\n        <StepperItem step={1} className=\"not-last:flex-1\">\n          <StepperTrigger>\n            <StepperIndicator asChild>\n              <img\n                className=\"rounded-full\"\n                src=\"/avatar-40-05.jpg\"\n                width={32}\n                height={32}\n                alt=\"Mike Palmer\"\n              />\n            </StepperIndicator>\n          </StepperTrigger>\n          <StepperSeparator />\n        </StepperItem>\n        <StepperItem step={2} className=\"not-last:flex-1\" loading>\n          <StepperTrigger>\n            <StepperIndicator />\n          </StepperTrigger>\n          <StepperSeparator />\n        </StepperItem>\n        <StepperItem step={3} className=\"not-last:flex-1\">\n          <StepperTrigger>\n            <StepperIndicator asChild>\n              <Shuffle size={14} aria-hidden=\"true\" />\n              <span className=\"sr-only\">Shuffle</span>\n            </StepperIndicator>\n          </StepperTrigger>\n        </StepperItem>\n      </Stepper>\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Stepper with mixed elements\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-06.vue",
          "target": "components/ui/stepper-06.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Shuffle } from 'lucide-vue-next';\nimport { Stepper } from '@timui/vue';\nimport { StepperIndicator } from '@timui/vue';\nimport { StepperItem } from '@timui/vue';\nimport { StepperSeparator } from '@timui/vue';\nimport { StepperTrigger } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"mx-auto max-w-xl space-y-8 text-center\"><Stepper :default-value=\"2\"><StepperItem :step=\"1\" class=\"not-last:flex-1\"><StepperTrigger><StepperIndicator as-child><img class=\"rounded-full\" src=\"/avatar-40-05.jpg\" :width=\"32\" :height=\"32\" alt=\"Mike Palmer\" /></StepperIndicator></StepperTrigger><StepperSeparator /></StepperItem><StepperItem :step=\"2\" class=\"not-last:flex-1\" loading><StepperTrigger><StepperIndicator /></StepperTrigger><StepperSeparator /></StepperItem><StepperItem :step=\"3\" class=\"not-last:flex-1\"><StepperTrigger><StepperIndicator as-child><Shuffle :size=\"14\" aria-hidden=\"true\" /><span class=\"sr-only\">Shuffle</span></StepperIndicator></StepperTrigger></StepperItem></Stepper><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Stepper with mixed elements\n      </p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-06.html",
          "target": "components/ui/stepper-06.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"mx-auto max-w-xl space-y-8 text-center\"><Stepper default-value=\"${2}\"><StepperItem step=\"${1}\" class=\"not-last:flex-1\"><StepperTrigger><StepperIndicator aschild><img class=\"rounded-full\" src=\"/avatar-40-05.jpg\" width=\"${32}\" height=\"${32}\" alt=\"Mike Palmer\" /></StepperIndicator></StepperTrigger><StepperSeparator /></StepperItem><StepperItem step=\"${2}\" class=\"not-last:flex-1\" loading><StepperTrigger><StepperIndicator /></StepperTrigger><StepperSeparator /></StepperItem><StepperItem step=\"${3}\" class=\"not-last:flex-1\"><StepperTrigger><StepperIndicator aschild><Shuffle size=\"${14}\" aria-hidden=\"true\" /><span class=\"sr-only\">Shuffle</span></StepperIndicator></StepperTrigger></StepperItem></Stepper><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Stepper with mixed elements\n      </p></div>\n</template>"
        },
        {
          "path": "registry/default/components/stepper/stepper-06.wxml",
          "target": "components/ui/stepper-06/stepper-06.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"mx-auto max-w-xl space-y-8 text-center\"><stepper default-value=\"{{2}}\"><stepperitem step=\"{{1}}\" class=\"not-last:flex-1\"><steppertrigger><stepperindicator aschild><image class=\"rounded-full\" src=\"/avatar-40-05.jpg\" width=\"{{32}}\" height=\"{{32}}\" alt=\"Mike Palmer\" /></stepperindicator></steppertrigger><stepperseparator /></stepperitem><stepperitem step=\"{{2}}\" class=\"not-last:flex-1\" loading><steppertrigger><stepperindicator /></steppertrigger><stepperseparator /></stepperitem><stepperitem step=\"{{3}}\" class=\"not-last:flex-1\"><steppertrigger><stepperindicator aschild><shuffle size=\"{{14}}\" aria-hidden=\"true\" /><text class=\"sr-only\">Shuffle</text></stepperindicator></steppertrigger></stepperitem></stepper><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Stepper with mixed elements\n      </text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "stepper"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "stepper-06",
          "group": "stepper",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "stepper-06",
              "path": "registry/default/components/stepper/stepper-06.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "stepper-06",
              "path": "registry/default/components/stepper/stepper-06.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "stepper-06",
              "path": "registry/default/components/stepper/stepper-06.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "stepper-06",
              "path": "registry/default/components/stepper/stepper-06.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "stepper",
        "title": "Stepper · Numeric indicators"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "stepper"
      ]
    },
    {
      "name": "stepper-07",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/stepper.json"
      ],
      "files": [
        {
          "path": "registry/default/components/stepper/stepper-07.tsx",
          "type": "registry:component",
          "target": "components/ui/stepper-07.tsx",
          "content": "import { Stepper, StepperIndicator, StepperItem, StepperTitle, StepperTrigger } from '@timui/react'\n\nconst steps = [\n  {\n    step: 1,\n    title: 'Step One',\n  },\n  {\n    step: 2,\n    title: 'Step Two',\n  },\n  {\n    step: 3,\n    title: 'Step Three',\n  },\n  {\n    step: 4,\n    title: 'Step Four',\n  },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"mx-auto max-w-xl space-y-8 text-center\">\n      <Stepper defaultValue={2} className=\"items-start gap-4\">\n        {steps.map(({ step, title }) => (\n          <StepperItem key={step} step={step} className=\"flex-1\">\n            <StepperTrigger className=\"w-full flex-col items-start gap-2 rounded\">\n              <StepperIndicator asChild className=\"bg-border h-1 w-full\">\n                <span className=\"sr-only\">{step}</span>\n              </StepperIndicator>\n              <div className=\"space-y-0.5\">\n                <StepperTitle>{title}</StepperTitle>\n              </div>\n            </StepperTrigger>\n          </StepperItem>\n        ))}\n      </Stepper>\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Stepper with labels\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-07.vue",
          "target": "components/ui/stepper-07.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Stepper } from '@timui/vue';\nimport { StepperIndicator } from '@timui/vue';\nimport { StepperItem } from '@timui/vue';\nimport { StepperTitle } from '@timui/vue';\nimport { StepperTrigger } from '@timui/vue';\n\n\n\n\n\nconst steps = [\n  {\n    step: 1,\n    title: 'Step One',\n  },\n  {\n    step: 2,\n    title: 'Step Two',\n  },\n  {\n    step: 3,\n    title: 'Step Three',\n  },\n  {\n    step: 4,\n    title: 'Step Four',\n  },\n]\n\n</script>\n\n<template>\n  <div class=\"mx-auto max-w-xl space-y-8 text-center\"><Stepper :default-value=\"2\" class=\"items-start gap-4\"><StepperItem v-for=\"({ step, title }, index) in steps\" :key=\"step\" :step=\"step\" class=\"flex-1\"><StepperTrigger class=\"w-full flex-col items-start gap-2 rounded\"><StepperIndicator as-child class=\"bg-border h-1 w-full\"><span class=\"sr-only\">{{ step }}</span></StepperIndicator><div class=\"space-y-0.5\"><StepperTitle>{{ title }}</StepperTitle></div></StepperTrigger></StepperItem></Stepper><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Stepper with labels\n      </p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-07.html",
          "target": "components/ui/stepper-07.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"mx-auto max-w-xl space-y-8 text-center\"><Stepper default-value=\"${2}\" class=\"items-start gap-4\"><!-- Loop steps -->\n<StepperItem key=\"${step}\" step=\"${step}\" class=\"flex-1\"><StepperTrigger class=\"w-full flex-col items-start gap-2 rounded\"><StepperIndicator aschild class=\"bg-border h-1 w-full\"><span class=\"sr-only\">${step}</span></StepperIndicator><div class=\"space-y-0.5\"><StepperTitle>${title}</StepperTitle></div></StepperTrigger></StepperItem>\n<!-- End Loop --></Stepper><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Stepper with labels\n      </p></div>\n</template>"
        },
        {
          "path": "registry/default/components/stepper/stepper-07.wxml",
          "target": "components/ui/stepper-07/stepper-07.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"mx-auto max-w-xl space-y-8 text-center\"><stepper default-value=\"{{2}}\" class=\"items-start gap-4\"><stepperitem wx:for=\"{{steps}}\" wx:for-item=\"{ step, title }\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{step}}\" step=\"{{step}}\" class=\"flex-1\"><steppertrigger class=\"w-full flex-col items-start gap-2 rounded\"><stepperindicator aschild class=\"bg-border h-1 w-full\"><text class=\"sr-only\">{{ step }}</text></stepperindicator><view class=\"space-y-0.5\"><steppertitle>{{ title }}</steppertitle></view></steppertrigger></stepperitem></stepper><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Stepper with labels\n      </text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "stepper"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "stepper-07",
          "group": "stepper",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "stepper-07",
              "path": "registry/default/components/stepper/stepper-07.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "stepper-07",
              "path": "registry/default/components/stepper/stepper-07.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "stepper-07",
              "path": "registry/default/components/stepper/stepper-07.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "stepper-07",
              "path": "registry/default/components/stepper/stepper-07.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "stepper",
        "title": "Stepper · With step titles"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "stepper"
      ]
    },
    {
      "name": "stepper-08",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/stepper.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/stepper/stepper-08.tsx",
          "type": "registry:component",
          "target": "components/ui/stepper-08.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Button, Stepper, StepperIndicator, StepperItem, StepperTrigger } from '@timui/react'\nimport { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react'\n\nconst steps = [1, 2, 3, 4]\n\nexport default function Component() {\n  const [currentStep, setCurrentStep] = useState(2)\n\n  return (\n    <div className=\"mx-auto max-w-xl space-y-8 text-center\">\n      <div className=\"flex items-center gap-2\">\n        <Button\n          className=\"shrink-0\"\n          variant=\"ghost\"\n          size=\"icon\"\n          onClick={() => setCurrentStep((prev) => prev - 1)}\n          disabled={currentStep === 1}\n          aria-label=\"Prev step\"\n        >\n          <ChevronLeftIcon size={16} aria-hidden=\"true\" />\n        </Button>\n        <Stepper value={currentStep} onValueChange={setCurrentStep} className=\"gap-1\">\n          {steps.map((step) => (\n            <StepperItem key={step} step={step} className=\"flex-1\">\n              <StepperTrigger className=\"w-full flex-col items-start gap-2\" asChild>\n                <StepperIndicator asChild className=\"bg-border h-1 w-full\">\n                  <span className=\"sr-only\">{step}</span>\n                </StepperIndicator>\n              </StepperTrigger>\n            </StepperItem>\n          ))}\n        </Stepper>\n        <Button\n          className=\"shrink-0\"\n          variant=\"ghost\"\n          size=\"icon\"\n          onClick={() => setCurrentStep((prev) => prev + 1)}\n          disabled={currentStep === steps.length}\n          aria-label=\"Next step\"\n        >\n          <ChevronRightIcon size={16} aria-hidden=\"true\" />\n        </Button>\n      </div>\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Paginated stepper\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-08.vue",
          "target": "components/ui/stepper-08.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { ChevronLeftIcon, ChevronRightIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { Stepper } from '@timui/vue';\nimport { StepperIndicator } from '@timui/vue';\nimport { StepperItem } from '@timui/vue';\nimport { StepperTrigger } from '@timui/vue';\n\n\n\nconst currentStep = ref(2);\n\n\nfunction setCurrentStep(next: typeof currentStep.value | ((prev: typeof currentStep.value) => typeof currentStep.value)) {\n  currentStep.value = typeof next === 'function'\n    ? (next as (prev: typeof currentStep.value) => typeof currentStep.value)(currentStep.value)\n    : next;\n}\n\n\nconst steps = [1, 2, 3, 4]\n\n</script>\n\n<template>\n  <div class=\"mx-auto max-w-xl space-y-8 text-center\"><div class=\"flex items-center gap-2\"><Button class=\"shrink-0\" variant=\"ghost\" size=\"icon\" @click=\"setCurrentStep((prev) => prev - 1)\" :disabled=\"currentStep === 1\" aria-label=\"Prev step\"><ChevronLeftIcon :size=\"16\" aria-hidden=\"true\" /></Button><Stepper :value=\"currentStep\" @update:modelValue=\"setCurrentStep\" class=\"gap-1\"><StepperItem v-for=\"(step, index) in steps\" :key=\"step\" :step=\"step\" class=\"flex-1\"><StepperTrigger class=\"w-full flex-col items-start gap-2\" as-child><StepperIndicator as-child class=\"bg-border h-1 w-full\"><span class=\"sr-only\">{{ step }}</span></StepperIndicator></StepperTrigger></StepperItem></Stepper><Button class=\"shrink-0\" variant=\"ghost\" size=\"icon\" @click=\"setCurrentStep((prev) => prev + 1)\" :disabled=\"currentStep === steps.length\" aria-label=\"Next step\"><ChevronRightIcon :size=\"16\" aria-hidden=\"true\" /></Button></div><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Paginated stepper\n      </p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-08.html",
          "target": "components/ui/stepper-08.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"mx-auto max-w-xl space-y-8 text-center\"><div class=\"flex items-center gap-2\"><Button class=\"shrink-0\" variant=\"ghost\" size=\"icon\" on-click=\"${() => setCurrentStep((prev) => prev - 1)}\" disabled=\"${currentStep === 1}\" aria-label=\"Prev step\"><ChevronLeftIcon size=\"${16}\" aria-hidden=\"true\" /></Button><Stepper value=\"${currentStep}\" on-value-change=\"${setCurrentStep}\" class=\"gap-1\"><!-- Loop steps -->\n<StepperItem key=\"${step}\" step=\"${step}\" class=\"flex-1\"><StepperTrigger class=\"w-full flex-col items-start gap-2\" aschild><StepperIndicator aschild class=\"bg-border h-1 w-full\"><span class=\"sr-only\">${step}</span></StepperIndicator></StepperTrigger></StepperItem>\n<!-- End Loop --></Stepper><Button class=\"shrink-0\" variant=\"ghost\" size=\"icon\" on-click=\"${() => setCurrentStep((prev) => prev + 1)}\" disabled=\"${currentStep === steps.length}\" aria-label=\"Next step\"><ChevronRightIcon size=\"${16}\" aria-hidden=\"true\" /></Button></div><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Paginated stepper\n      </p></div>\n</template>"
        },
        {
          "path": "registry/default/components/stepper/stepper-08.wxml",
          "target": "components/ui/stepper-08/stepper-08.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"mx-auto max-w-xl space-y-8 text-center\"><view class=\"flex items-center gap-2\"><button class=\"shrink-0\" variant=\"ghost\" size=\"icon\" bindtap=\"setCurrentStep((prev) => prev - 1)\" disabled=\"{{currentStep === 1}}\" aria-label=\"Prev step\"><chevronlefticon size=\"{{16}}\" aria-hidden=\"true\" /></button><stepper value=\"{{currentStep}}\" bindchange=\"setCurrentStep\" class=\"gap-1\"><stepperitem wx:for=\"{{steps}}\" wx:for-item=\"step\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{step}}\" step=\"{{step}}\" class=\"flex-1\"><steppertrigger class=\"w-full flex-col items-start gap-2\" aschild><stepperindicator aschild class=\"bg-border h-1 w-full\"><text class=\"sr-only\">{{ step }}</text></stepperindicator></steppertrigger></stepperitem></stepper><button class=\"shrink-0\" variant=\"ghost\" size=\"icon\" bindtap=\"setCurrentStep((prev) => prev + 1)\" disabled=\"{{currentStep === steps.length}}\" aria-label=\"Next step\"><chevronrighticon size=\"{{16}}\" aria-hidden=\"true\" /></button></view><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Paginated stepper\n      </text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "stepper"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "stepper-08",
          "group": "stepper",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "stepper-08",
              "path": "registry/default/components/stepper/stepper-08.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "stepper-08",
              "path": "registry/default/components/stepper/stepper-08.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "stepper-08",
              "path": "registry/default/components/stepper/stepper-08.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "stepper-08",
              "path": "registry/default/components/stepper/stepper-08.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "stepper",
        "title": "Stepper · Numeric indicators"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "stepper"
      ]
    },
    {
      "name": "stepper-09",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/stepper.json"
      ],
      "files": [
        {
          "path": "registry/default/components/stepper/stepper-09.tsx",
          "type": "registry:component",
          "target": "components/ui/stepper-09.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Button, Stepper, StepperIndicator, StepperItem, StepperTrigger } from '@timui/react'\n\nconst steps = [1, 2, 3, 4]\n\nexport default function Component() {\n  const [currentStep, setCurrentStep] = useState(1)\n\n  return (\n    <div className=\"mx-auto max-w-xl space-y-8 text-center\">\n      <div className=\"space-y-3\">\n        <Stepper value={currentStep} onValueChange={setCurrentStep}>\n          {steps.map((step) => (\n            <StepperItem key={step} step={step} className=\"flex-1\">\n              <StepperTrigger className=\"w-full flex-col items-start gap-2\" asChild>\n                <StepperIndicator asChild className=\"bg-border h-2 w-full rounded-none\">\n                  <span className=\"sr-only\">{step}</span>\n                </StepperIndicator>\n              </StepperTrigger>\n            </StepperItem>\n          ))}\n        </Stepper>\n        <div className=\"text-muted-foreground text-sm font-medium tabular-nums\">\n          Step {currentStep} of {steps.length}\n        </div>\n      </div>\n      <div className=\"flex justify-center space-x-4\">\n        <Button\n          variant=\"outline\"\n          className=\"w-32\"\n          onClick={() => setCurrentStep((prev) => prev - 1)}\n          disabled={currentStep === 1}\n        >\n          Prev step\n        </Button>\n        <Button\n          variant=\"outline\"\n          className=\"w-32\"\n          onClick={() => setCurrentStep((prev) => prev + 1)}\n          disabled={currentStep >= steps.length}\n        >\n          Next step\n        </Button>\n      </div>\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Progress stepper\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-09.vue",
          "target": "components/ui/stepper-09.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Button } from '@timui/vue';\nimport { Stepper } from '@timui/vue';\nimport { StepperIndicator } from '@timui/vue';\nimport { StepperItem } from '@timui/vue';\nimport { StepperTrigger } from '@timui/vue';\n\n\n\nconst currentStep = ref(1);\n\n\nfunction setCurrentStep(next: typeof currentStep.value | ((prev: typeof currentStep.value) => typeof currentStep.value)) {\n  currentStep.value = typeof next === 'function'\n    ? (next as (prev: typeof currentStep.value) => typeof currentStep.value)(currentStep.value)\n    : next;\n}\n\n\nconst steps = [1, 2, 3, 4]\n\n</script>\n\n<template>\n  <div class=\"mx-auto max-w-xl space-y-8 text-center\"><div class=\"space-y-3\"><Stepper :value=\"currentStep\" @update:modelValue=\"setCurrentStep\"><StepperItem v-for=\"(step, index) in steps\" :key=\"step\" :step=\"step\" class=\"flex-1\"><StepperTrigger class=\"w-full flex-col items-start gap-2\" as-child><StepperIndicator as-child class=\"bg-border h-2 w-full rounded-none\"><span class=\"sr-only\">{{ step }}</span></StepperIndicator></StepperTrigger></StepperItem></Stepper><div class=\"text-muted-foreground text-sm font-medium tabular-nums\">Step {{ currentStep }}of {{ steps.length }}</div></div><div class=\"flex justify-center space-x-4\"><Button variant=\"outline\" class=\"w-32\" @click=\"setCurrentStep((prev) => prev - 1)\" :disabled=\"currentStep === 1\">Prev step\n        </Button><Button variant=\"outline\" class=\"w-32\" @click=\"setCurrentStep((prev) => prev + 1)\" :disabled=\"currentStep >= steps.length\">Next step\n        </Button></div><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Progress stepper\n      </p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-09.html",
          "target": "components/ui/stepper-09.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"mx-auto max-w-xl space-y-8 text-center\"><div class=\"space-y-3\"><Stepper value=\"${currentStep}\" on-value-change=\"${setCurrentStep}\"><!-- Loop steps -->\n<StepperItem key=\"${step}\" step=\"${step}\" class=\"flex-1\"><StepperTrigger class=\"w-full flex-col items-start gap-2\" aschild><StepperIndicator aschild class=\"bg-border h-2 w-full rounded-none\"><span class=\"sr-only\">${step}</span></StepperIndicator></StepperTrigger></StepperItem>\n<!-- End Loop --></Stepper><div class=\"text-muted-foreground text-sm font-medium tabular-nums\">Step ${currentStep}of ${steps.length}</div></div><div class=\"flex justify-center space-x-4\"><Button variant=\"outline\" class=\"w-32\" on-click=\"${() => setCurrentStep((prev) => prev - 1)}\" disabled=\"${currentStep === 1}\">Prev step\n        </Button><Button variant=\"outline\" class=\"w-32\" on-click=\"${() => setCurrentStep((prev) => prev + 1)}\" disabled=\"${currentStep >= steps.length}\">Next step\n        </Button></div><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Progress stepper\n      </p></div>\n</template>"
        },
        {
          "path": "registry/default/components/stepper/stepper-09.wxml",
          "target": "components/ui/stepper-09/stepper-09.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"mx-auto max-w-xl space-y-8 text-center\"><view class=\"space-y-3\"><stepper value=\"{{currentStep}}\" bindchange=\"setCurrentStep\"><stepperitem wx:for=\"{{steps}}\" wx:for-item=\"step\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{step}}\" step=\"{{step}}\" class=\"flex-1\"><steppertrigger class=\"w-full flex-col items-start gap-2\" aschild><stepperindicator aschild class=\"bg-border h-2 w-full rounded-none\"><text class=\"sr-only\">{{ step }}</text></stepperindicator></steppertrigger></stepperitem></stepper><view class=\"text-muted-foreground text-sm font-medium tabular-nums\">Step {{ currentStep }}of {{ steps.length }}</view></view><view class=\"flex justify-center space-x-4\"><button variant=\"outline\" class=\"w-32\" bindtap=\"setCurrentStep((prev) => prev - 1)\" disabled=\"{{currentStep === 1}}\">Prev step\n        </button><button variant=\"outline\" class=\"w-32\" bindtap=\"setCurrentStep((prev) => prev + 1)\" disabled=\"{{currentStep >= steps.length}}\">Next step\n        </button></view><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Progress stepper\n      </text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "stepper"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "stepper-09",
          "group": "stepper",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "stepper-09",
              "path": "registry/default/components/stepper/stepper-09.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "stepper-09",
              "path": "registry/default/components/stepper/stepper-09.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "stepper-09",
              "path": "registry/default/components/stepper/stepper-09.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "stepper-09",
              "path": "registry/default/components/stepper/stepper-09.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "stepper",
        "title": "Stepper · Numeric indicators"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "stepper"
      ]
    },
    {
      "name": "stepper-10",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/stepper.json"
      ],
      "files": [
        {
          "path": "registry/default/components/stepper/stepper-10.tsx",
          "type": "registry:component",
          "target": "components/ui/stepper-10.tsx",
          "content": "import {\n  Stepper,\n  StepperDescription,\n  StepperIndicator,\n  StepperItem,\n  StepperSeparator,\n  StepperTitle,\n  StepperTrigger,\n} from '@timui/react'\n\nconst steps = [\n  {\n    step: 1,\n    title: 'Step One',\n    description: 'Desc for step one',\n  },\n  {\n    step: 2,\n    title: 'Step Two',\n    description: 'Desc for step two',\n  },\n  {\n    step: 3,\n    title: 'Step Three',\n    description: 'Desc for step three',\n  },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"space-y-8 text-center\">\n      <Stepper defaultValue={2}>\n        {steps.map(({ step, title, description }) => (\n          <StepperItem key={step} step={step} className=\"relative flex-1 flex-col!\">\n            <StepperTrigger className=\"flex-col gap-3 rounded\">\n              <StepperIndicator />\n              <div className=\"space-y-0.5 px-2\">\n                <StepperTitle>{title}</StepperTitle>\n                <StepperDescription className=\"max-sm:hidden\">{description}</StepperDescription>\n              </div>\n            </StepperTrigger>\n            {step < steps.length && (\n              <StepperSeparator className=\"absolute inset-x-0 top-3 left-[calc(50%+0.75rem+0.125rem)] -order-1 m-0 -translate-y-1/2 group-data-[orientation=horizontal]/stepper:w-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=horizontal]/stepper:flex-none\" />\n            )}\n          </StepperItem>\n        ))}\n      </Stepper>\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Stepper with titles and descriptions\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-10.vue",
          "target": "components/ui/stepper-10.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Stepper } from '@timui/vue';\nimport { StepperDescription } from '@timui/vue';\nimport { StepperIndicator } from '@timui/vue';\nimport { StepperItem } from '@timui/vue';\nimport { StepperSeparator } from '@timui/vue';\nimport { StepperTitle } from '@timui/vue';\nimport { StepperTrigger } from '@timui/vue';\n\n\n\n\n\nconst steps = [\n  {\n    step: 1,\n    title: 'Step One',\n    description: 'Desc for step one',\n  },\n  {\n    step: 2,\n    title: 'Step Two',\n    description: 'Desc for step two',\n  },\n  {\n    step: 3,\n    title: 'Step Three',\n    description: 'Desc for step three',\n  },\n]\n\n</script>\n\n<template>\n  <div class=\"space-y-8 text-center\"><Stepper :default-value=\"2\"><StepperItem v-for=\"({ step, title, description }, index) in steps\" :key=\"step\" :step=\"step\" class=\"relative flex-1 flex-col!\"><StepperTrigger class=\"flex-col gap-3 rounded\"><StepperIndicator /><div class=\"space-y-0.5 px-2\"><StepperTitle>{{ title }}</StepperTitle><StepperDescription class=\"max-sm:hidden\">{{ description }}</StepperDescription></div></StepperTrigger><StepperSeparator v-if=\"step < steps.length\" class=\"absolute inset-x-0 top-3 left-[calc(50%+0.75rem+0.125rem)] -order-1 m-0 -translate-y-1/2 group-data-[orientation=horizontal]/stepper:w-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=horizontal]/stepper:flex-none\" /></StepperItem></Stepper><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Stepper with titles and descriptions\n      </p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-10.html",
          "target": "components/ui/stepper-10.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-8 text-center\"><Stepper default-value=\"${2}\"><!-- Loop steps -->\n<StepperItem key=\"${step}\" step=\"${step}\" class=\"relative flex-1 flex-col!\"><StepperTrigger class=\"flex-col gap-3 rounded\"><StepperIndicator /><div class=\"space-y-0.5 px-2\"><StepperTitle>${title}</StepperTitle><StepperDescription class=\"max-sm:hidden\">${description}</StepperDescription></div></StepperTrigger><!-- if step < steps.length -->\n<StepperSeparator class=\"absolute inset-x-0 top-3 left-[calc(50%+0.75rem+0.125rem)] -order-1 m-0 -translate-y-1/2 group-data-[orientation=horizontal]/stepper:w-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=horizontal]/stepper:flex-none\" />\n<!-- endif --></StepperItem>\n<!-- End Loop --></Stepper><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Stepper with titles and descriptions\n      </p></div>\n</template>"
        },
        {
          "path": "registry/default/components/stepper/stepper-10.wxml",
          "target": "components/ui/stepper-10/stepper-10.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-8 text-center\"><stepper default-value=\"{{2}}\"><stepperitem wx:for=\"{{steps}}\" wx:for-item=\"{ step, title, description }\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{step}}\" step=\"{{step}}\" class=\"relative flex-1 flex-col!\"><steppertrigger class=\"flex-col gap-3 rounded\"><stepperindicator /><view class=\"space-y-0.5 px-2\"><steppertitle>{{ title }}</steppertitle><stepperdescription class=\"max-sm:hidden\">{{ description }}</stepperdescription></view></steppertrigger><stepperseparator wx:if=\"{{step < steps.length}}\" class=\"absolute inset-x-0 top-3 left-[calc(50%+0.75rem+0.125rem)] -order-1 m-0 -translate-y-1/2 group-data-[orientation=horizontal]/stepper:w-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=horizontal]/stepper:flex-none\" /></stepperitem></stepper><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Stepper with titles and descriptions\n      </text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "stepper"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "stepper-10",
          "group": "stepper",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "stepper-10",
              "path": "registry/default/components/stepper/stepper-10.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "stepper-10",
              "path": "registry/default/components/stepper/stepper-10.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "stepper-10",
              "path": "registry/default/components/stepper/stepper-10.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "stepper-10",
              "path": "registry/default/components/stepper/stepper-10.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "stepper",
        "title": "Stepper · With step titles"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "stepper"
      ]
    },
    {
      "name": "stepper-11",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/stepper.json"
      ],
      "files": [
        {
          "path": "registry/default/components/stepper/stepper-11.tsx",
          "type": "registry:component",
          "target": "components/ui/stepper-11.tsx",
          "content": "import {\n  Stepper,\n  StepperIndicator,\n  StepperItem,\n  StepperSeparator,\n  StepperTitle,\n  StepperTrigger,\n} from '@timui/react'\n\nconst steps = [\n  {\n    step: 1,\n    title: 'Step One',\n  },\n  {\n    step: 2,\n    title: 'Step Two',\n  },\n  {\n    step: 3,\n    title: 'Step Three',\n  },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"space-y-8 text-center\">\n      <Stepper defaultValue={2}>\n        {steps.map(({ step, title }) => (\n          <StepperItem key={step} step={step} className=\"not-last:flex-1 max-md:items-start\">\n            <StepperTrigger className=\"rounded max-md:flex-col\">\n              <StepperIndicator />\n              <div className=\"text-center md:text-left\">\n                <StepperTitle>{title}</StepperTitle>\n              </div>\n            </StepperTrigger>\n            {step < steps.length && <StepperSeparator className=\"max-md:mt-3.5 md:mx-4\" />}\n          </StepperItem>\n        ))}\n      </Stepper>\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Stepper with inline titles\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-11.vue",
          "target": "components/ui/stepper-11.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Stepper } from '@timui/vue';\nimport { StepperIndicator } from '@timui/vue';\nimport { StepperItem } from '@timui/vue';\nimport { StepperSeparator } from '@timui/vue';\nimport { StepperTitle } from '@timui/vue';\nimport { StepperTrigger } from '@timui/vue';\n\n\n\n\n\nconst steps = [\n  {\n    step: 1,\n    title: 'Step One',\n  },\n  {\n    step: 2,\n    title: 'Step Two',\n  },\n  {\n    step: 3,\n    title: 'Step Three',\n  },\n]\n\n</script>\n\n<template>\n  <div class=\"space-y-8 text-center\"><Stepper :default-value=\"2\"><StepperItem v-for=\"({ step, title }, index) in steps\" :key=\"step\" :step=\"step\" class=\"not-last:flex-1 max-md:items-start\"><StepperTrigger class=\"rounded max-md:flex-col\"><StepperIndicator /><div class=\"text-center md:text-left\"><StepperTitle>{{ title }}</StepperTitle></div></StepperTrigger><StepperSeparator v-if=\"step < steps.length\" class=\"max-md:mt-3.5 md:mx-4\" /></StepperItem></Stepper><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Stepper with inline titles\n      </p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-11.html",
          "target": "components/ui/stepper-11.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-8 text-center\"><Stepper default-value=\"${2}\"><!-- Loop steps -->\n<StepperItem key=\"${step}\" step=\"${step}\" class=\"not-last:flex-1 max-md:items-start\"><StepperTrigger class=\"rounded max-md:flex-col\"><StepperIndicator /><div class=\"text-center md:text-left\"><StepperTitle>${title}</StepperTitle></div></StepperTrigger><!-- if step < steps.length -->\n<StepperSeparator class=\"max-md:mt-3.5 md:mx-4\" />\n<!-- endif --></StepperItem>\n<!-- End Loop --></Stepper><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Stepper with inline titles\n      </p></div>\n</template>"
        },
        {
          "path": "registry/default/components/stepper/stepper-11.wxml",
          "target": "components/ui/stepper-11/stepper-11.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-8 text-center\"><stepper default-value=\"{{2}}\"><stepperitem wx:for=\"{{steps}}\" wx:for-item=\"{ step, title }\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{step}}\" step=\"{{step}}\" class=\"not-last:flex-1 max-md:items-start\"><steppertrigger class=\"rounded max-md:flex-col\"><stepperindicator /><view class=\"text-center md:text-left\"><steppertitle>{{ title }}</steppertitle></view></steppertrigger><stepperseparator wx:if=\"{{step < steps.length}}\" class=\"max-md:mt-3.5 md:mx-4\" /></stepperitem></stepper><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Stepper with inline titles\n      </text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "stepper"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "stepper-11",
          "group": "stepper",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "stepper-11",
              "path": "registry/default/components/stepper/stepper-11.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "stepper-11",
              "path": "registry/default/components/stepper/stepper-11.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "stepper-11",
              "path": "registry/default/components/stepper/stepper-11.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "stepper-11",
              "path": "registry/default/components/stepper/stepper-11.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "stepper",
        "title": "Stepper · With step titles"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "stepper"
      ]
    },
    {
      "name": "stepper-12",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/stepper.json"
      ],
      "files": [
        {
          "path": "registry/default/components/stepper/stepper-12.tsx",
          "type": "registry:component",
          "target": "components/ui/stepper-12.tsx",
          "content": "import {\n  Stepper,\n  StepperDescription,\n  StepperIndicator,\n  StepperItem,\n  StepperSeparator,\n  StepperTitle,\n  StepperTrigger,\n} from '@timui/react'\n\nconst steps = [\n  {\n    step: 1,\n    title: 'Step One',\n    description: 'Desc for step one',\n  },\n  {\n    step: 2,\n    title: 'Step Two',\n    description: 'Desc for step two',\n  },\n  {\n    step: 3,\n    title: 'Step Three',\n    description: 'Desc for step three',\n  },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"space-y-8 text-center\">\n      <Stepper defaultValue={2}>\n        {steps.map(({ step, title, description }) => (\n          <StepperItem key={step} step={step} className=\"not-last:flex-1 max-md:items-start\">\n            <StepperTrigger className=\"rounded max-md:flex-col\">\n              <StepperIndicator />\n              <div className=\"text-center md:text-left\">\n                <StepperTitle>{title}</StepperTitle>\n                <StepperDescription className=\"max-sm:hidden\">{description}</StepperDescription>\n              </div>\n            </StepperTrigger>\n            {step < steps.length && <StepperSeparator className=\"max-md:mt-3.5 md:mx-4\" />}\n          </StepperItem>\n        ))}\n      </Stepper>\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Stepper with inline titles and descriptions\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-12.vue",
          "target": "components/ui/stepper-12.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Stepper } from '@timui/vue';\nimport { StepperDescription } from '@timui/vue';\nimport { StepperIndicator } from '@timui/vue';\nimport { StepperItem } from '@timui/vue';\nimport { StepperSeparator } from '@timui/vue';\nimport { StepperTitle } from '@timui/vue';\nimport { StepperTrigger } from '@timui/vue';\n\n\n\n\n\nconst steps = [\n  {\n    step: 1,\n    title: 'Step One',\n    description: 'Desc for step one',\n  },\n  {\n    step: 2,\n    title: 'Step Two',\n    description: 'Desc for step two',\n  },\n  {\n    step: 3,\n    title: 'Step Three',\n    description: 'Desc for step three',\n  },\n]\n\n</script>\n\n<template>\n  <div class=\"space-y-8 text-center\"><Stepper :default-value=\"2\"><StepperItem v-for=\"({ step, title, description }, index) in steps\" :key=\"step\" :step=\"step\" class=\"not-last:flex-1 max-md:items-start\"><StepperTrigger class=\"rounded max-md:flex-col\"><StepperIndicator /><div class=\"text-center md:text-left\"><StepperTitle>{{ title }}</StepperTitle><StepperDescription class=\"max-sm:hidden\">{{ description }}</StepperDescription></div></StepperTrigger><StepperSeparator v-if=\"step < steps.length\" class=\"max-md:mt-3.5 md:mx-4\" /></StepperItem></Stepper><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Stepper with inline titles and descriptions\n      </p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-12.html",
          "target": "components/ui/stepper-12.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-8 text-center\"><Stepper default-value=\"${2}\"><!-- Loop steps -->\n<StepperItem key=\"${step}\" step=\"${step}\" class=\"not-last:flex-1 max-md:items-start\"><StepperTrigger class=\"rounded max-md:flex-col\"><StepperIndicator /><div class=\"text-center md:text-left\"><StepperTitle>${title}</StepperTitle><StepperDescription class=\"max-sm:hidden\">${description}</StepperDescription></div></StepperTrigger><!-- if step < steps.length -->\n<StepperSeparator class=\"max-md:mt-3.5 md:mx-4\" />\n<!-- endif --></StepperItem>\n<!-- End Loop --></Stepper><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Stepper with inline titles and descriptions\n      </p></div>\n</template>"
        },
        {
          "path": "registry/default/components/stepper/stepper-12.wxml",
          "target": "components/ui/stepper-12/stepper-12.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-8 text-center\"><stepper default-value=\"{{2}}\"><stepperitem wx:for=\"{{steps}}\" wx:for-item=\"{ step, title, description }\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{step}}\" step=\"{{step}}\" class=\"not-last:flex-1 max-md:items-start\"><steppertrigger class=\"rounded max-md:flex-col\"><stepperindicator /><view class=\"text-center md:text-left\"><steppertitle>{{ title }}</steppertitle><stepperdescription class=\"max-sm:hidden\">{{ description }}</stepperdescription></view></steppertrigger><stepperseparator wx:if=\"{{step < steps.length}}\" class=\"max-md:mt-3.5 md:mx-4\" /></stepperitem></stepper><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Stepper with inline titles and descriptions\n      </text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "stepper"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "stepper-12",
          "group": "stepper",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "stepper-12",
              "path": "registry/default/components/stepper/stepper-12.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "stepper-12",
              "path": "registry/default/components/stepper/stepper-12.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "stepper-12",
              "path": "registry/default/components/stepper/stepper-12.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "stepper-12",
              "path": "registry/default/components/stepper/stepper-12.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "stepper",
        "title": "Stepper · With step titles"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "stepper"
      ]
    },
    {
      "name": "stepper-13",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/stepper.json"
      ],
      "files": [
        {
          "path": "registry/default/components/stepper/stepper-13.tsx",
          "type": "registry:component",
          "target": "components/ui/stepper-13.tsx",
          "content": "import {\n  Stepper,\n  StepperDescription,\n  StepperIndicator,\n  StepperItem,\n  StepperSeparator,\n  StepperTitle,\n  StepperTrigger,\n} from '@timui/react'\n\nconst steps = [\n  {\n    step: 1,\n    title: 'Step One',\n    description: 'Desc for step one',\n  },\n  {\n    step: 2,\n    title: 'Step Two',\n    description: 'Desc for step two',\n  },\n  {\n    step: 3,\n    title: 'Step Three',\n    description: 'Desc for step three',\n  },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"space-y-8 text-center\">\n      <Stepper defaultValue={2}>\n        {steps.map(({ step, title, description }) => (\n          <StepperItem key={step} step={step} className=\"not-last:flex-1 max-md:items-start\">\n            <StepperTrigger className=\"gap-4 rounded max-md:flex-col\">\n              <StepperIndicator />\n              <div className=\"text-center md:-order-1 md:text-left\">\n                <StepperTitle>{title}</StepperTitle>\n                <StepperDescription className=\"max-sm:hidden\">{description}</StepperDescription>\n              </div>\n            </StepperTrigger>\n            {step < steps.length && <StepperSeparator className=\"max-md:mt-3.5 md:mx-4\" />}\n          </StepperItem>\n        ))}\n      </Stepper>\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Stepper with inline titles and descriptions\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-13.vue",
          "target": "components/ui/stepper-13.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Stepper } from '@timui/vue';\nimport { StepperDescription } from '@timui/vue';\nimport { StepperIndicator } from '@timui/vue';\nimport { StepperItem } from '@timui/vue';\nimport { StepperSeparator } from '@timui/vue';\nimport { StepperTitle } from '@timui/vue';\nimport { StepperTrigger } from '@timui/vue';\n\n\n\n\n\nconst steps = [\n  {\n    step: 1,\n    title: 'Step One',\n    description: 'Desc for step one',\n  },\n  {\n    step: 2,\n    title: 'Step Two',\n    description: 'Desc for step two',\n  },\n  {\n    step: 3,\n    title: 'Step Three',\n    description: 'Desc for step three',\n  },\n]\n\n</script>\n\n<template>\n  <div class=\"space-y-8 text-center\"><Stepper :default-value=\"2\"><StepperItem v-for=\"({ step, title, description }, index) in steps\" :key=\"step\" :step=\"step\" class=\"not-last:flex-1 max-md:items-start\"><StepperTrigger class=\"gap-4 rounded max-md:flex-col\"><StepperIndicator /><div class=\"text-center md:-order-1 md:text-left\"><StepperTitle>{{ title }}</StepperTitle><StepperDescription class=\"max-sm:hidden\">{{ description }}</StepperDescription></div></StepperTrigger><StepperSeparator v-if=\"step < steps.length\" class=\"max-md:mt-3.5 md:mx-4\" /></StepperItem></Stepper><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Stepper with inline titles and descriptions\n      </p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-13.html",
          "target": "components/ui/stepper-13.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-8 text-center\"><Stepper default-value=\"${2}\"><!-- Loop steps -->\n<StepperItem key=\"${step}\" step=\"${step}\" class=\"not-last:flex-1 max-md:items-start\"><StepperTrigger class=\"gap-4 rounded max-md:flex-col\"><StepperIndicator /><div class=\"text-center md:-order-1 md:text-left\"><StepperTitle>${title}</StepperTitle><StepperDescription class=\"max-sm:hidden\">${description}</StepperDescription></div></StepperTrigger><!-- if step < steps.length -->\n<StepperSeparator class=\"max-md:mt-3.5 md:mx-4\" />\n<!-- endif --></StepperItem>\n<!-- End Loop --></Stepper><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Stepper with inline titles and descriptions\n      </p></div>\n</template>"
        },
        {
          "path": "registry/default/components/stepper/stepper-13.wxml",
          "target": "components/ui/stepper-13/stepper-13.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-8 text-center\"><stepper default-value=\"{{2}}\"><stepperitem wx:for=\"{{steps}}\" wx:for-item=\"{ step, title, description }\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{step}}\" step=\"{{step}}\" class=\"not-last:flex-1 max-md:items-start\"><steppertrigger class=\"gap-4 rounded max-md:flex-col\"><stepperindicator /><view class=\"text-center md:-order-1 md:text-left\"><steppertitle>{{ title }}</steppertitle><stepperdescription class=\"max-sm:hidden\">{{ description }}</stepperdescription></view></steppertrigger><stepperseparator wx:if=\"{{step < steps.length}}\" class=\"max-md:mt-3.5 md:mx-4\" /></stepperitem></stepper><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Stepper with inline titles and descriptions\n      </text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "stepper"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "stepper-13",
          "group": "stepper",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "stepper-13",
              "path": "registry/default/components/stepper/stepper-13.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "stepper-13",
              "path": "registry/default/components/stepper/stepper-13.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "stepper-13",
              "path": "registry/default/components/stepper/stepper-13.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "stepper-13",
              "path": "registry/default/components/stepper/stepper-13.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "stepper",
        "title": "Stepper · With step titles"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "stepper"
      ]
    },
    {
      "name": "stepper-14",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/stepper.json"
      ],
      "files": [
        {
          "path": "registry/default/components/stepper/stepper-14.tsx",
          "type": "registry:component",
          "target": "components/ui/stepper-14.tsx",
          "content": "import {\n  Stepper,\n  StepperIndicator,\n  StepperItem,\n  StepperSeparator,\n  StepperTrigger,\n} from '@timui/react'\n\nconst steps = [1, 2, 3, 4]\n\nexport default function Component() {\n  return (\n    <div className=\"space-y-8 text-center\">\n      <Stepper defaultValue={2} orientation=\"vertical\">\n        {steps.map((step) => (\n          <StepperItem key={step} step={step} className=\"not-last:flex-1\">\n            <StepperTrigger>\n              <StepperIndicator />\n            </StepperTrigger>\n            {step < steps.length && <StepperSeparator />}\n          </StepperItem>\n        ))}\n      </Stepper>\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Vertical stepper with numbers and checkmarks\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-14.vue",
          "target": "components/ui/stepper-14.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Stepper } from '@timui/vue';\nimport { StepperIndicator } from '@timui/vue';\nimport { StepperItem } from '@timui/vue';\nimport { StepperSeparator } from '@timui/vue';\nimport { StepperTrigger } from '@timui/vue';\n\n\n\n\n\nconst steps = [1, 2, 3, 4]\n\n</script>\n\n<template>\n  <div class=\"space-y-8 text-center\"><Stepper :default-value=\"2\" orientation=\"vertical\"><StepperItem v-for=\"(step, index) in steps\" :key=\"step\" :step=\"step\" class=\"not-last:flex-1\"><StepperTrigger><StepperIndicator /></StepperTrigger><StepperSeparator v-if=\"step < steps.length\" /></StepperItem></Stepper><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Vertical stepper with numbers and checkmarks\n      </p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-14.html",
          "target": "components/ui/stepper-14.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-8 text-center\"><Stepper default-value=\"${2}\" orientation=\"vertical\"><!-- Loop steps -->\n<StepperItem key=\"${step}\" step=\"${step}\" class=\"not-last:flex-1\"><StepperTrigger><StepperIndicator /></StepperTrigger><!-- if step < steps.length -->\n<StepperSeparator />\n<!-- endif --></StepperItem>\n<!-- End Loop --></Stepper><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Vertical stepper with numbers and checkmarks\n      </p></div>\n</template>"
        },
        {
          "path": "registry/default/components/stepper/stepper-14.wxml",
          "target": "components/ui/stepper-14/stepper-14.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-8 text-center\"><stepper default-value=\"{{2}}\" orientation=\"vertical\"><stepperitem wx:for=\"{{steps}}\" wx:for-item=\"step\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{step}}\" step=\"{{step}}\" class=\"not-last:flex-1\"><steppertrigger><stepperindicator /></steppertrigger><stepperseparator wx:if=\"{{step < steps.length}}\" /></stepperitem></stepper><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Vertical stepper with numbers and checkmarks\n      </text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "stepper",
          "vertical stepper"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "stepper-14",
          "group": "stepper",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "stepper-14",
              "path": "registry/default/components/stepper/stepper-14.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "stepper-14",
              "path": "registry/default/components/stepper/stepper-14.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "stepper-14",
              "path": "registry/default/components/stepper/stepper-14.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "stepper-14",
              "path": "registry/default/components/stepper/stepper-14.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "stepper",
        "title": "Stepper · Dot indicators"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "stepper"
      ]
    },
    {
      "name": "stepper-15",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/stepper.json"
      ],
      "files": [
        {
          "path": "registry/default/components/stepper/stepper-15.tsx",
          "type": "registry:component",
          "target": "components/ui/stepper-15.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport {\n  Button,\n  Stepper,\n  StepperIndicator,\n  StepperItem,\n  StepperSeparator,\n  StepperTrigger,\n} from '@timui/react'\n\nconst steps = [1, 2, 3, 4]\n\nexport default function Component() {\n  const [currentStep, setCurrentStep] = useState(1)\n  return (\n    <div className=\"space-y-8 text-center\">\n      <Stepper value={currentStep} onValueChange={setCurrentStep} orientation=\"vertical\">\n        {steps.map((step) => (\n          <StepperItem key={step} step={step} className=\"not-last:flex-1\">\n            <StepperTrigger asChild>\n              <StepperIndicator />\n            </StepperTrigger>\n            {step < steps.length && <StepperSeparator />}\n          </StepperItem>\n        ))}\n      </Stepper>\n      <div className=\"flex justify-center space-x-4\">\n        <Button\n          variant=\"outline\"\n          className=\"w-32\"\n          onClick={() => setCurrentStep((prev) => prev - 1)}\n          disabled={currentStep === 1}\n        >\n          Prev step\n        </Button>\n        <Button\n          variant=\"outline\"\n          className=\"w-32\"\n          onClick={() => setCurrentStep((prev) => prev + 1)}\n          disabled={currentStep > steps.length}\n        >\n          Next step\n        </Button>\n      </div>\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Controlled vertical stepper with checkmarks\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-15.vue",
          "target": "components/ui/stepper-15.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Button } from '@timui/vue';\nimport { Stepper } from '@timui/vue';\nimport { StepperIndicator } from '@timui/vue';\nimport { StepperItem } from '@timui/vue';\nimport { StepperSeparator } from '@timui/vue';\nimport { StepperTrigger } from '@timui/vue';\n\n\n\nconst currentStep = ref(1);\n\n\nfunction setCurrentStep(next: typeof currentStep.value | ((prev: typeof currentStep.value) => typeof currentStep.value)) {\n  currentStep.value = typeof next === 'function'\n    ? (next as (prev: typeof currentStep.value) => typeof currentStep.value)(currentStep.value)\n    : next;\n}\n\n\nconst steps = [1, 2, 3, 4]\n\n</script>\n\n<template>\n  <div class=\"space-y-8 text-center\"><Stepper :value=\"currentStep\" @update:modelValue=\"setCurrentStep\" orientation=\"vertical\"><StepperItem v-for=\"(step, index) in steps\" :key=\"step\" :step=\"step\" class=\"not-last:flex-1\"><StepperTrigger as-child><StepperIndicator /></StepperTrigger><StepperSeparator v-if=\"step < steps.length\" /></StepperItem></Stepper><div class=\"flex justify-center space-x-4\"><Button variant=\"outline\" class=\"w-32\" @click=\"setCurrentStep((prev) => prev - 1)\" :disabled=\"currentStep === 1\">Prev step\n        </Button><Button variant=\"outline\" class=\"w-32\" @click=\"setCurrentStep((prev) => prev + 1)\" :disabled=\"currentStep > steps.length\">Next step\n        </Button></div><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Controlled vertical stepper with checkmarks\n      </p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-15.html",
          "target": "components/ui/stepper-15.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-8 text-center\"><Stepper value=\"${currentStep}\" on-value-change=\"${setCurrentStep}\" orientation=\"vertical\"><!-- Loop steps -->\n<StepperItem key=\"${step}\" step=\"${step}\" class=\"not-last:flex-1\"><StepperTrigger aschild><StepperIndicator /></StepperTrigger><!-- if step < steps.length -->\n<StepperSeparator />\n<!-- endif --></StepperItem>\n<!-- End Loop --></Stepper><div class=\"flex justify-center space-x-4\"><Button variant=\"outline\" class=\"w-32\" on-click=\"${() => setCurrentStep((prev) => prev - 1)}\" disabled=\"${currentStep === 1}\">Prev step\n        </Button><Button variant=\"outline\" class=\"w-32\" on-click=\"${() => setCurrentStep((prev) => prev + 1)}\" disabled=\"${currentStep > steps.length}\">Next step\n        </Button></div><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Controlled vertical stepper with checkmarks\n      </p></div>\n</template>"
        },
        {
          "path": "registry/default/components/stepper/stepper-15.wxml",
          "target": "components/ui/stepper-15/stepper-15.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-8 text-center\"><stepper value=\"{{currentStep}}\" bindchange=\"setCurrentStep\" orientation=\"vertical\"><stepperitem wx:for=\"{{steps}}\" wx:for-item=\"step\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{step}}\" step=\"{{step}}\" class=\"not-last:flex-1\"><steppertrigger aschild><stepperindicator /></steppertrigger><stepperseparator wx:if=\"{{step < steps.length}}\" /></stepperitem></stepper><view class=\"flex justify-center space-x-4\"><button variant=\"outline\" class=\"w-32\" bindtap=\"setCurrentStep((prev) => prev - 1)\" disabled=\"{{currentStep === 1}}\">Prev step\n        </button><button variant=\"outline\" class=\"w-32\" bindtap=\"setCurrentStep((prev) => prev + 1)\" disabled=\"{{currentStep > steps.length}}\">Next step\n        </button></view><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Controlled vertical stepper with checkmarks\n      </text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "stepper",
          "vertical stepper"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "stepper-15",
          "group": "stepper",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "stepper-15",
              "path": "registry/default/components/stepper/stepper-15.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "stepper-15",
              "path": "registry/default/components/stepper/stepper-15.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "stepper-15",
              "path": "registry/default/components/stepper/stepper-15.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "stepper-15",
              "path": "registry/default/components/stepper/stepper-15.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "stepper",
        "title": "Stepper · Numeric indicators"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "stepper"
      ]
    },
    {
      "name": "stepper-16",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/stepper.json"
      ],
      "files": [
        {
          "path": "registry/default/components/stepper/stepper-16.tsx",
          "type": "registry:component",
          "target": "components/ui/stepper-16.tsx",
          "content": "import {\n  Stepper,\n  StepperIndicator,\n  StepperItem,\n  StepperSeparator,\n  StepperTitle,\n  StepperTrigger,\n} from '@timui/react'\n\nconst steps = [\n  {\n    step: 1,\n    title: 'Step One',\n  },\n  {\n    step: 2,\n    title: 'Step Two',\n  },\n  {\n    step: 3,\n    title: 'Step Three',\n  },\n  {\n    step: 4,\n    title: 'Step Four',\n  },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"space-y-8 text-center\">\n      <Stepper defaultValue={2} orientation=\"vertical\">\n        {steps.map(({ step, title }) => (\n          <StepperItem key={step} step={step} className=\"relative items-start not-last:flex-1\">\n            <StepperTrigger className=\"items-start rounded pb-12 last:pb-0\">\n              <StepperIndicator />\n              <div className=\"mt-0.5 px-2 text-left\">\n                <StepperTitle>{title}</StepperTitle>\n              </div>\n            </StepperTrigger>\n            {step < steps.length && (\n              <StepperSeparator className=\"absolute inset-y-0 top-[calc(1.5rem+0.125rem)] left-3 -order-1 m-0 -translate-x-1/2 group-data-[orientation=horizontal]/stepper:w-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=horizontal]/stepper:flex-none group-data-[orientation=vertical]/stepper:h-[calc(100%-1.5rem-0.25rem)]\" />\n            )}\n          </StepperItem>\n        ))}\n      </Stepper>\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Vertical stepper with inline titles\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-16.vue",
          "target": "components/ui/stepper-16.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Stepper } from '@timui/vue';\nimport { StepperIndicator } from '@timui/vue';\nimport { StepperItem } from '@timui/vue';\nimport { StepperSeparator } from '@timui/vue';\nimport { StepperTitle } from '@timui/vue';\nimport { StepperTrigger } from '@timui/vue';\n\n\n\n\n\nconst steps = [\n  {\n    step: 1,\n    title: 'Step One',\n  },\n  {\n    step: 2,\n    title: 'Step Two',\n  },\n  {\n    step: 3,\n    title: 'Step Three',\n  },\n  {\n    step: 4,\n    title: 'Step Four',\n  },\n]\n\n</script>\n\n<template>\n  <div class=\"space-y-8 text-center\"><Stepper :default-value=\"2\" orientation=\"vertical\"><StepperItem v-for=\"({ step, title }, index) in steps\" :key=\"step\" :step=\"step\" class=\"relative items-start not-last:flex-1\"><StepperTrigger class=\"items-start rounded pb-12 last:pb-0\"><StepperIndicator /><div class=\"mt-0.5 px-2 text-left\"><StepperTitle>{{ title }}</StepperTitle></div></StepperTrigger><StepperSeparator v-if=\"step < steps.length\" class=\"absolute inset-y-0 top-[calc(1.5rem+0.125rem)] left-3 -order-1 m-0 -translate-x-1/2 group-data-[orientation=horizontal]/stepper:w-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=horizontal]/stepper:flex-none group-data-[orientation=vertical]/stepper:h-[calc(100%-1.5rem-0.25rem)]\" /></StepperItem></Stepper><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Vertical stepper with inline titles\n      </p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-16.html",
          "target": "components/ui/stepper-16.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-8 text-center\"><Stepper default-value=\"${2}\" orientation=\"vertical\"><!-- Loop steps -->\n<StepperItem key=\"${step}\" step=\"${step}\" class=\"relative items-start not-last:flex-1\"><StepperTrigger class=\"items-start rounded pb-12 last:pb-0\"><StepperIndicator /><div class=\"mt-0.5 px-2 text-left\"><StepperTitle>${title}</StepperTitle></div></StepperTrigger><!-- if step < steps.length -->\n<StepperSeparator class=\"absolute inset-y-0 top-[calc(1.5rem+0.125rem)] left-3 -order-1 m-0 -translate-x-1/2 group-data-[orientation=horizontal]/stepper:w-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=horizontal]/stepper:flex-none group-data-[orientation=vertical]/stepper:h-[calc(100%-1.5rem-0.25rem)]\" />\n<!-- endif --></StepperItem>\n<!-- End Loop --></Stepper><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Vertical stepper with inline titles\n      </p></div>\n</template>"
        },
        {
          "path": "registry/default/components/stepper/stepper-16.wxml",
          "target": "components/ui/stepper-16/stepper-16.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-8 text-center\"><stepper default-value=\"{{2}}\" orientation=\"vertical\"><stepperitem wx:for=\"{{steps}}\" wx:for-item=\"{ step, title }\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{step}}\" step=\"{{step}}\" class=\"relative items-start not-last:flex-1\"><steppertrigger class=\"items-start rounded pb-12 last:pb-0\"><stepperindicator /><view class=\"mt-0.5 px-2 text-left\"><steppertitle>{{ title }}</steppertitle></view></steppertrigger><stepperseparator wx:if=\"{{step < steps.length}}\" class=\"absolute inset-y-0 top-[calc(1.5rem+0.125rem)] left-3 -order-1 m-0 -translate-x-1/2 group-data-[orientation=horizontal]/stepper:w-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=horizontal]/stepper:flex-none group-data-[orientation=vertical]/stepper:h-[calc(100%-1.5rem-0.25rem)]\" /></stepperitem></stepper><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Vertical stepper with inline titles\n      </text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "stepper",
          "vertical stepper"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "stepper-16",
          "group": "stepper",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "stepper-16",
              "path": "registry/default/components/stepper/stepper-16.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "stepper-16",
              "path": "registry/default/components/stepper/stepper-16.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "stepper-16",
              "path": "registry/default/components/stepper/stepper-16.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "stepper-16",
              "path": "registry/default/components/stepper/stepper-16.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "stepper",
        "title": "Stepper · With step titles"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "stepper"
      ]
    },
    {
      "name": "stepper-17",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/stepper.json"
      ],
      "files": [
        {
          "path": "registry/default/components/stepper/stepper-17.tsx",
          "type": "registry:component",
          "target": "components/ui/stepper-17.tsx",
          "content": "import {\n  Stepper,\n  StepperDescription,\n  StepperIndicator,\n  StepperItem,\n  StepperSeparator,\n  StepperTitle,\n  StepperTrigger,\n} from '@timui/react'\n\nconst steps = [\n  {\n    step: 1,\n    title: 'Step One',\n    description: 'Desc for step one',\n  },\n  {\n    step: 2,\n    title: 'Step Two',\n    description: 'Desc for step two',\n  },\n  {\n    step: 3,\n    title: 'Step Three',\n    description: 'Desc for step three',\n  },\n]\n\nexport default function Component() {\n  return (\n    <div className=\"space-y-8 text-center\">\n      <Stepper defaultValue={2} orientation=\"vertical\">\n        {steps.map(({ step, title, description }) => (\n          <StepperItem key={step} step={step} className=\"relative items-start not-last:flex-1\">\n            <StepperTrigger className=\"items-start rounded pb-12 last:pb-0\">\n              <StepperIndicator />\n              <div className=\"mt-0.5 space-y-0.5 px-2 text-left\">\n                <StepperTitle>{title}</StepperTitle>\n                <StepperDescription>{description}</StepperDescription>\n              </div>\n            </StepperTrigger>\n            {step < steps.length && (\n              <StepperSeparator className=\"absolute inset-y-0 top-[calc(1.5rem+0.125rem)] left-3 -order-1 m-0 -translate-x-1/2 group-data-[orientation=horizontal]/stepper:w-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=horizontal]/stepper:flex-none group-data-[orientation=vertical]/stepper:h-[calc(100%-1.5rem-0.25rem)]\" />\n            )}\n          </StepperItem>\n        ))}\n      </Stepper>\n      <p className=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">\n        Vertical stepper with inline titles and descriptions\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-17.vue",
          "target": "components/ui/stepper-17.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Stepper } from '@timui/vue';\nimport { StepperDescription } from '@timui/vue';\nimport { StepperIndicator } from '@timui/vue';\nimport { StepperItem } from '@timui/vue';\nimport { StepperSeparator } from '@timui/vue';\nimport { StepperTitle } from '@timui/vue';\nimport { StepperTrigger } from '@timui/vue';\n\n\n\n\n\nconst steps = [\n  {\n    step: 1,\n    title: 'Step One',\n    description: 'Desc for step one',\n  },\n  {\n    step: 2,\n    title: 'Step Two',\n    description: 'Desc for step two',\n  },\n  {\n    step: 3,\n    title: 'Step Three',\n    description: 'Desc for step three',\n  },\n]\n\n</script>\n\n<template>\n  <div class=\"space-y-8 text-center\"><Stepper :default-value=\"2\" orientation=\"vertical\"><StepperItem v-for=\"({ step, title, description }, index) in steps\" :key=\"step\" :step=\"step\" class=\"relative items-start not-last:flex-1\"><StepperTrigger class=\"items-start rounded pb-12 last:pb-0\"><StepperIndicator /><div class=\"mt-0.5 space-y-0.5 px-2 text-left\"><StepperTitle>{{ title }}</StepperTitle><StepperDescription>{{ description }}</StepperDescription></div></StepperTrigger><StepperSeparator v-if=\"step < steps.length\" class=\"absolute inset-y-0 top-[calc(1.5rem+0.125rem)] left-3 -order-1 m-0 -translate-x-1/2 group-data-[orientation=horizontal]/stepper:w-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=horizontal]/stepper:flex-none group-data-[orientation=vertical]/stepper:h-[calc(100%-1.5rem-0.25rem)]\" /></StepperItem></Stepper><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Vertical stepper with inline titles and descriptions\n      </p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/stepper/stepper-17.html",
          "target": "components/ui/stepper-17.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-8 text-center\"><Stepper default-value=\"${2}\" orientation=\"vertical\"><!-- Loop steps -->\n<StepperItem key=\"${step}\" step=\"${step}\" class=\"relative items-start not-last:flex-1\"><StepperTrigger class=\"items-start rounded pb-12 last:pb-0\"><StepperIndicator /><div class=\"mt-0.5 space-y-0.5 px-2 text-left\"><StepperTitle>${title}</StepperTitle><StepperDescription>${description}</StepperDescription></div></StepperTrigger><!-- if step < steps.length -->\n<StepperSeparator class=\"absolute inset-y-0 top-[calc(1.5rem+0.125rem)] left-3 -order-1 m-0 -translate-x-1/2 group-data-[orientation=horizontal]/stepper:w-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=horizontal]/stepper:flex-none group-data-[orientation=vertical]/stepper:h-[calc(100%-1.5rem-0.25rem)]\" />\n<!-- endif --></StepperItem>\n<!-- End Loop --></Stepper><p class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Vertical stepper with inline titles and descriptions\n      </p></div>\n</template>"
        },
        {
          "path": "registry/default/components/stepper/stepper-17.wxml",
          "target": "components/ui/stepper-17/stepper-17.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-8 text-center\"><stepper default-value=\"{{2}}\" orientation=\"vertical\"><stepperitem wx:for=\"{{steps}}\" wx:for-item=\"{ step, title, description }\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{step}}\" step=\"{{step}}\" class=\"relative items-start not-last:flex-1\"><steppertrigger class=\"items-start rounded pb-12 last:pb-0\"><stepperindicator /><view class=\"mt-0.5 space-y-0.5 px-2 text-left\"><steppertitle>{{ title }}</steppertitle><stepperdescription>{{ description }}</stepperdescription></view></steppertrigger><stepperseparator wx:if=\"{{step < steps.length}}\" class=\"absolute inset-y-0 top-[calc(1.5rem+0.125rem)] left-3 -order-1 m-0 -translate-x-1/2 group-data-[orientation=horizontal]/stepper:w-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=horizontal]/stepper:flex-none group-data-[orientation=vertical]/stepper:h-[calc(100%-1.5rem-0.25rem)]\" /></stepperitem></stepper><text class=\"text-muted-foreground mt-2 text-xs\" role=\"region\" aria-live=\"polite\">Vertical stepper with inline titles and descriptions\n      </text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "stepper",
          "vertical stepper"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "stepper-17",
          "group": "stepper",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "stepper-17",
              "path": "registry/default/components/stepper/stepper-17.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "stepper-17",
              "path": "registry/default/components/stepper/stepper-17.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "stepper-17",
              "path": "registry/default/components/stepper/stepper-17.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "stepper-17",
              "path": "registry/default/components/stepper/stepper-17.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "stepper",
        "title": "Stepper · With step titles"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "stepper"
      ]
    },
    {
      "name": "timeline-01",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/timeline.json"
      ],
      "files": [
        {
          "path": "registry/default/components/timeline/timeline-01.tsx",
          "type": "registry:component",
          "target": "components/ui/timeline-01.tsx",
          "content": "import {\n  Timeline,\n  TimelineHeader,\n  TimelineIndicator,\n  TimelineItem,\n  TimelineSeparator,\n  TimelineTitle,\n} from '@timui/react'\n\nconst items = [\n  {\n    id: 1,\n    date: 'Mar 15, 2024',\n    title: 'Project Kickoff',\n    description:\n      'Initial team meeting and project scope definition. Established key milestones and resource allocation.',\n  },\n  {\n    id: 2,\n    date: 'Mar 22, 2024',\n    title: 'Design Phase',\n    description:\n      'Completed wireframes and user interface mockups. Stakeholder review and feedback incorporated.',\n  },\n  {\n    id: 3,\n    date: 'Apr 5, 2024',\n    title: 'Development Sprint',\n    description: 'Backend API implementation and frontend component development in progress.',\n  },\n  {\n    id: 4,\n    date: 'Apr 19, 2024',\n    title: 'Testing & Deployment',\n    description:\n      'Quality assurance testing, performance optimization, and production deployment preparation.',\n  },\n]\n\nexport default function Component() {\n  return (\n    <Timeline defaultValue={3}>\n      {items.map((item) => (\n        <TimelineItem key={item.id} step={item.id}>\n          <TimelineHeader>\n            <TimelineSeparator />\n            <TimelineTitle className=\"-mt-0.5\">{item.title}</TimelineTitle>\n            <TimelineIndicator />\n          </TimelineHeader>\n        </TimelineItem>\n      ))}\n    </Timeline>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/timeline/timeline-01.vue",
          "target": "components/ui/timeline-01.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Timeline } from '@timui/vue';\nimport { TimelineHeader } from '@timui/vue';\nimport { TimelineIndicator } from '@timui/vue';\nimport { TimelineItem } from '@timui/vue';\nimport { TimelineSeparator } from '@timui/vue';\nimport { TimelineTitle } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: 1,\n    date: 'Mar 15, 2024',\n    title: 'Project Kickoff',\n    description:\n      'Initial team meeting and project scope definition. Established key milestones and resource allocation.',\n  },\n  {\n    id: 2,\n    date: 'Mar 22, 2024',\n    title: 'Design Phase',\n    description:\n      'Completed wireframes and user interface mockups. Stakeholder review and feedback incorporated.',\n  },\n  {\n    id: 3,\n    date: 'Apr 5, 2024',\n    title: 'Development Sprint',\n    description: 'Backend API implementation and frontend component development in progress.',\n  },\n  {\n    id: 4,\n    date: 'Apr 19, 2024',\n    title: 'Testing & Deployment',\n    description:\n      'Quality assurance testing, performance optimization, and production deployment preparation.',\n  },\n]\n\n</script>\n\n<template>\n  <Timeline :default-value=\"3\"><TimelineItem v-for=\"(item, index) in items\" :key=\"item.id\" :step=\"item.id\"><TimelineHeader><TimelineSeparator /><TimelineTitle class=\"-mt-0.5\">{{ item.title }}</TimelineTitle><TimelineIndicator /></TimelineHeader></TimelineItem></Timeline>\n</template>\n"
        },
        {
          "path": "registry/default/components/timeline/timeline-01.html",
          "target": "components/ui/timeline-01.html",
          "type": "registry:component",
          "content": "<template>\n  <Timeline default-value=\"${3}\"><!-- Loop items -->\n<TimelineItem key=\"${item.id}\" step=\"${item.id}\"><TimelineHeader><TimelineSeparator /><TimelineTitle class=\"-mt-0.5\">${item.title}</TimelineTitle><TimelineIndicator /></TimelineHeader></TimelineItem>\n<!-- End Loop --></Timeline>\n</template>"
        },
        {
          "path": "registry/default/components/timeline/timeline-01.wxml",
          "target": "components/ui/timeline-01/timeline-01.wxml",
          "type": "registry:component",
          "content": "<view>\n  <timeline default-value=\"{{3}}\"><timelineitem wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{item.id}}\" step=\"{{item.id}}\"><timelineheader><timelineseparator /><timelinetitle class=\"-mt-0.5\">{{ item.title }}</timelinetitle><timelineindicator /></timelineheader></timelineitem></timeline>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "timeline",
          "vertical timeline"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "timeline-01",
          "group": "timeline",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "timeline-01",
              "path": "registry/default/components/timeline/timeline-01.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "timeline-01",
              "path": "registry/default/components/timeline/timeline-01.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "timeline-01",
              "path": "registry/default/components/timeline/timeline-01.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "timeline-01",
              "path": "registry/default/components/timeline/timeline-01.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "timeline",
        "title": "Timeline · Project timeline"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "timeline"
      ]
    },
    {
      "name": "timeline-02",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/timeline.json"
      ],
      "files": [
        {
          "path": "registry/default/components/timeline/timeline-02.tsx",
          "type": "registry:component",
          "target": "components/ui/timeline-02.tsx",
          "content": "import {\n  Timeline,\n  TimelineContent,\n  TimelineDate,\n  TimelineHeader,\n  TimelineIndicator,\n  TimelineItem,\n  TimelineSeparator,\n  TimelineTitle,\n} from '@timui/react'\n\nconst items = [\n  {\n    id: 1,\n    date: 'Mar 15, 2024',\n    title: 'Project Kickoff',\n    description:\n      'Initial team meeting and project scope definition. Established key milestones and resource allocation.',\n  },\n  {\n    id: 2,\n    date: 'Mar 22, 2024',\n    title: 'Design Phase',\n    description:\n      'Completed wireframes and user interface mockups. Stakeholder review and feedback incorporated.',\n  },\n  {\n    id: 3,\n    date: 'Apr 5, 2024',\n    title: 'Development Sprint',\n    description: 'Backend API implementation and frontend component development in progress.',\n  },\n  {\n    id: 4,\n    date: 'Apr 19, 2024',\n    title: 'Testing & Deployment',\n    description:\n      'Quality assurance testing, performance optimization, and production deployment preparation.',\n  },\n]\n\nexport default function Component() {\n  return (\n    <Timeline defaultValue={3}>\n      {items.map((item) => (\n        <TimelineItem\n          key={item.id}\n          step={item.id}\n          className=\"group-data-[orientation=vertical]/timeline:sm:ms-32\"\n        >\n          <TimelineHeader>\n            <TimelineSeparator />\n            <TimelineDate className=\"group-data-[orientation=vertical]/timeline:sm:absolute group-data-[orientation=vertical]/timeline:sm:-left-32 group-data-[orientation=vertical]/timeline:sm:w-20 group-data-[orientation=vertical]/timeline:sm:text-right\">\n              {item.date}\n            </TimelineDate>\n            <TimelineTitle className=\"sm:-mt-0.5\">{item.title}</TimelineTitle>\n            <TimelineIndicator />\n          </TimelineHeader>\n          <TimelineContent>{item.description}</TimelineContent>\n        </TimelineItem>\n      ))}\n    </Timeline>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/timeline/timeline-02.vue",
          "target": "components/ui/timeline-02.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Timeline } from '@timui/vue';\nimport { TimelineContent } from '@timui/vue';\nimport { TimelineDate } from '@timui/vue';\nimport { TimelineHeader } from '@timui/vue';\nimport { TimelineIndicator } from '@timui/vue';\nimport { TimelineItem } from '@timui/vue';\nimport { TimelineSeparator } from '@timui/vue';\nimport { TimelineTitle } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: 1,\n    date: 'Mar 15, 2024',\n    title: 'Project Kickoff',\n    description:\n      'Initial team meeting and project scope definition. Established key milestones and resource allocation.',\n  },\n  {\n    id: 2,\n    date: 'Mar 22, 2024',\n    title: 'Design Phase',\n    description:\n      'Completed wireframes and user interface mockups. Stakeholder review and feedback incorporated.',\n  },\n  {\n    id: 3,\n    date: 'Apr 5, 2024',\n    title: 'Development Sprint',\n    description: 'Backend API implementation and frontend component development in progress.',\n  },\n  {\n    id: 4,\n    date: 'Apr 19, 2024',\n    title: 'Testing & Deployment',\n    description:\n      'Quality assurance testing, performance optimization, and production deployment preparation.',\n  },\n]\n\n</script>\n\n<template>\n  <Timeline :default-value=\"3\"><TimelineItem v-for=\"(item, index) in items\" :key=\"item.id\" :step=\"item.id\" class=\"group-data-[orientation=vertical]/timeline:sm:ms-32\"><TimelineHeader><TimelineSeparator /><TimelineDate class=\"group-data-[orientation=vertical]/timeline:sm:absolute group-data-[orientation=vertical]/timeline:sm:-left-32 group-data-[orientation=vertical]/timeline:sm:w-20 group-data-[orientation=vertical]/timeline:sm:text-right\">{{ item.date }}</TimelineDate><TimelineTitle class=\"sm:-mt-0.5\">{{ item.title }}</TimelineTitle><TimelineIndicator /></TimelineHeader><TimelineContent>{{ item.description }}</TimelineContent></TimelineItem></Timeline>\n</template>\n"
        },
        {
          "path": "registry/default/components/timeline/timeline-02.html",
          "target": "components/ui/timeline-02.html",
          "type": "registry:component",
          "content": "<template>\n  <Timeline default-value=\"${3}\"><!-- Loop items -->\n<TimelineItem key=\"${item.id}\" step=\"${item.id}\" class=\"group-data-[orientation=vertical]/timeline:sm:ms-32\"><TimelineHeader><TimelineSeparator /><TimelineDate class=\"group-data-[orientation=vertical]/timeline:sm:absolute group-data-[orientation=vertical]/timeline:sm:-left-32 group-data-[orientation=vertical]/timeline:sm:w-20 group-data-[orientation=vertical]/timeline:sm:text-right\">${item.date}</TimelineDate><TimelineTitle class=\"sm:-mt-0.5\">${item.title}</TimelineTitle><TimelineIndicator /></TimelineHeader><TimelineContent>${item.description}</TimelineContent></TimelineItem>\n<!-- End Loop --></Timeline>\n</template>"
        },
        {
          "path": "registry/default/components/timeline/timeline-02.wxml",
          "target": "components/ui/timeline-02/timeline-02.wxml",
          "type": "registry:component",
          "content": "<view>\n  <timeline default-value=\"{{3}}\"><timelineitem wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{item.id}}\" step=\"{{item.id}}\" class=\"group-data-[orientation=vertical]/timeline:sm:ms-32\"><timelineheader><timelineseparator /><timelinedate class=\"group-data-[orientation=vertical]/timeline:sm:absolute group-data-[orientation=vertical]/timeline:sm:-left-32 group-data-[orientation=vertical]/timeline:sm:w-20 group-data-[orientation=vertical]/timeline:sm:text-right\">{{ item.date }}</timelinedate><timelinetitle class=\"sm:-mt-0.5\">{{ item.title }}</timelinetitle><timelineindicator /></timelineheader><timelinecontent>{{ item.description }}</timelinecontent></timelineitem></timeline>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "timeline",
          "vertical timeline"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "timeline-02",
          "group": "timeline",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "timeline-02",
              "path": "registry/default/components/timeline/timeline-02.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "timeline-02",
              "path": "registry/default/components/timeline/timeline-02.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "timeline-02",
              "path": "registry/default/components/timeline/timeline-02.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "timeline-02",
              "path": "registry/default/components/timeline/timeline-02.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "timeline",
        "title": "Timeline · Detailed timeline"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "timeline"
      ]
    },
    {
      "name": "timeline-03",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/timeline.json"
      ],
      "files": [
        {
          "path": "registry/default/components/timeline/timeline-03.tsx",
          "type": "registry:component",
          "target": "components/ui/timeline-03.tsx",
          "content": "import {\n  Timeline,\n  TimelineContent,\n  TimelineDate,\n  TimelineHeader,\n  TimelineIndicator,\n  TimelineItem,\n  TimelineSeparator,\n  TimelineTitle,\n} from '@timui/react'\n\nconst items = [\n  {\n    id: 1,\n    date: 'Mar 15, 2024',\n    title: 'Project Kickoff',\n    description:\n      'Initial team meeting and project scope definition. Established key milestones and resource allocation.',\n  },\n  {\n    id: 2,\n    date: 'Mar 22, 2024',\n    title: 'Design Phase',\n    description:\n      'Completed wireframes and user interface mockups. Stakeholder review and feedback incorporated.',\n  },\n  {\n    id: 3,\n    date: 'Apr 5, 2024',\n    title: 'Development Sprint',\n    description: 'Backend API implementation and frontend component development in progress.',\n  },\n  {\n    id: 4,\n    date: 'Apr 19, 2024',\n    title: 'Testing & Deployment',\n    description:\n      'Quality assurance testing, performance optimization, and production deployment preparation.',\n  },\n]\n\nexport default function Component() {\n  return (\n    <Timeline defaultValue={3}>\n      {items.map((item) => (\n        <TimelineItem key={item.id} step={item.id}>\n          <TimelineHeader>\n            <TimelineSeparator />\n            <TimelineDate>{item.date}</TimelineDate>\n            <TimelineTitle>{item.title}</TimelineTitle>\n            <TimelineIndicator />\n          </TimelineHeader>\n          <TimelineContent>{item.description}</TimelineContent>\n        </TimelineItem>\n      ))}\n    </Timeline>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/timeline/timeline-03.vue",
          "target": "components/ui/timeline-03.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Timeline } from '@timui/vue';\nimport { TimelineContent } from '@timui/vue';\nimport { TimelineDate } from '@timui/vue';\nimport { TimelineHeader } from '@timui/vue';\nimport { TimelineIndicator } from '@timui/vue';\nimport { TimelineItem } from '@timui/vue';\nimport { TimelineSeparator } from '@timui/vue';\nimport { TimelineTitle } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: 1,\n    date: 'Mar 15, 2024',\n    title: 'Project Kickoff',\n    description:\n      'Initial team meeting and project scope definition. Established key milestones and resource allocation.',\n  },\n  {\n    id: 2,\n    date: 'Mar 22, 2024',\n    title: 'Design Phase',\n    description:\n      'Completed wireframes and user interface mockups. Stakeholder review and feedback incorporated.',\n  },\n  {\n    id: 3,\n    date: 'Apr 5, 2024',\n    title: 'Development Sprint',\n    description: 'Backend API implementation and frontend component development in progress.',\n  },\n  {\n    id: 4,\n    date: 'Apr 19, 2024',\n    title: 'Testing & Deployment',\n    description:\n      'Quality assurance testing, performance optimization, and production deployment preparation.',\n  },\n]\n\n</script>\n\n<template>\n  <Timeline :default-value=\"3\"><TimelineItem v-for=\"(item, index) in items\" :key=\"item.id\" :step=\"item.id\"><TimelineHeader><TimelineSeparator /><TimelineDate>{{ item.date }}</TimelineDate><TimelineTitle>{{ item.title }}</TimelineTitle><TimelineIndicator /></TimelineHeader><TimelineContent>{{ item.description }}</TimelineContent></TimelineItem></Timeline>\n</template>\n"
        },
        {
          "path": "registry/default/components/timeline/timeline-03.html",
          "target": "components/ui/timeline-03.html",
          "type": "registry:component",
          "content": "<template>\n  <Timeline default-value=\"${3}\"><!-- Loop items -->\n<TimelineItem key=\"${item.id}\" step=\"${item.id}\"><TimelineHeader><TimelineSeparator /><TimelineDate>${item.date}</TimelineDate><TimelineTitle>${item.title}</TimelineTitle><TimelineIndicator /></TimelineHeader><TimelineContent>${item.description}</TimelineContent></TimelineItem>\n<!-- End Loop --></Timeline>\n</template>"
        },
        {
          "path": "registry/default/components/timeline/timeline-03.wxml",
          "target": "components/ui/timeline-03/timeline-03.wxml",
          "type": "registry:component",
          "content": "<view>\n  <timeline default-value=\"{{3}}\"><timelineitem wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{item.id}}\" step=\"{{item.id}}\"><timelineheader><timelineseparator /><timelinedate>{{ item.date }}</timelinedate><timelinetitle>{{ item.title }}</timelinetitle><timelineindicator /></timelineheader><timelinecontent>{{ item.description }}</timelinecontent></timelineitem></timeline>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "timeline",
          "vertical timeline"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "timeline-03",
          "group": "timeline",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "timeline-03",
              "path": "registry/default/components/timeline/timeline-03.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "timeline-03",
              "path": "registry/default/components/timeline/timeline-03.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "timeline-03",
              "path": "registry/default/components/timeline/timeline-03.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "timeline-03",
              "path": "registry/default/components/timeline/timeline-03.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "timeline",
        "title": "Timeline · Detailed timeline"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "timeline"
      ]
    },
    {
      "name": "timeline-04",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/timeline.json"
      ],
      "files": [
        {
          "path": "registry/default/components/timeline/timeline-04.tsx",
          "type": "registry:component",
          "target": "components/ui/timeline-04.tsx",
          "content": "import {\n  Timeline,\n  TimelineContent,\n  TimelineDate,\n  TimelineHeader,\n  TimelineIndicator,\n  TimelineItem,\n  TimelineSeparator,\n  TimelineTitle,\n} from '@timui/react'\n\nconst items = [\n  {\n    id: 1,\n    date: '15 minutes ago',\n    title: 'Pull Request Submitted',\n    description:\n      'Submitted PR #342 with new feature implementation. Waiting for code review from team leads.',\n  },\n  {\n    id: 2,\n    date: '10 minutes ago',\n    title: 'CI Pipeline Started',\n    description:\n      'Automated tests and build process initiated. Running unit tests and code quality checks.',\n  },\n  {\n    id: 3,\n    date: '5 minutes ago',\n    title: 'Code Review Feedback',\n    description:\n      'Received comments on PR. Minor adjustments needed in error handling and documentation.',\n  },\n  {\n    id: 4,\n    title: 'Changes Pushed',\n    description:\n      'Implemented requested changes and pushed updates to feature branch. Awaiting final approval.',\n  },\n]\n\nexport default function Component() {\n  return (\n    <Timeline defaultValue={3}>\n      {items.map((item) => (\n        <TimelineItem key={item.id} step={item.id}>\n          <TimelineHeader>\n            <TimelineSeparator />\n            <TimelineTitle className=\"-mt-0.5\">{item.title}</TimelineTitle>\n            <TimelineIndicator />\n          </TimelineHeader>\n          <TimelineContent>\n            {item.description}\n            <TimelineDate className=\"mt-2 mb-0\">{item.date}</TimelineDate>\n          </TimelineContent>\n        </TimelineItem>\n      ))}\n    </Timeline>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/timeline/timeline-04.vue",
          "target": "components/ui/timeline-04.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Timeline } from '@timui/vue';\nimport { TimelineContent } from '@timui/vue';\nimport { TimelineDate } from '@timui/vue';\nimport { TimelineHeader } from '@timui/vue';\nimport { TimelineIndicator } from '@timui/vue';\nimport { TimelineItem } from '@timui/vue';\nimport { TimelineSeparator } from '@timui/vue';\nimport { TimelineTitle } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: 1,\n    date: '15 minutes ago',\n    title: 'Pull Request Submitted',\n    description:\n      'Submitted PR #342 with new feature implementation. Waiting for code review from team leads.',\n  },\n  {\n    id: 2,\n    date: '10 minutes ago',\n    title: 'CI Pipeline Started',\n    description:\n      'Automated tests and build process initiated. Running unit tests and code quality checks.',\n  },\n  {\n    id: 3,\n    date: '5 minutes ago',\n    title: 'Code Review Feedback',\n    description:\n      'Received comments on PR. Minor adjustments needed in error handling and documentation.',\n  },\n  {\n    id: 4,\n    title: 'Changes Pushed',\n    description:\n      'Implemented requested changes and pushed updates to feature branch. Awaiting final approval.',\n  },\n]\n\n</script>\n\n<template>\n  <Timeline :default-value=\"3\"><TimelineItem v-for=\"(item, index) in items\" :key=\"item.id\" :step=\"item.id\"><TimelineHeader><TimelineSeparator /><TimelineTitle class=\"-mt-0.5\">{{ item.title }}</TimelineTitle><TimelineIndicator /></TimelineHeader><TimelineContent>{{ item.description }}<TimelineDate class=\"mt-2 mb-0\">{{ item.date }}</TimelineDate></TimelineContent></TimelineItem></Timeline>\n</template>\n"
        },
        {
          "path": "registry/default/components/timeline/timeline-04.html",
          "target": "components/ui/timeline-04.html",
          "type": "registry:component",
          "content": "<template>\n  <Timeline default-value=\"${3}\"><!-- Loop items -->\n<TimelineItem key=\"${item.id}\" step=\"${item.id}\"><TimelineHeader><TimelineSeparator /><TimelineTitle class=\"-mt-0.5\">${item.title}</TimelineTitle><TimelineIndicator /></TimelineHeader><TimelineContent>${item.description}<TimelineDate class=\"mt-2 mb-0\">${item.date}</TimelineDate></TimelineContent></TimelineItem>\n<!-- End Loop --></Timeline>\n</template>"
        },
        {
          "path": "registry/default/components/timeline/timeline-04.wxml",
          "target": "components/ui/timeline-04/timeline-04.wxml",
          "type": "registry:component",
          "content": "<view>\n  <timeline default-value=\"{{3}}\"><timelineitem wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{item.id}}\" step=\"{{item.id}}\"><timelineheader><timelineseparator /><timelinetitle class=\"-mt-0.5\">{{ item.title }}</timelinetitle><timelineindicator /></timelineheader><timelinecontent>{{ item.description }}<timelinedate class=\"mt-2 mb-0\">{{ item.date }}</timelinedate></timelinecontent></timelineitem></timeline>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "timeline",
          "vertical timeline"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "timeline-04",
          "group": "timeline",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "timeline-04",
              "path": "registry/default/components/timeline/timeline-04.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "timeline-04",
              "path": "registry/default/components/timeline/timeline-04.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "timeline-04",
              "path": "registry/default/components/timeline/timeline-04.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "timeline-04",
              "path": "registry/default/components/timeline/timeline-04.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "timeline",
        "title": "Timeline · Detailed timeline"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "timeline"
      ]
    },
    {
      "name": "timeline-05",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/timeline.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/timeline/timeline-05.tsx",
          "type": "registry:component",
          "target": "components/ui/timeline-05.tsx",
          "content": "import {\n  Timeline,\n  TimelineContent,\n  TimelineDate,\n  TimelineHeader,\n  TimelineIndicator,\n  TimelineItem,\n  TimelineSeparator,\n  TimelineTitle,\n} from '@timui/react'\nimport { CheckIcon } from 'lucide-react'\n\nconst items = [\n  {\n    id: 1,\n    date: 'Mar 15, 2024',\n    title: 'Project Kickoff',\n    description:\n      'Initial team meeting and project scope definition. Established key milestones and resource allocation.',\n  },\n  {\n    id: 2,\n    date: 'Mar 22, 2024',\n    title: 'Design Phase',\n    description:\n      'Completed wireframes and user interface mockups. Stakeholder review and feedback incorporated.',\n  },\n  {\n    id: 3,\n    date: 'Apr 5, 2024',\n    title: 'Development Sprint',\n    description: 'Backend API implementation and frontend component development in progress.',\n  },\n  {\n    id: 4,\n    date: 'Apr 19, 2024',\n    title: 'Testing & Deployment',\n    description:\n      'Quality assurance testing, performance optimization, and production deployment preparation.',\n  },\n]\n\nexport default function Component() {\n  return (\n    <Timeline defaultValue={3}>\n      {items.map((item) => (\n        <TimelineItem\n          key={item.id}\n          step={item.id}\n          className=\"group-data-[orientation=vertical]/timeline:ms-10\"\n        >\n          <TimelineHeader>\n            <TimelineSeparator className=\"group-data-[orientation=vertical]/timeline:-left-7 group-data-[orientation=vertical]/timeline:h-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=vertical]/timeline:translate-y-6.5\" />\n            <TimelineDate>{item.date}</TimelineDate>\n            <TimelineTitle>{item.title}</TimelineTitle>\n            <TimelineIndicator className=\"group-data-completed/timeline-item:bg-primary group-data-completed/timeline-item:text-primary-foreground flex size-6 items-center justify-center group-data-completed/timeline-item:border-none group-data-[orientation=vertical]/timeline:-left-7\">\n              <CheckIcon className=\"group-not-data-completed/timeline-item:hidden\" size={16} />\n            </TimelineIndicator>\n          </TimelineHeader>\n          <TimelineContent>{item.description}</TimelineContent>\n        </TimelineItem>\n      ))}\n    </Timeline>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/timeline/timeline-05.vue",
          "target": "components/ui/timeline-05.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { CheckIcon } from 'lucide-vue-next';\nimport { Timeline } from '@timui/vue';\nimport { TimelineContent } from '@timui/vue';\nimport { TimelineDate } from '@timui/vue';\nimport { TimelineHeader } from '@timui/vue';\nimport { TimelineIndicator } from '@timui/vue';\nimport { TimelineItem } from '@timui/vue';\nimport { TimelineSeparator } from '@timui/vue';\nimport { TimelineTitle } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: 1,\n    date: 'Mar 15, 2024',\n    title: 'Project Kickoff',\n    description:\n      'Initial team meeting and project scope definition. Established key milestones and resource allocation.',\n  },\n  {\n    id: 2,\n    date: 'Mar 22, 2024',\n    title: 'Design Phase',\n    description:\n      'Completed wireframes and user interface mockups. Stakeholder review and feedback incorporated.',\n  },\n  {\n    id: 3,\n    date: 'Apr 5, 2024',\n    title: 'Development Sprint',\n    description: 'Backend API implementation and frontend component development in progress.',\n  },\n  {\n    id: 4,\n    date: 'Apr 19, 2024',\n    title: 'Testing & Deployment',\n    description:\n      'Quality assurance testing, performance optimization, and production deployment preparation.',\n  },\n]\n\n</script>\n\n<template>\n  <Timeline :default-value=\"3\"><TimelineItem v-for=\"(item, index) in items\" :key=\"item.id\" :step=\"item.id\" class=\"group-data-[orientation=vertical]/timeline:ms-10\"><TimelineHeader><TimelineSeparator class=\"group-data-[orientation=vertical]/timeline:-left-7 group-data-[orientation=vertical]/timeline:h-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=vertical]/timeline:translate-y-6.5\" /><TimelineDate>{{ item.date }}</TimelineDate><TimelineTitle>{{ item.title }}</TimelineTitle><TimelineIndicator class=\"group-data-completed/timeline-item:bg-primary group-data-completed/timeline-item:text-primary-foreground flex size-6 items-center justify-center group-data-completed/timeline-item:border-none group-data-[orientation=vertical]/timeline:-left-7\"><CheckIcon class=\"group-not-data-completed/timeline-item:hidden\" :size=\"16\" /></TimelineIndicator></TimelineHeader><TimelineContent>{{ item.description }}</TimelineContent></TimelineItem></Timeline>\n</template>\n"
        },
        {
          "path": "registry/default/components/timeline/timeline-05.html",
          "target": "components/ui/timeline-05.html",
          "type": "registry:component",
          "content": "<template>\n  <Timeline default-value=\"${3}\"><!-- Loop items -->\n<TimelineItem key=\"${item.id}\" step=\"${item.id}\" class=\"group-data-[orientation=vertical]/timeline:ms-10\"><TimelineHeader><TimelineSeparator class=\"group-data-[orientation=vertical]/timeline:-left-7 group-data-[orientation=vertical]/timeline:h-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=vertical]/timeline:translate-y-6.5\" /><TimelineDate>${item.date}</TimelineDate><TimelineTitle>${item.title}</TimelineTitle><TimelineIndicator class=\"group-data-completed/timeline-item:bg-primary group-data-completed/timeline-item:text-primary-foreground flex size-6 items-center justify-center group-data-completed/timeline-item:border-none group-data-[orientation=vertical]/timeline:-left-7\"><CheckIcon class=\"group-not-data-completed/timeline-item:hidden\" size=\"${16}\" /></TimelineIndicator></TimelineHeader><TimelineContent>${item.description}</TimelineContent></TimelineItem>\n<!-- End Loop --></Timeline>\n</template>"
        },
        {
          "path": "registry/default/components/timeline/timeline-05.wxml",
          "target": "components/ui/timeline-05/timeline-05.wxml",
          "type": "registry:component",
          "content": "<view>\n  <timeline default-value=\"{{3}}\"><timelineitem wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{item.id}}\" step=\"{{item.id}}\" class=\"group-data-[orientation=vertical]/timeline:ms-10\"><timelineheader><timelineseparator class=\"group-data-[orientation=vertical]/timeline:-left-7 group-data-[orientation=vertical]/timeline:h-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=vertical]/timeline:translate-y-6.5\" /><timelinedate>{{ item.date }}</timelinedate><timelinetitle>{{ item.title }}</timelinetitle><timelineindicator class=\"group-data-completed/timeline-item:bg-primary group-data-completed/timeline-item:text-primary-foreground flex size-6 items-center justify-center group-data-completed/timeline-item:border-none group-data-[orientation=vertical]/timeline:-left-7\"><checkicon class=\"group-not-data-completed/timeline-item:hidden\" size=\"{{16}}\" /></timelineindicator></timelineheader><timelinecontent>{{ item.description }}</timelinecontent></timelineitem></timeline>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "timeline",
          "vertical timeline"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "timeline-05",
          "group": "timeline",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "timeline-05",
              "path": "registry/default/components/timeline/timeline-05.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "timeline-05",
              "path": "registry/default/components/timeline/timeline-05.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "timeline-05",
              "path": "registry/default/components/timeline/timeline-05.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "timeline-05",
              "path": "registry/default/components/timeline/timeline-05.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "timeline",
        "title": "Timeline · Detailed timeline"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "timeline"
      ]
    },
    {
      "name": "timeline-06",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/timeline.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/timeline/timeline-06.tsx",
          "type": "registry:component",
          "target": "components/ui/timeline-06.tsx",
          "content": "import {\n  Timeline,\n  TimelineContent,\n  TimelineDate,\n  TimelineHeader,\n  TimelineIndicator,\n  TimelineItem,\n  TimelineSeparator,\n  TimelineTitle,\n} from '@timui/react'\nimport { GitCompare, GitFork, GitMerge, GitPullRequest } from 'lucide-react'\n\nconst items = [\n  {\n    id: 1,\n    date: '15 minutes ago',\n    title: 'Forked Repository',\n    description: 'Forked the repository to create a new branch for development.',\n    icon: GitFork,\n  },\n  {\n    id: 2,\n    date: '10 minutes ago',\n    title: 'Pull Request Submitted',\n    description:\n      'Submitted PR #342 with new feature implementation. Waiting for code review from team leads.',\n    icon: GitPullRequest,\n  },\n  {\n    id: 3,\n    date: '5 minutes ago',\n    title: 'Comparing Branches',\n    description:\n      'Received comments on PR. Minor adjustments needed in error handling and documentation.',\n    icon: GitCompare,\n  },\n  {\n    id: 4,\n    title: 'Merged Branch',\n    description: 'Merged the feature branch into the main branch. Ready for deployment.',\n    icon: GitMerge,\n  },\n]\n\nexport default function Component() {\n  return (\n    <Timeline defaultValue={3}>\n      {items.map((item) => (\n        <TimelineItem\n          key={item.id}\n          step={item.id}\n          className=\"group-data-[orientation=vertical]/timeline:ms-10\"\n        >\n          <TimelineHeader>\n            <TimelineSeparator className=\"group-data-[orientation=vertical]/timeline:-left-7 group-data-[orientation=vertical]/timeline:h-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=vertical]/timeline:translate-y-6.5\" />\n            <TimelineTitle className=\"mt-0.5\">{item.title}</TimelineTitle>\n            <TimelineIndicator className=\"bg-primary/10 group-data-completed/timeline-item:bg-primary group-data-completed/timeline-item:text-primary-foreground flex size-6 items-center justify-center border-none group-data-[orientation=vertical]/timeline:-left-7\">\n              <item.icon size={14} />\n            </TimelineIndicator>\n          </TimelineHeader>\n          <TimelineContent>\n            {item.description}\n            <TimelineDate className=\"mt-2 mb-0\">{item.date}</TimelineDate>\n          </TimelineContent>\n        </TimelineItem>\n      ))}\n    </Timeline>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/timeline/timeline-06.vue",
          "target": "components/ui/timeline-06.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { GitCompare, GitFork, GitMerge, GitPullRequest } from 'lucide-vue-next';\nimport { Timeline } from '@timui/vue';\nimport { TimelineContent } from '@timui/vue';\nimport { TimelineDate } from '@timui/vue';\nimport { TimelineHeader } from '@timui/vue';\nimport { TimelineIndicator } from '@timui/vue';\nimport { TimelineItem } from '@timui/vue';\nimport { TimelineSeparator } from '@timui/vue';\nimport { TimelineTitle } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: 1,\n    date: '15 minutes ago',\n    title: 'Forked Repository',\n    description: 'Forked the repository to create a new branch for development.',\n    icon: GitFork,\n  },\n  {\n    id: 2,\n    date: '10 minutes ago',\n    title: 'Pull Request Submitted',\n    description:\n      'Submitted PR #342 with new feature implementation. Waiting for code review from team leads.',\n    icon: GitPullRequest,\n  },\n  {\n    id: 3,\n    date: '5 minutes ago',\n    title: 'Comparing Branches',\n    description:\n      'Received comments on PR. Minor adjustments needed in error handling and documentation.',\n    icon: GitCompare,\n  },\n  {\n    id: 4,\n    title: 'Merged Branch',\n    description: 'Merged the feature branch into the main branch. Ready for deployment.',\n    icon: GitMerge,\n  },\n]\n\n</script>\n\n<template>\n  <Timeline :default-value=\"3\"><TimelineItem v-for=\"(item, index) in items\" :key=\"item.id\" :step=\"item.id\" class=\"group-data-[orientation=vertical]/timeline:ms-10\"><TimelineHeader><TimelineSeparator class=\"group-data-[orientation=vertical]/timeline:-left-7 group-data-[orientation=vertical]/timeline:h-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=vertical]/timeline:translate-y-6.5\" /><TimelineTitle class=\"mt-0.5\">{{ item.title }}</TimelineTitle><TimelineIndicator class=\"bg-primary/10 group-data-completed/timeline-item:bg-primary group-data-completed/timeline-item:text-primary-foreground flex size-6 items-center justify-center border-none group-data-[orientation=vertical]/timeline:-left-7\"><item.icon :size=\"14\" /></TimelineIndicator></TimelineHeader><TimelineContent>{{ item.description }}<TimelineDate class=\"mt-2 mb-0\">{{ item.date }}</TimelineDate></TimelineContent></TimelineItem></Timeline>\n</template>\n"
        },
        {
          "path": "registry/default/components/timeline/timeline-06.html",
          "target": "components/ui/timeline-06.html",
          "type": "registry:component",
          "content": "<template>\n  <Timeline default-value=\"${3}\"><!-- Loop items -->\n<TimelineItem key=\"${item.id}\" step=\"${item.id}\" class=\"group-data-[orientation=vertical]/timeline:ms-10\"><TimelineHeader><TimelineSeparator class=\"group-data-[orientation=vertical]/timeline:-left-7 group-data-[orientation=vertical]/timeline:h-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=vertical]/timeline:translate-y-6.5\" /><TimelineTitle class=\"mt-0.5\">${item.title}</TimelineTitle><TimelineIndicator class=\"bg-primary/10 group-data-completed/timeline-item:bg-primary group-data-completed/timeline-item:text-primary-foreground flex size-6 items-center justify-center border-none group-data-[orientation=vertical]/timeline:-left-7\"><item.icon size=\"${14}\" /></TimelineIndicator></TimelineHeader><TimelineContent>${item.description}<TimelineDate class=\"mt-2 mb-0\">${item.date}</TimelineDate></TimelineContent></TimelineItem>\n<!-- End Loop --></Timeline>\n</template>"
        },
        {
          "path": "registry/default/components/timeline/timeline-06.wxml",
          "target": "components/ui/timeline-06/timeline-06.wxml",
          "type": "registry:component",
          "content": "<view>\n  <timeline default-value=\"{{3}}\"><timelineitem wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{item.id}}\" step=\"{{item.id}}\" class=\"group-data-[orientation=vertical]/timeline:ms-10\"><timelineheader><timelineseparator class=\"group-data-[orientation=vertical]/timeline:-left-7 group-data-[orientation=vertical]/timeline:h-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=vertical]/timeline:translate-y-6.5\" /><timelinetitle class=\"mt-0.5\">{{ item.title }}</timelinetitle><timelineindicator class=\"bg-primary/10 group-data-completed/timeline-item:bg-primary group-data-completed/timeline-item:text-primary-foreground flex size-6 items-center justify-center border-none group-data-[orientation=vertical]/timeline:-left-7\"><item.icon size=\"{{14}}\" /></timelineindicator></timelineheader><timelinecontent>{{ item.description }}<timelinedate class=\"mt-2 mb-0\">{{ item.date }}</timelinedate></timelinecontent></timelineitem></timeline>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "timeline",
          "vertical timeline"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "timeline-06",
          "group": "timeline",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "timeline-06",
              "path": "registry/default/components/timeline/timeline-06.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "timeline-06",
              "path": "registry/default/components/timeline/timeline-06.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "timeline-06",
              "path": "registry/default/components/timeline/timeline-06.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "timeline-06",
              "path": "registry/default/components/timeline/timeline-06.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "timeline",
        "title": "Timeline · Detailed timeline"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "timeline"
      ]
    },
    {
      "name": "timeline-07",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/timeline.json"
      ],
      "files": [
        {
          "path": "registry/default/components/timeline/timeline-07.tsx",
          "type": "registry:component",
          "target": "components/ui/timeline-07.tsx",
          "content": "import {\n  Timeline,\n  TimelineContent,\n  TimelineDate,\n  TimelineHeader,\n  TimelineIndicator,\n  TimelineItem,\n  TimelineSeparator,\n  TimelineTitle,\n} from '@timui/react'\n\nconst items = [\n  {\n    id: 1,\n    date: '15 minutes ago',\n    title: 'Hannah Kandell',\n    action: 'opened a new issue',\n    description: \"I'm having trouble with the new component library. It's not rendering properly.\",\n    image: '/avatar-40-01.jpg',\n  },\n  {\n    id: 2,\n    date: '10 minutes ago',\n    title: 'Chris Tompson',\n    action: 'commented on',\n    description:\n      \"Hey Hannah, I'm having trouble with the new component library. It's not rendering properly.\",\n    image: '/avatar-40-02.jpg',\n  },\n  {\n    id: 3,\n    date: '5 minutes ago',\n    title: 'Emma Davis',\n    action: 'assigned you to',\n    description: 'The new component library is not rendering properly. Can you take a look?',\n    image: '/avatar-40-03.jpg',\n  },\n  {\n    id: 4,\n    date: '2 minutes ago',\n    title: 'Alex Morgan',\n    action: 'closed the issue',\n    description: 'The issue has been fixed. Please review the changes.',\n    image: '/avatar-40-05.jpg',\n  },\n]\n\nexport default function Component() {\n  return (\n    <Timeline>\n      {items.map((item) => (\n        <TimelineItem\n          key={item.id}\n          step={item.id}\n          className=\"group-data-[orientation=vertical]/timeline:ms-10 group-data-[orientation=vertical]/timeline:not-last:pb-8\"\n        >\n          <TimelineHeader>\n            <TimelineSeparator className=\"group-data-[orientation=vertical]/timeline:-left-7 group-data-[orientation=vertical]/timeline:h-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=vertical]/timeline:translate-y-6.5\" />\n            <TimelineTitle className=\"mt-0.5\">\n              {item.title}{' '}\n              <span className=\"text-muted-foreground text-sm font-normal\">{item.action}</span>\n            </TimelineTitle>\n            <TimelineIndicator className=\"bg-primary/10 group-data-completed/timeline-item:bg-primary group-data-completed/timeline-item:text-primary-foreground flex size-6 items-center justify-center border-none group-data-[orientation=vertical]/timeline:-left-7\">\n              <img src={item.image} alt={item.title} className=\"size-6 rounded-full\" />\n            </TimelineIndicator>\n          </TimelineHeader>\n          <TimelineContent className=\"text-foreground mt-2 rounded-lg border px-4 py-3\">\n            {item.description}\n            <TimelineDate className=\"mt-1 mb-0\">{item.date}</TimelineDate>\n          </TimelineContent>\n        </TimelineItem>\n      ))}\n    </Timeline>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/timeline/timeline-07.vue",
          "target": "components/ui/timeline-07.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Timeline } from '@timui/vue';\nimport { TimelineContent } from '@timui/vue';\nimport { TimelineDate } from '@timui/vue';\nimport { TimelineHeader } from '@timui/vue';\nimport { TimelineIndicator } from '@timui/vue';\nimport { TimelineItem } from '@timui/vue';\nimport { TimelineSeparator } from '@timui/vue';\nimport { TimelineTitle } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: 1,\n    date: '15 minutes ago',\n    title: 'Hannah Kandell',\n    action: 'opened a new issue',\n    description: \"I'm having trouble with the new component library. It's not rendering properly.\",\n    image: '/avatar-40-01.jpg',\n  },\n  {\n    id: 2,\n    date: '10 minutes ago',\n    title: 'Chris Tompson',\n    action: 'commented on',\n    description:\n      \"Hey Hannah, I'm having trouble with the new component library. It's not rendering properly.\",\n    image: '/avatar-40-02.jpg',\n  },\n  {\n    id: 3,\n    date: '5 minutes ago',\n    title: 'Emma Davis',\n    action: 'assigned you to',\n    description: 'The new component library is not rendering properly. Can you take a look?',\n    image: '/avatar-40-03.jpg',\n  },\n  {\n    id: 4,\n    date: '2 minutes ago',\n    title: 'Alex Morgan',\n    action: 'closed the issue',\n    description: 'The issue has been fixed. Please review the changes.',\n    image: '/avatar-40-05.jpg',\n  },\n]\n\n</script>\n\n<template>\n  <Timeline><TimelineItem v-for=\"(item, index) in items\" :key=\"item.id\" :step=\"item.id\" class=\"group-data-[orientation=vertical]/timeline:ms-10 group-data-[orientation=vertical]/timeline:not-last:pb-8\"><TimelineHeader><TimelineSeparator class=\"group-data-[orientation=vertical]/timeline:-left-7 group-data-[orientation=vertical]/timeline:h-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=vertical]/timeline:translate-y-6.5\" /><TimelineTitle class=\"mt-0.5\">{{ item.title }}{{ ' ' }}<span class=\"text-muted-foreground text-sm font-normal\">{{ item.action }}</span></TimelineTitle><TimelineIndicator class=\"bg-primary/10 group-data-completed/timeline-item:bg-primary group-data-completed/timeline-item:text-primary-foreground flex size-6 items-center justify-center border-none group-data-[orientation=vertical]/timeline:-left-7\"><img :src=\"item.image\" :alt=\"item.title\" class=\"size-6 rounded-full\" /></TimelineIndicator></TimelineHeader><TimelineContent class=\"text-foreground mt-2 rounded-lg border px-4 py-3\">{{ item.description }}<TimelineDate class=\"mt-1 mb-0\">{{ item.date }}</TimelineDate></TimelineContent></TimelineItem></Timeline>\n</template>\n"
        },
        {
          "path": "registry/default/components/timeline/timeline-07.html",
          "target": "components/ui/timeline-07.html",
          "type": "registry:component",
          "content": "<template>\n  <Timeline><!-- Loop items -->\n<TimelineItem key=\"${item.id}\" step=\"${item.id}\" class=\"group-data-[orientation=vertical]/timeline:ms-10 group-data-[orientation=vertical]/timeline:not-last:pb-8\"><TimelineHeader><TimelineSeparator class=\"group-data-[orientation=vertical]/timeline:-left-7 group-data-[orientation=vertical]/timeline:h-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=vertical]/timeline:translate-y-6.5\" /><TimelineTitle class=\"mt-0.5\">${item.title}${' '}<span class=\"text-muted-foreground text-sm font-normal\">${item.action}</span></TimelineTitle><TimelineIndicator class=\"bg-primary/10 group-data-completed/timeline-item:bg-primary group-data-completed/timeline-item:text-primary-foreground flex size-6 items-center justify-center border-none group-data-[orientation=vertical]/timeline:-left-7\"><img src=\"${item.image}\" alt=\"${item.title}\" class=\"size-6 rounded-full\" /></TimelineIndicator></TimelineHeader><TimelineContent class=\"text-foreground mt-2 rounded-lg border px-4 py-3\">${item.description}<TimelineDate class=\"mt-1 mb-0\">${item.date}</TimelineDate></TimelineContent></TimelineItem>\n<!-- End Loop --></Timeline>\n</template>"
        },
        {
          "path": "registry/default/components/timeline/timeline-07.wxml",
          "target": "components/ui/timeline-07/timeline-07.wxml",
          "type": "registry:component",
          "content": "<view>\n  <timeline><timelineitem wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{item.id}}\" step=\"{{item.id}}\" class=\"group-data-[orientation=vertical]/timeline:ms-10 group-data-[orientation=vertical]/timeline:not-last:pb-8\"><timelineheader><timelineseparator class=\"group-data-[orientation=vertical]/timeline:-left-7 group-data-[orientation=vertical]/timeline:h-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=vertical]/timeline:translate-y-6.5\" /><timelinetitle class=\"mt-0.5\">{{ item.title }}{{ ' ' }}<text class=\"text-muted-foreground text-sm font-normal\">{{ item.action }}</text></timelinetitle><timelineindicator class=\"bg-primary/10 group-data-completed/timeline-item:bg-primary group-data-completed/timeline-item:text-primary-foreground flex size-6 items-center justify-center border-none group-data-[orientation=vertical]/timeline:-left-7\"><image src=\"{{item.image}}\" alt=\"{{item.title}}\" class=\"size-6 rounded-full\" /></timelineindicator></timelineheader><timelinecontent class=\"text-foreground mt-2 rounded-lg border px-4 py-3\">{{ item.description }}<timelinedate class=\"mt-1 mb-0\">{{ item.date }}</timelinedate></timelinecontent></timelineitem></timeline>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "timeline",
          "vertical timeline"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "timeline-07",
          "group": "timeline",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "timeline-07",
              "path": "registry/default/components/timeline/timeline-07.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "timeline-07",
              "path": "registry/default/components/timeline/timeline-07.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "timeline-07",
              "path": "registry/default/components/timeline/timeline-07.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "timeline-07",
              "path": "registry/default/components/timeline/timeline-07.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "timeline",
        "title": "Timeline · Detailed timeline"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "timeline"
      ]
    },
    {
      "name": "timeline-08",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/timeline.json"
      ],
      "files": [
        {
          "path": "registry/default/components/timeline/timeline-08.tsx",
          "type": "registry:component",
          "target": "components/ui/timeline-08.tsx",
          "content": "import {\n  Timeline,\n  TimelineDate,\n  TimelineHeader,\n  TimelineIndicator,\n  TimelineItem,\n  TimelineSeparator,\n  TimelineTitle,\n} from '@timui/react'\n\nconst items = [\n  {\n    id: 1,\n    date: 'Mar 15, 2024',\n    title: 'Project Kickoff',\n  },\n  {\n    id: 2,\n    date: 'Mar 22, 2024',\n    title: 'Design Phase',\n  },\n  {\n    id: 3,\n    date: 'Apr 5, 2024',\n    title: 'Development Sprint',\n  },\n  {\n    id: 4,\n    date: 'Apr 19, 2024',\n    title: 'Testing & Deployment',\n  },\n  {\n    id: 5,\n    date: 'May 3, 2024',\n    title: 'User Training',\n  },\n  {\n    id: 6,\n    date: 'May 17, 2024',\n    title: 'Project Handover',\n  },\n]\n\nexport default function Component() {\n  return (\n    <Timeline defaultValue={3}>\n      {items.map((item) => (\n        <TimelineItem\n          key={item.id}\n          step={item.id}\n          className=\"w-[calc(50%-1.5rem)] odd:ms-auto even:text-right even:group-data-[orientation=vertical]/timeline:ms-0 even:group-data-[orientation=vertical]/timeline:me-8 even:group-data-[orientation=vertical]/timeline:[&_[data-slot=timeline-indicator]]:-right-6 even:group-data-[orientation=vertical]/timeline:[&_[data-slot=timeline-indicator]]:left-auto even:group-data-[orientation=vertical]/timeline:[&_[data-slot=timeline-indicator]]:translate-x-1/2 even:group-data-[orientation=vertical]/timeline:[&_[data-slot=timeline-separator]]:-right-6 even:group-data-[orientation=vertical]/timeline:[&_[data-slot=timeline-separator]]:left-auto even:group-data-[orientation=vertical]/timeline:[&_[data-slot=timeline-separator]]:translate-x-1/2\"\n        >\n          <TimelineHeader>\n            <TimelineSeparator />\n            <TimelineDate>{item.date}</TimelineDate>\n            <TimelineTitle>{item.title}</TimelineTitle>\n            <TimelineIndicator />\n          </TimelineHeader>\n        </TimelineItem>\n      ))}\n    </Timeline>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/timeline/timeline-08.vue",
          "target": "components/ui/timeline-08.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Timeline } from '@timui/vue';\nimport { TimelineDate } from '@timui/vue';\nimport { TimelineHeader } from '@timui/vue';\nimport { TimelineIndicator } from '@timui/vue';\nimport { TimelineItem } from '@timui/vue';\nimport { TimelineSeparator } from '@timui/vue';\nimport { TimelineTitle } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: 1,\n    date: 'Mar 15, 2024',\n    title: 'Project Kickoff',\n  },\n  {\n    id: 2,\n    date: 'Mar 22, 2024',\n    title: 'Design Phase',\n  },\n  {\n    id: 3,\n    date: 'Apr 5, 2024',\n    title: 'Development Sprint',\n  },\n  {\n    id: 4,\n    date: 'Apr 19, 2024',\n    title: 'Testing & Deployment',\n  },\n  {\n    id: 5,\n    date: 'May 3, 2024',\n    title: 'User Training',\n  },\n  {\n    id: 6,\n    date: 'May 17, 2024',\n    title: 'Project Handover',\n  },\n]\n\n</script>\n\n<template>\n  <Timeline :default-value=\"3\"><TimelineItem v-for=\"(item, index) in items\" :key=\"item.id\" :step=\"item.id\" class=\"w-[calc(50%-1.5rem)] odd:ms-auto even:text-right even:group-data-[orientation=vertical]/timeline:ms-0 even:group-data-[orientation=vertical]/timeline:me-8 even:group-data-[orientation=vertical]/timeline:[&_[data-slot=timeline-indicator]]:-right-6 even:group-data-[orientation=vertical]/timeline:[&_[data-slot=timeline-indicator]]:left-auto even:group-data-[orientation=vertical]/timeline:[&_[data-slot=timeline-indicator]]:translate-x-1/2 even:group-data-[orientation=vertical]/timeline:[&_[data-slot=timeline-separator]]:-right-6 even:group-data-[orientation=vertical]/timeline:[&_[data-slot=timeline-separator]]:left-auto even:group-data-[orientation=vertical]/timeline:[&_[data-slot=timeline-separator]]:translate-x-1/2\"><TimelineHeader><TimelineSeparator /><TimelineDate>{{ item.date }}</TimelineDate><TimelineTitle>{{ item.title }}</TimelineTitle><TimelineIndicator /></TimelineHeader></TimelineItem></Timeline>\n</template>\n"
        },
        {
          "path": "registry/default/components/timeline/timeline-08.html",
          "target": "components/ui/timeline-08.html",
          "type": "registry:component",
          "content": "<template>\n  <Timeline default-value=\"${3}\"><!-- Loop items -->\n<TimelineItem key=\"${item.id}\" step=\"${item.id}\" class=\"w-[calc(50%-1.5rem)] odd:ms-auto even:text-right even:group-data-[orientation=vertical]/timeline:ms-0 even:group-data-[orientation=vertical]/timeline:me-8 even:group-data-[orientation=vertical]/timeline:[&_[data-slot=timeline-indicator]]:-right-6 even:group-data-[orientation=vertical]/timeline:[&_[data-slot=timeline-indicator]]:left-auto even:group-data-[orientation=vertical]/timeline:[&_[data-slot=timeline-indicator]]:translate-x-1/2 even:group-data-[orientation=vertical]/timeline:[&_[data-slot=timeline-separator]]:-right-6 even:group-data-[orientation=vertical]/timeline:[&_[data-slot=timeline-separator]]:left-auto even:group-data-[orientation=vertical]/timeline:[&_[data-slot=timeline-separator]]:translate-x-1/2\"><TimelineHeader><TimelineSeparator /><TimelineDate>${item.date}</TimelineDate><TimelineTitle>${item.title}</TimelineTitle><TimelineIndicator /></TimelineHeader></TimelineItem>\n<!-- End Loop --></Timeline>\n</template>"
        },
        {
          "path": "registry/default/components/timeline/timeline-08.wxml",
          "target": "components/ui/timeline-08/timeline-08.wxml",
          "type": "registry:component",
          "content": "<view>\n  <timeline default-value=\"{{3}}\"><timelineitem wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{item.id}}\" step=\"{{item.id}}\" class=\"w-[calc(50%-1.5rem)] odd:ms-auto even:text-right even:group-data-[orientation=vertical]/timeline:ms-0 even:group-data-[orientation=vertical]/timeline:me-8 even:group-data-[orientation=vertical]/timeline:[&_[data-slot=timeline-indicator]]:-right-6 even:group-data-[orientation=vertical]/timeline:[&_[data-slot=timeline-indicator]]:left-auto even:group-data-[orientation=vertical]/timeline:[&_[data-slot=timeline-indicator]]:translate-x-1/2 even:group-data-[orientation=vertical]/timeline:[&_[data-slot=timeline-separator]]:-right-6 even:group-data-[orientation=vertical]/timeline:[&_[data-slot=timeline-separator]]:left-auto even:group-data-[orientation=vertical]/timeline:[&_[data-slot=timeline-separator]]:translate-x-1/2\"><timelineheader><timelineseparator /><timelinedate>{{ item.date }}</timelinedate><timelinetitle>{{ item.title }}</timelinetitle><timelineindicator /></timelineheader></timelineitem></timeline>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "timeline",
          "vertical timeline"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "timeline-08",
          "group": "timeline",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "timeline-08",
              "path": "registry/default/components/timeline/timeline-08.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "timeline-08",
              "path": "registry/default/components/timeline/timeline-08.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "timeline-08",
              "path": "registry/default/components/timeline/timeline-08.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "timeline-08",
              "path": "registry/default/components/timeline/timeline-08.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "timeline",
        "title": "Timeline · Timeline with dates"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "timeline"
      ]
    },
    {
      "name": "timeline-09",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/timeline.json"
      ],
      "files": [
        {
          "path": "registry/default/components/timeline/timeline-09.tsx",
          "type": "registry:component",
          "target": "components/ui/timeline-09.tsx",
          "content": "import { Timeline, TimelineContent, TimelineDate, TimelineItem } from '@timui/react'\n\nconst items = [\n  {\n    id: 1,\n    date: new Date('2024-01-09T10:55:00'),\n    description: 'System backup completed successfully.',\n  },\n  {\n    id: 2,\n    date: new Date('2024-01-09T10:50:00'),\n    description: 'User authentication service restarted due to configuration update.',\n  },\n  {\n    id: 3,\n    date: new Date('2024-01-09T10:45:00'),\n    description: 'Warning: High CPU usage detected on worker node-03.',\n  },\n  {\n    id: 4,\n    date: new Date('2024-01-09T10:40:00'),\n    description: 'New deployment initiated for api-service v2.1.0.',\n  },\n]\n\nexport default function Component() {\n  return (\n    <Timeline className=\"divide-y rounded-lg border\">\n      {items.map((item) => (\n        <TimelineItem key={item.id} step={item.id} className=\"m-0! px-4! py-3!\">\n          <TimelineContent className=\"text-foreground\">\n            {item.description}\n            <TimelineDate className=\"mt-1\">\n              {item.date.toLocaleDateString('en-US', {\n                year: 'numeric',\n                month: 'long',\n                day: 'numeric',\n              })}{' '}\n              at{' '}\n              {item.date.toLocaleTimeString('en-US', {\n                hour: 'numeric',\n                minute: '2-digit',\n                hour12: true,\n              })}\n            </TimelineDate>\n          </TimelineContent>\n        </TimelineItem>\n      ))}\n    </Timeline>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/timeline/timeline-09.vue",
          "target": "components/ui/timeline-09.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Timeline } from '@timui/vue';\nimport { TimelineContent } from '@timui/vue';\nimport { TimelineDate } from '@timui/vue';\nimport { TimelineItem } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: 1,\n    date: new Date('2024-01-09T10:55:00'),\n    description: 'System backup completed successfully.',\n  },\n  {\n    id: 2,\n    date: new Date('2024-01-09T10:50:00'),\n    description: 'User authentication service restarted due to configuration update.',\n  },\n  {\n    id: 3,\n    date: new Date('2024-01-09T10:45:00'),\n    description: 'Warning: High CPU usage detected on worker node-03.',\n  },\n  {\n    id: 4,\n    date: new Date('2024-01-09T10:40:00'),\n    description: 'New deployment initiated for api-service v2.1.0.',\n  },\n]\n\n</script>\n\n<template>\n  <Timeline class=\"divide-y rounded-lg border\"><TimelineItem v-for=\"(item, index) in items\" :key=\"item.id\" :step=\"item.id\" class=\"m-0! px-4! py-3!\"><TimelineContent class=\"text-foreground\">{{ item.description }}<TimelineDate class=\"mt-1\">{{ item.date.toLocaleDateString('en-US', {\n                year: 'numeric',\n                month: 'long',\n                day: 'numeric',\n              }) }}{{ ' ' }}at{{ ' ' }}{{ item.date.toLocaleTimeString('en-US', {\n                hour: 'numeric',\n                minute: '2-digit',\n                hour12: true,\n              }) }}</TimelineDate></TimelineContent></TimelineItem></Timeline>\n</template>\n"
        },
        {
          "path": "registry/default/components/timeline/timeline-09.html",
          "target": "components/ui/timeline-09.html",
          "type": "registry:component",
          "content": "<template>\n  <Timeline class=\"divide-y rounded-lg border\"><!-- Loop items -->\n<TimelineItem key=\"${item.id}\" step=\"${item.id}\" class=\"m-0! px-4! py-3!\"><TimelineContent class=\"text-foreground\">${item.description}<TimelineDate class=\"mt-1\">${item.date.toLocaleDateString('en-US', {\n                year: 'numeric',\n                month: 'long',\n                day: 'numeric',\n              })}${' '}at${' '}${item.date.toLocaleTimeString('en-US', {\n                hour: 'numeric',\n                minute: '2-digit',\n                hour12: true,\n              })}</TimelineDate></TimelineContent></TimelineItem>\n<!-- End Loop --></Timeline>\n</template>"
        },
        {
          "path": "registry/default/components/timeline/timeline-09.wxml",
          "target": "components/ui/timeline-09/timeline-09.wxml",
          "type": "registry:component",
          "content": "<view>\n  <timeline class=\"divide-y rounded-lg border\"><timelineitem wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{item.id}}\" step=\"{{item.id}}\" class=\"m-0! px-4! py-3!\"><timelinecontent class=\"text-foreground\">{{ item.description }}<timelinedate class=\"mt-1\">{{ item.date.toLocaleDateString('en-US', {\n                year: 'numeric',\n                month: 'long',\n                day: 'numeric',\n              }) }}{{ ' ' }}at{{ ' ' }}{{ item.date.toLocaleTimeString('en-US', {\n                hour: 'numeric',\n                minute: '2-digit',\n                hour12: true,\n              }) }}</timelinedate></timelinecontent></timelineitem></timeline>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "timeline",
          "vertical timeline"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "timeline-09",
          "group": "timeline",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "timeline-09",
              "path": "registry/default/components/timeline/timeline-09.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "timeline-09",
              "path": "registry/default/components/timeline/timeline-09.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "timeline-09",
              "path": "registry/default/components/timeline/timeline-09.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "timeline-09",
              "path": "registry/default/components/timeline/timeline-09.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "timeline",
        "title": "Timeline · Detailed timeline"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "timeline"
      ]
    },
    {
      "name": "timeline-10",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/timeline.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/timeline/timeline-10.tsx",
          "type": "registry:component",
          "target": "components/ui/timeline-10.tsx",
          "content": "import { Timeline, TimelineContent, TimelineItem } from '@timui/react'\nimport { BookOpenIcon, LucideIcon, MessageCircleIcon, PencilIcon, PlusIcon } from 'lucide-react'\n\nconst items: {\n  id: number\n  user: string\n  image: string\n  action: ActionType\n  date: Date\n}[] = [\n  {\n    id: 1,\n    user: 'Matt',\n    image: '/avatar-40-02.jpg',\n    action: 'post',\n    date: new Date(Date.now() - 59000), // 59 seconds ago\n  },\n  {\n    id: 2,\n    user: 'Matt',\n    image: '/avatar-40-02.jpg',\n    action: 'reply',\n    date: new Date(Date.now() - 180000), // 3 minutes ago\n  },\n  {\n    id: 3,\n    user: 'Matt',\n    image: '/avatar-40-02.jpg',\n    action: 'edit',\n    date: new Date(Date.now() - 300000), // 5 minutes ago\n  },\n  {\n    id: 4,\n    user: 'Matt',\n    image: '/avatar-40-02.jpg',\n    action: 'create',\n    date: new Date(Date.now() - 600000), // 10 minutes ago\n  },\n]\n\ntype ActionType = 'post' | 'reply' | 'edit' | 'create'\n\nfunction getActionIcon(action: ActionType): LucideIcon {\n  const icons: Record<ActionType, LucideIcon> = {\n    post: BookOpenIcon,\n    reply: MessageCircleIcon,\n    edit: PencilIcon,\n    create: PlusIcon,\n  }\n  return icons[action]\n}\n\nfunction getActionText(action: ActionType): string {\n  const texts: Record<ActionType, string> = {\n    post: 'wrote a new post',\n    reply: 'replied to a comment',\n    edit: 'edited a post',\n    create: 'created a new project',\n  }\n  return texts[action]\n}\n\nfunction getRelativeTimeString(date: Date): string {\n  const now = new Date()\n  const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000)\n\n  if (diffInSeconds < 60) {\n    return `${diffInSeconds} seconds ago`\n  } else if (diffInSeconds < 3600) {\n    const minutes = Math.floor(diffInSeconds / 60)\n    return `${minutes} ${minutes === 1 ? 'minute' : 'minutes'} ago`\n  } else if (diffInSeconds < 86400) {\n    const hours = Math.floor(diffInSeconds / 3600)\n    return `${hours} ${hours === 1 ? 'hour' : 'hours'} ago`\n  } else {\n    const days = Math.floor(diffInSeconds / 86400)\n    return `${days} ${days === 1 ? 'day' : 'days'} ago`\n  }\n}\n\nexport default function Component() {\n  return (\n    <div className=\"space-y-3\">\n      <div className=\"text-muted-foreground text-xs font-medium\">Activity</div>\n      <Timeline>\n        {items.map((item) => {\n          const ActionIcon = getActionIcon(item.action)\n          return (\n            <TimelineItem\n              key={item.id}\n              step={item.id}\n              className=\"m-0! flex-row items-center gap-3 py-2.5!\"\n            >\n              <ActionIcon className=\"text-muted-foreground/80\" size={16} />\n              <img src={item.image} alt={item.user} className=\"size-6 rounded-full\" />\n              <TimelineContent className=\"text-foreground\">\n                <a className=\"font-medium hover:underline\" href=\"#\">\n                  {item.user}\n                </a>\n                <span className=\"font-normal\">\n                  {' '}\n                  {getActionText(item.action)}{' '}\n                  <a className=\"hover:underline\" href=\"#\">\n                    {getRelativeTimeString(item.date)}\n                  </a>\n                </span>\n              </TimelineContent>\n            </TimelineItem>\n          )\n        })}\n      </Timeline>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/timeline/timeline-10.vue",
          "target": "components/ui/timeline-10.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { BookOpenIcon, MessageCircleIcon, PencilIcon, PlusIcon } from 'lucide-vue-next'\nimport { Timeline } from '@timui/vue'\nimport { TimelineContent } from '@timui/vue'\nimport { TimelineItem } from '@timui/vue'\n\ntype ActionType = 'post' | 'reply' | 'edit' | 'create'\n\ntype ActivityItem = {\n  id: number\n  user: string\n  image: string\n  action: ActionType\n  date: Date\n}\n\nconst items: ActivityItem[] = [\n  {\n    id: 1,\n    user: 'Matt',\n    image: '/avatar-40-02.jpg',\n    action: 'post',\n    date: new Date(Date.now() - 59000),\n  },\n  {\n    id: 2,\n    user: 'Matt',\n    image: '/avatar-40-02.jpg',\n    action: 'reply',\n    date: new Date(Date.now() - 180000),\n  },\n  {\n    id: 3,\n    user: 'Matt',\n    image: '/avatar-40-02.jpg',\n    action: 'edit',\n    date: new Date(Date.now() - 300000),\n  },\n  {\n    id: 4,\n    user: 'Matt',\n    image: '/avatar-40-02.jpg',\n    action: 'create',\n    date: new Date(Date.now() - 600000),\n  },\n]\n\nconst iconMap = {\n  post: BookOpenIcon,\n  reply: MessageCircleIcon,\n  edit: PencilIcon,\n  create: PlusIcon,\n} as const\n\nconst textMap: Record<ActionType, string> = {\n  post: 'wrote a new post',\n  reply: 'replied to a comment',\n  edit: 'edited a post',\n  create: 'created a new project',\n}\n\nconst getRelativeTimeString = (date: Date): string => {\n  const now = new Date()\n  const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000)\n\n  if (diffInSeconds < 60) {\n    return `${diffInSeconds} seconds ago`\n  }\n\n  if (diffInSeconds < 3600) {\n    const minutes = Math.floor(diffInSeconds / 60)\n    return `${minutes} ${minutes === 1 ? 'minute' : 'minutes'} ago`\n  }\n\n  if (diffInSeconds < 86400) {\n    const hours = Math.floor(diffInSeconds / 3600)\n    return `${hours} ${hours === 1 ? 'hour' : 'hours'} ago`\n  }\n\n  const days = Math.floor(diffInSeconds / 86400)\n  return `${days} ${days === 1 ? 'day' : 'days'} ago`\n}\n</script>\n\n<template>\n  <div class=\"space-y-3\">\n    <div class=\"text-muted-foreground text-xs font-medium\">Activity</div>\n    <Timeline>\n      <TimelineItem\n        v-for=\"item in items\"\n        :key=\"item.id\"\n        :step=\"item.id\"\n        class=\"m-0! flex-row items-center gap-3 py-2.5!\"\n      >\n        <component :is=\"iconMap[item.action]\" class=\"text-muted-foreground/80\" :size=\"16\" />\n        <img :src=\"item.image\" :alt=\"item.user\" class=\"size-6 rounded-full\" />\n        <TimelineContent class=\"text-foreground\">\n          <a class=\"font-medium hover:underline\" href=\"#\">{{ item.user }}</a>\n          <span class=\"font-normal\">\n            {{ ' ' }}{{ textMap[item.action] }}{{ ' ' }}\n            <a class=\"hover:underline\" href=\"#\">{{ getRelativeTimeString(item.date) }}</a>\n          </span>\n        </TimelineContent>\n      </TimelineItem>\n    </Timeline>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/timeline/timeline-10.html",
          "target": "components/ui/timeline-10.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"space-y-3\"><div class=\"text-muted-foreground text-xs font-medium\">Activity</div><Timeline>${items.map((item) => {\n          const ActionIcon = getActionIcon(item.action)\n          return (\n            <TimelineItem\n              key={item.id}\n              step={item.id}\n              className=\"m-0! flex-row items-center gap-3 py-2.5!\"\n            >\n              <ActionIcon className=\"text-muted-foreground/80\" size={16} />\n              <img src={item.image} alt={item.user} className=\"size-6 rounded-full\" />\n              <TimelineContent className=\"text-foreground\">\n                <a className=\"font-medium hover:underline\" href=\"#\">\n                  {item.user}\n                </a>\n                <span className=\"font-normal\">\n                  {' '}\n                  {getActionText(item.action)}{' '}\n                  <a className=\"hover:underline\" href=\"#\">\n                    {getRelativeTimeString(item.date)}\n                  </a>\n                </span>\n              </TimelineContent>\n            </TimelineItem>\n          )\n        })}</Timeline></div>\n</template>"
        },
        {
          "path": "registry/default/components/timeline/timeline-10.wxml",
          "target": "components/ui/timeline-10/timeline-10.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"space-y-3\"><view class=\"text-muted-foreground text-xs font-medium\">Activity</view><timeline>{{ items.map((item) => {\n          const ActionIcon = getActionIcon(item.action)\n          return (\n            <TimelineItem\n              key={item.id}\n              step={item.id}\n              className=\"m-0! flex-row items-center gap-3 py-2.5!\"\n            >\n              <ActionIcon className=\"text-muted-foreground/80\" size={16} />\n              <img src={item.image} alt={item.user} className=\"size-6 rounded-full\" />\n              <TimelineContent className=\"text-foreground\">\n                <a className=\"font-medium hover:underline\" href=\"#\">\n                  {item.user}\n                </a>\n                <span className=\"font-normal\">\n                  {' '}\n                  {getActionText(item.action)}{' '}\n                  <a className=\"hover:underline\" href=\"#\">\n                    {getRelativeTimeString(item.date)}\n                  </a>\n                </span>\n              </TimelineContent>\n            </TimelineItem>\n          )\n        }) }}</timeline></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "timeline",
          "vertical timeline"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "timeline-10",
          "group": "timeline",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "timeline-10",
              "path": "registry/default/components/timeline/timeline-10.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "timeline-10",
              "path": "registry/default/components/timeline/timeline-10.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "timeline-10",
              "path": "registry/default/components/timeline/timeline-10.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "timeline-10",
              "path": "registry/default/components/timeline/timeline-10.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "timeline",
        "title": "Timeline · Timeline with content"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "timeline"
      ]
    },
    {
      "name": "timeline-11",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/timeline.json"
      ],
      "files": [
        {
          "path": "registry/default/components/timeline/timeline-11.tsx",
          "type": "registry:component",
          "target": "components/ui/timeline-11.tsx",
          "content": "import {\n  Timeline,\n  TimelineContent,\n  TimelineDate,\n  TimelineHeader,\n  TimelineIndicator,\n  TimelineItem,\n  TimelineSeparator,\n  TimelineTitle,\n} from '@timui/react'\n\nconst items = [\n  {\n    id: 1,\n    date: 'Mar 15, 2024',\n    title: 'Project Kickoff',\n    description: 'Initial team meeting.',\n  },\n  {\n    id: 2,\n    date: 'Mar 22, 2024',\n    title: 'Design Phase',\n    description: 'Completed wireframes.',\n  },\n  {\n    id: 3,\n    date: 'Apr 5, 2024',\n    title: 'Development Sprint',\n    description: 'Backend development.',\n  },\n  {\n    id: 4,\n    date: 'Apr 19, 2024',\n    title: 'Testing & Deployment',\n    description: 'Performance optimization.',\n  },\n]\n\nexport default function Component() {\n  return (\n    <Timeline defaultValue={3} orientation=\"horizontal\">\n      {items.map((item) => (\n        <TimelineItem key={item.id} step={item.id}>\n          <TimelineHeader>\n            <TimelineSeparator />\n            <TimelineDate>{item.date}</TimelineDate>\n            <TimelineTitle>{item.title}</TimelineTitle>\n            <TimelineIndicator />\n          </TimelineHeader>\n          <TimelineContent>{item.description}</TimelineContent>\n        </TimelineItem>\n      ))}\n    </Timeline>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/timeline/timeline-11.vue",
          "target": "components/ui/timeline-11.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Timeline } from '@timui/vue';\nimport { TimelineContent } from '@timui/vue';\nimport { TimelineDate } from '@timui/vue';\nimport { TimelineHeader } from '@timui/vue';\nimport { TimelineIndicator } from '@timui/vue';\nimport { TimelineItem } from '@timui/vue';\nimport { TimelineSeparator } from '@timui/vue';\nimport { TimelineTitle } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: 1,\n    date: 'Mar 15, 2024',\n    title: 'Project Kickoff',\n    description: 'Initial team meeting.',\n  },\n  {\n    id: 2,\n    date: 'Mar 22, 2024',\n    title: 'Design Phase',\n    description: 'Completed wireframes.',\n  },\n  {\n    id: 3,\n    date: 'Apr 5, 2024',\n    title: 'Development Sprint',\n    description: 'Backend development.',\n  },\n  {\n    id: 4,\n    date: 'Apr 19, 2024',\n    title: 'Testing & Deployment',\n    description: 'Performance optimization.',\n  },\n]\n\n</script>\n\n<template>\n  <Timeline :default-value=\"3\" orientation=\"horizontal\"><TimelineItem v-for=\"(item, index) in items\" :key=\"item.id\" :step=\"item.id\"><TimelineHeader><TimelineSeparator /><TimelineDate>{{ item.date }}</TimelineDate><TimelineTitle>{{ item.title }}</TimelineTitle><TimelineIndicator /></TimelineHeader><TimelineContent>{{ item.description }}</TimelineContent></TimelineItem></Timeline>\n</template>\n"
        },
        {
          "path": "registry/default/components/timeline/timeline-11.html",
          "target": "components/ui/timeline-11.html",
          "type": "registry:component",
          "content": "<template>\n  <Timeline default-value=\"${3}\" orientation=\"horizontal\"><!-- Loop items -->\n<TimelineItem key=\"${item.id}\" step=\"${item.id}\"><TimelineHeader><TimelineSeparator /><TimelineDate>${item.date}</TimelineDate><TimelineTitle>${item.title}</TimelineTitle><TimelineIndicator /></TimelineHeader><TimelineContent>${item.description}</TimelineContent></TimelineItem>\n<!-- End Loop --></Timeline>\n</template>"
        },
        {
          "path": "registry/default/components/timeline/timeline-11.wxml",
          "target": "components/ui/timeline-11/timeline-11.wxml",
          "type": "registry:component",
          "content": "<view>\n  <timeline default-value=\"{{3}}\" orientation=\"horizontal\"><timelineitem wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{item.id}}\" step=\"{{item.id}}\"><timelineheader><timelineseparator /><timelinedate>{{ item.date }}</timelinedate><timelinetitle>{{ item.title }}</timelinetitle><timelineindicator /></timelineheader><timelinecontent>{{ item.description }}</timelinecontent></timelineitem></timeline>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "timeline"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "timeline-11",
          "group": "timeline",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "timeline-11",
              "path": "registry/default/components/timeline/timeline-11.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "timeline-11",
              "path": "registry/default/components/timeline/timeline-11.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "timeline-11",
              "path": "registry/default/components/timeline/timeline-11.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "timeline-11",
              "path": "registry/default/components/timeline/timeline-11.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "timeline",
        "title": "Timeline · Detailed timeline"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "timeline"
      ]
    },
    {
      "name": "timeline-12",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/timeline.json"
      ],
      "files": [
        {
          "path": "registry/default/components/timeline/timeline-12.tsx",
          "type": "registry:component",
          "target": "components/ui/timeline-12.tsx",
          "content": "import {\n  Timeline,\n  TimelineContent,\n  TimelineDate,\n  TimelineHeader,\n  TimelineIndicator,\n  TimelineItem,\n  TimelineSeparator,\n  TimelineTitle,\n} from '@timui/react'\n\nconst items = [\n  {\n    id: 1,\n    date: 'Mar 15, 2024',\n    title: 'Project Kickoff',\n    description: 'Initial team meeting.',\n  },\n  {\n    id: 2,\n    date: 'Mar 22, 2024',\n    title: 'Design Phase',\n    description: 'Completed wireframes.',\n  },\n  {\n    id: 3,\n    date: 'Apr 5, 2024',\n    title: 'Development Sprint',\n    description: 'Backend development.',\n  },\n  {\n    id: 4,\n    date: 'Apr 19, 2024',\n    title: 'Testing & Deployment',\n    description: 'Performance optimization.',\n  },\n]\n\nexport default function Component() {\n  return (\n    <Timeline defaultValue={3} orientation=\"horizontal\">\n      {items.map((item) => (\n        <TimelineItem\n          key={item.id}\n          step={item.id}\n          className=\"group-data-[orientation=horizontal]/timeline:mt-0\"\n        >\n          <TimelineHeader>\n            <TimelineSeparator className=\"group-data-[orientation=horizontal]/timeline:top-8\" />\n            <TimelineDate className=\"mb-10\">{item.date}</TimelineDate>\n            <TimelineTitle>{item.title}</TimelineTitle>\n            <TimelineIndicator className=\"group-data-[orientation=horizontal]/timeline:top-8\" />\n          </TimelineHeader>\n          <TimelineContent>{item.description}</TimelineContent>\n        </TimelineItem>\n      ))}\n    </Timeline>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/timeline/timeline-12.vue",
          "target": "components/ui/timeline-12.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Timeline } from '@timui/vue';\nimport { TimelineContent } from '@timui/vue';\nimport { TimelineDate } from '@timui/vue';\nimport { TimelineHeader } from '@timui/vue';\nimport { TimelineIndicator } from '@timui/vue';\nimport { TimelineItem } from '@timui/vue';\nimport { TimelineSeparator } from '@timui/vue';\nimport { TimelineTitle } from '@timui/vue';\n\n\n\n\n\nconst items = [\n  {\n    id: 1,\n    date: 'Mar 15, 2024',\n    title: 'Project Kickoff',\n    description: 'Initial team meeting.',\n  },\n  {\n    id: 2,\n    date: 'Mar 22, 2024',\n    title: 'Design Phase',\n    description: 'Completed wireframes.',\n  },\n  {\n    id: 3,\n    date: 'Apr 5, 2024',\n    title: 'Development Sprint',\n    description: 'Backend development.',\n  },\n  {\n    id: 4,\n    date: 'Apr 19, 2024',\n    title: 'Testing & Deployment',\n    description: 'Performance optimization.',\n  },\n]\n\n</script>\n\n<template>\n  <Timeline :default-value=\"3\" orientation=\"horizontal\"><TimelineItem v-for=\"(item, index) in items\" :key=\"item.id\" :step=\"item.id\" class=\"group-data-[orientation=horizontal]/timeline:mt-0\"><TimelineHeader><TimelineSeparator class=\"group-data-[orientation=horizontal]/timeline:top-8\" /><TimelineDate class=\"mb-10\">{{ item.date }}</TimelineDate><TimelineTitle>{{ item.title }}</TimelineTitle><TimelineIndicator class=\"group-data-[orientation=horizontal]/timeline:top-8\" /></TimelineHeader><TimelineContent>{{ item.description }}</TimelineContent></TimelineItem></Timeline>\n</template>\n"
        },
        {
          "path": "registry/default/components/timeline/timeline-12.html",
          "target": "components/ui/timeline-12.html",
          "type": "registry:component",
          "content": "<template>\n  <Timeline default-value=\"${3}\" orientation=\"horizontal\"><!-- Loop items -->\n<TimelineItem key=\"${item.id}\" step=\"${item.id}\" class=\"group-data-[orientation=horizontal]/timeline:mt-0\"><TimelineHeader><TimelineSeparator class=\"group-data-[orientation=horizontal]/timeline:top-8\" /><TimelineDate class=\"mb-10\">${item.date}</TimelineDate><TimelineTitle>${item.title}</TimelineTitle><TimelineIndicator class=\"group-data-[orientation=horizontal]/timeline:top-8\" /></TimelineHeader><TimelineContent>${item.description}</TimelineContent></TimelineItem>\n<!-- End Loop --></Timeline>\n</template>"
        },
        {
          "path": "registry/default/components/timeline/timeline-12.wxml",
          "target": "components/ui/timeline-12/timeline-12.wxml",
          "type": "registry:component",
          "content": "<view>\n  <timeline default-value=\"{{3}}\" orientation=\"horizontal\"><timelineitem wx:for=\"{{items}}\" wx:for-item=\"item\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{item.id}}\" step=\"{{item.id}}\" class=\"group-data-[orientation=horizontal]/timeline:mt-0\"><timelineheader><timelineseparator class=\"group-data-[orientation=horizontal]/timeline:top-8\" /><timelinedate class=\"mb-10\">{{ item.date }}</timelinedate><timelinetitle>{{ item.title }}</timelinetitle><timelineindicator class=\"group-data-[orientation=horizontal]/timeline:top-8\" /></timelineheader><timelinecontent>{{ item.description }}</timelinecontent></timelineitem></timeline>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "timeline"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "timeline-12",
          "group": "timeline",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "timeline-12",
              "path": "registry/default/components/timeline/timeline-12.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "timeline-12",
              "path": "registry/default/components/timeline/timeline-12.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "timeline-12",
              "path": "registry/default/components/timeline/timeline-12.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "timeline-12",
              "path": "registry/default/components/timeline/timeline-12.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "timeline",
        "title": "Timeline · Detailed timeline"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "timeline"
      ]
    },
    {
      "name": "event-calendar-01",
      "type": "registry:component",
      "dependencies": [
        "@dnd-kit/core",
        "@dnd-kit/core/dist/hooks/utilities",
        "@dnd-kit/utilities",
        "@remixicon/react",
        "@timui/core",
        "@timui/react",
        "date-fns"
      ],
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/calendar.json",
        "https://ui.timkit.cn/r/checkbox.json",
        "https://ui.timkit.cn/r/dropdown-menu.json",
        "https://ui.timkit.cn/r/dialog.json",
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/textarea.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/popover.json",
        "https://ui.timkit.cn/r/radio-group.json",
        "https://ui.timkit.cn/r/select.json",
        "https://ui.timkit.cn/r/sonner.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react",
        "sonner"
      ],
      "files": [
        {
          "path": "registry/default/components/event-calendar/event-calendar-01.tsx",
          "type": "registry:component",
          "target": "components/ui/event-calendar-01.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { addDays, setHours, setMinutes, subDays } from 'date-fns'\n\nimport { EventCalendar, type CalendarEvent } from '@/registry/default/components/event-calendar'\n\n// Sample events data with hardcoded times\nconst sampleEvents: CalendarEvent[] = [\n  {\n    id: '1',\n    title: 'Annual Planning',\n    description: 'Strategic planning for next year',\n    start: subDays(new Date(), 24), // 24 days before today\n    end: subDays(new Date(), 23), // 23 days before today\n    allDay: true,\n    color: 'sky',\n    location: 'Main Conference Hall',\n  },\n  {\n    id: '2',\n    title: 'Project Deadline',\n    description: 'Submit final deliverables',\n    start: setMinutes(setHours(subDays(new Date(), 9), 13), 0), // 1:00 PM, 9 days before\n    end: setMinutes(setHours(subDays(new Date(), 9), 15), 30), // 3:30 PM, 9 days before\n    color: 'amber',\n    location: 'Office',\n  },\n  {\n    id: '3',\n    title: 'Quarterly Budget Review',\n    description: 'Strategic planning for next year',\n    start: subDays(new Date(), 13), // 13 days before today\n    end: subDays(new Date(), 13), // 13 days before today\n    allDay: true,\n    color: 'orange',\n    location: 'Main Conference Hall',\n  },\n  {\n    id: '4',\n    title: 'Team Meeting',\n    description: 'Weekly team sync',\n    start: setMinutes(setHours(new Date(), 10), 0), // 10:00 AM today\n    end: setMinutes(setHours(new Date(), 11), 0), // 11:00 AM today\n    color: 'sky',\n    location: 'Conference Room A',\n  },\n  {\n    id: '5',\n    title: 'Lunch with Client',\n    description: 'Discuss new project requirements',\n    start: setMinutes(setHours(addDays(new Date(), 1), 12), 0), // 12:00 PM, 1 day from now\n    end: setMinutes(setHours(addDays(new Date(), 1), 13), 15), // 1:15 PM, 1 day from now\n    color: 'emerald',\n    location: 'Downtown Cafe',\n  },\n  {\n    id: '6',\n    title: 'Product Launch',\n    description: 'New product release',\n    start: addDays(new Date(), 3), // 3 days from now\n    end: addDays(new Date(), 6), // 6 days from now\n    allDay: true,\n    color: 'violet',\n  },\n  {\n    id: '7',\n    title: 'Sales Conference',\n    description: 'Discuss about new clients',\n    start: setMinutes(setHours(addDays(new Date(), 4), 14), 30), // 2:30 PM, 4 days from now\n    end: setMinutes(setHours(addDays(new Date(), 5), 14), 45), // 2:45 PM, 5 days from now\n    color: 'rose',\n    location: 'Downtown Cafe',\n  },\n  {\n    id: '8',\n    title: 'Team Meeting',\n    description: 'Weekly team sync',\n    start: setMinutes(setHours(addDays(new Date(), 5), 9), 0), // 9:00 AM, 5 days from now\n    end: setMinutes(setHours(addDays(new Date(), 5), 10), 30), // 10:30 AM, 5 days from now\n    color: 'orange',\n    location: 'Conference Room A',\n  },\n  {\n    id: '9',\n    title: 'Review contracts',\n    description: 'Weekly team sync',\n    start: setMinutes(setHours(addDays(new Date(), 5), 14), 0), // 2:00 PM, 5 days from now\n    end: setMinutes(setHours(addDays(new Date(), 5), 15), 30), // 3:30 PM, 5 days from now\n    color: 'sky',\n    location: 'Conference Room A',\n  },\n  {\n    id: '10',\n    title: 'Team Meeting',\n    description: 'Weekly team sync',\n    start: setMinutes(setHours(addDays(new Date(), 5), 9), 45), // 9:45 AM, 5 days from now\n    end: setMinutes(setHours(addDays(new Date(), 5), 11), 0), // 11:00 AM, 5 days from now\n    color: 'amber',\n    location: 'Conference Room A',\n  },\n  {\n    id: '11',\n    title: 'Marketing Strategy Session',\n    description: 'Quarterly marketing planning',\n    start: setMinutes(setHours(addDays(new Date(), 9), 10), 0), // 10:00 AM, 9 days from now\n    end: setMinutes(setHours(addDays(new Date(), 9), 15), 30), // 3:30 PM, 9 days from now\n    color: 'emerald',\n    location: 'Marketing Department',\n  },\n  {\n    id: '12',\n    title: 'Annual Shareholders Meeting',\n    description: 'Presentation of yearly results',\n    start: addDays(new Date(), 17), // 17 days from now\n    end: addDays(new Date(), 17), // 17 days from now\n    allDay: true,\n    color: 'sky',\n    location: 'Grand Conference Center',\n  },\n  {\n    id: '13',\n    title: 'Product Development Workshop',\n    description: 'Brainstorming for new features',\n    start: setMinutes(setHours(addDays(new Date(), 26), 9), 0), // 9:00 AM, 26 days from now\n    end: setMinutes(setHours(addDays(new Date(), 27), 17), 0), // 5:00 PM, 27 days from now\n    color: 'rose',\n    location: 'Innovation Lab',\n  },\n]\n\nexport default function Component() {\n  const [events, setEvents] = useState<CalendarEvent[]>(sampleEvents)\n\n  const handleEventAdd = (event: CalendarEvent) => {\n    setEvents([...events, event])\n  }\n\n  const handleEventUpdate = (updatedEvent: CalendarEvent) => {\n    setEvents(events.map((event) => (event.id === updatedEvent.id ? updatedEvent : event)))\n  }\n\n  const handleEventDelete = (eventId: string) => {\n    setEvents(events.filter((event) => event.id !== eventId))\n  }\n\n  return (\n    <EventCalendar\n      events={events}\n      onEventAdd={handleEventAdd}\n      onEventUpdate={handleEventUpdate}\n      onEventDelete={handleEventDelete}\n    />\n  )\n}\n"
        },
        {
          "path": "registry/default/components/event-calendar/agenda-view.tsx",
          "type": "registry:component",
          "target": "components/ui/agenda-view.tsx",
          "content": "'use client'\n\nimport { useMemo } from 'react'\nimport { RiCalendarEventLine } from '@remixicon/react'\nimport { addDays, format, isToday } from 'date-fns'\n\nimport {\n  AgendaDaysToShow,\n  CalendarEvent,\n  EventItem,\n  getAgendaEventsForDay,\n} from '@/registry/default/components/event-calendar'\n\ninterface AgendaViewProps {\n  currentDate: Date\n  events: CalendarEvent[]\n  onEventSelect: (event: CalendarEvent) => void\n}\n\nexport function AgendaView({ currentDate, events, onEventSelect }: AgendaViewProps) {\n  // Show events for the next days based on constant\n  const days = useMemo(() => {\n    console.log('Agenda view updating with date:', currentDate.toISOString())\n    return Array.from({ length: AgendaDaysToShow }, (_, i) => addDays(new Date(currentDate), i))\n  }, [currentDate])\n\n  const handleEventClick = (event: CalendarEvent, e: React.MouseEvent) => {\n    e.stopPropagation()\n    console.log('Agenda view event clicked:', event)\n    onEventSelect(event)\n  }\n\n  // Check if there are any days with events\n  const hasEvents = days.some((day) => getAgendaEventsForDay(events, day).length > 0)\n\n  return (\n    <div className=\"border-border/70 border-t px-4\">\n      {!hasEvents ? (\n        <div className=\"flex min-h-[70svh] flex-col items-center justify-center py-16 text-center\">\n          <RiCalendarEventLine size={32} className=\"text-muted-foreground/50 mb-2\" />\n          <h3 className=\"text-lg font-medium\">No events found</h3>\n          <p className=\"text-muted-foreground\">\n            There are no events scheduled for this time period.\n          </p>\n        </div>\n      ) : (\n        days.map((day) => {\n          const dayEvents = getAgendaEventsForDay(events, day)\n\n          if (dayEvents.length === 0) return null\n\n          return (\n            <div key={day.toString()} className=\"border-border/70 relative my-12 border-t\">\n              <span\n                className=\"bg-background absolute -top-3 left-0 flex h-6 items-center pe-4 text-[10px] uppercase data-today:font-medium sm:pe-4 sm:text-xs\"\n                data-today={isToday(day) || undefined}\n              >\n                {format(day, 'd MMM, EEEE')}\n              </span>\n              <div className=\"mt-6 space-y-2\">\n                {dayEvents.map((event) => (\n                  <EventItem\n                    key={event.id}\n                    event={event}\n                    view=\"agenda\"\n                    onClick={(e) => handleEventClick(event, e)}\n                  />\n                ))}\n              </div>\n            </div>\n          )\n        })\n      )}\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/event-calendar/calendar-dnd-context.tsx",
          "type": "registry:component",
          "target": "components/ui/calendar-dnd-context.tsx",
          "content": "'use client'\n\nimport { createContext, useContext, useId, useRef, useState, type ReactNode } from 'react'\nimport {\n  DndContext,\n  DragOverlay,\n  MouseSensor,\n  PointerSensor,\n  TouchSensor,\n  useSensor,\n  useSensors,\n  type DragEndEvent,\n  type DragOverEvent,\n  type DragStartEvent,\n  type UniqueIdentifier,\n} from '@dnd-kit/core'\nimport { addMinutes, differenceInMinutes } from 'date-fns'\n\nimport { EventItem, type CalendarEvent } from '@/registry/default/components/event-calendar'\n\n// Define the context type\ntype CalendarDndContextType = {\n  activeEvent: CalendarEvent | null\n  activeId: UniqueIdentifier | null\n  activeView: 'month' | 'week' | 'day' | null\n  currentTime: Date | null\n  eventHeight: number | null\n  isMultiDay: boolean\n  multiDayWidth: number | null\n  dragHandlePosition: {\n    x?: number\n    y?: number\n    data?: {\n      isFirstDay?: boolean\n      isLastDay?: boolean\n    }\n  } | null\n}\n\n// Create the context\nconst CalendarDndContext = createContext<CalendarDndContextType>({\n  activeEvent: null,\n  activeId: null,\n  activeView: null,\n  currentTime: null,\n  eventHeight: null,\n  isMultiDay: false,\n  multiDayWidth: null,\n  dragHandlePosition: null,\n})\n\n// Hook to use the context\nexport const useCalendarDnd = () => useContext(CalendarDndContext)\n\n// Props for the provider\ninterface CalendarDndProviderProps {\n  children: ReactNode\n  onEventUpdate: (event: CalendarEvent) => void\n}\n\nexport function CalendarDndProvider({ children, onEventUpdate }: CalendarDndProviderProps) {\n  const [activeEvent, setActiveEvent] = useState<CalendarEvent | null>(null)\n  const [activeId, setActiveId] = useState<UniqueIdentifier | null>(null)\n  const [activeView, setActiveView] = useState<'month' | 'week' | 'day' | null>(null)\n  const [currentTime, setCurrentTime] = useState<Date | null>(null)\n  const [eventHeight, setEventHeight] = useState<number | null>(null)\n  const [isMultiDay, setIsMultiDay] = useState(false)\n  const [multiDayWidth, setMultiDayWidth] = useState<number | null>(null)\n  const [dragHandlePosition, setDragHandlePosition] = useState<{\n    x?: number\n    y?: number\n    data?: {\n      isFirstDay?: boolean\n      isLastDay?: boolean\n    }\n  } | null>(null)\n\n  // Store original event dimensions\n  const eventDimensions = useRef<{ height: number }>({ height: 0 })\n\n  // Configure sensors for better drag detection\n  const sensors = useSensors(\n    useSensor(MouseSensor, {\n      // Require the mouse to move by 5px before activating\n      activationConstraint: {\n        distance: 5,\n      },\n    }),\n    useSensor(TouchSensor, {\n      // Press delay of 250ms, with tolerance of 5px of movement\n      activationConstraint: {\n        delay: 250,\n        tolerance: 5,\n      },\n    }),\n    useSensor(PointerSensor, {\n      // Require the pointer to move by 5px before activating\n      activationConstraint: {\n        distance: 5,\n      },\n    })\n  )\n\n  // Generate a stable ID for the DndContext\n  const dndContextId = useId()\n\n  const handleDragStart = (event: DragStartEvent) => {\n    const { active } = event\n\n    // Add safety check for data.current\n    if (!active.data.current) {\n      console.error('Missing data in drag start event', event)\n      return\n    }\n\n    const {\n      event: calendarEvent,\n      view,\n      height,\n      isMultiDay: eventIsMultiDay,\n      multiDayWidth: eventMultiDayWidth,\n      dragHandlePosition: eventDragHandlePosition,\n    } = active.data.current as {\n      event: CalendarEvent\n      view: 'month' | 'week' | 'day'\n      height?: number\n      isMultiDay?: boolean\n      multiDayWidth?: number\n      dragHandlePosition?: {\n        x?: number\n        y?: number\n        data?: {\n          isFirstDay?: boolean\n          isLastDay?: boolean\n        }\n      }\n    }\n\n    setActiveEvent(calendarEvent)\n    setActiveId(active.id)\n    setActiveView(view)\n    setCurrentTime(new Date(calendarEvent.start))\n    setIsMultiDay(eventIsMultiDay || false)\n    setMultiDayWidth(eventMultiDayWidth || null)\n    setDragHandlePosition(eventDragHandlePosition || null)\n\n    // Store event height if provided\n    if (height) {\n      eventDimensions.current.height = height\n      setEventHeight(height)\n    }\n  }\n\n  const handleDragOver = (event: DragOverEvent) => {\n    const { over } = event\n\n    if (over && activeEvent && over.data.current) {\n      const { date, time } = over.data.current as { date: Date; time?: number }\n\n      // Update time for week/day views\n      if (time !== undefined && activeView !== 'month') {\n        const newTime = new Date(date)\n\n        // Calculate hours and minutes with 15-minute precision\n        const hours = Math.floor(time)\n        const fractionalHour = time - hours\n\n        // Map to nearest 15 minute interval (0, 0.25, 0.5, 0.75)\n        let minutes = 0\n        if (fractionalHour < 0.125) minutes = 0\n        else if (fractionalHour < 0.375) minutes = 15\n        else if (fractionalHour < 0.625) minutes = 30\n        else minutes = 45\n\n        newTime.setHours(hours, minutes, 0, 0)\n\n        // Only update if time has changed\n        if (\n          !currentTime ||\n          newTime.getHours() !== currentTime.getHours() ||\n          newTime.getMinutes() !== currentTime.getMinutes() ||\n          newTime.getDate() !== currentTime.getDate() ||\n          newTime.getMonth() !== currentTime.getMonth() ||\n          newTime.getFullYear() !== currentTime.getFullYear()\n        ) {\n          setCurrentTime(newTime)\n        }\n      } else if (activeView === 'month') {\n        // For month view, just update the date but preserve time\n        const newTime = new Date(date)\n        if (currentTime) {\n          newTime.setHours(\n            currentTime.getHours(),\n            currentTime.getMinutes(),\n            currentTime.getSeconds(),\n            currentTime.getMilliseconds()\n          )\n        }\n\n        // Only update if date has changed\n        if (\n          !currentTime ||\n          newTime.getDate() !== currentTime.getDate() ||\n          newTime.getMonth() !== currentTime.getMonth() ||\n          newTime.getFullYear() !== currentTime.getFullYear()\n        ) {\n          setCurrentTime(newTime)\n        }\n      }\n    }\n  }\n\n  const handleDragEnd = (event: DragEndEvent) => {\n    const { active, over } = event\n\n    // Add robust error checking\n    if (!over || !activeEvent || !currentTime) {\n      // Reset state and exit early\n      setActiveEvent(null)\n      setActiveId(null)\n      setActiveView(null)\n      setCurrentTime(null)\n      setEventHeight(null)\n      setIsMultiDay(false)\n      setMultiDayWidth(null)\n      setDragHandlePosition(null)\n      return\n    }\n\n    try {\n      // Safely access data with checks\n      if (!active.data.current || !over.data.current) {\n        throw new Error('Missing data in drag event')\n      }\n\n      const activeData = active.data.current as {\n        event?: CalendarEvent\n        view?: string\n      }\n      const overData = over.data.current as { date?: Date; time?: number }\n\n      // Verify we have all required data\n      if (!activeData.event || !overData.date) {\n        throw new Error('Missing required event data')\n      }\n\n      const calendarEvent = activeData.event\n      const date = overData.date\n      const time = overData.time\n\n      // Calculate new start time\n      const newStart = new Date(date)\n\n      // If time is provided (for week/day views), set the hours and minutes\n      if (time !== undefined) {\n        const hours = Math.floor(time)\n        const fractionalHour = time - hours\n\n        // Map to nearest 15 minute interval (0, 0.25, 0.5, 0.75)\n        let minutes = 0\n        if (fractionalHour < 0.125) minutes = 0\n        else if (fractionalHour < 0.375) minutes = 15\n        else if (fractionalHour < 0.625) minutes = 30\n        else minutes = 45\n\n        newStart.setHours(hours, minutes, 0, 0)\n      } else {\n        // For month view, preserve the original time from currentTime\n        newStart.setHours(\n          currentTime.getHours(),\n          currentTime.getMinutes(),\n          currentTime.getSeconds(),\n          currentTime.getMilliseconds()\n        )\n      }\n\n      // Calculate new end time based on the original duration\n      const originalStart = new Date(calendarEvent.start)\n      const originalEnd = new Date(calendarEvent.end)\n      const durationMinutes = differenceInMinutes(originalEnd, originalStart)\n      const newEnd = addMinutes(newStart, durationMinutes)\n\n      // Only update if the start time has actually changed\n      const hasStartTimeChanged =\n        originalStart.getFullYear() !== newStart.getFullYear() ||\n        originalStart.getMonth() !== newStart.getMonth() ||\n        originalStart.getDate() !== newStart.getDate() ||\n        originalStart.getHours() !== newStart.getHours() ||\n        originalStart.getMinutes() !== newStart.getMinutes()\n\n      if (hasStartTimeChanged) {\n        // Update the event only if the time has changed\n        onEventUpdate({\n          ...calendarEvent,\n          start: newStart,\n          end: newEnd,\n        })\n      }\n    } catch (error) {\n      console.error('Error in drag end handler:', error)\n    } finally {\n      // Always reset state\n      setActiveEvent(null)\n      setActiveId(null)\n      setActiveView(null)\n      setCurrentTime(null)\n      setEventHeight(null)\n      setIsMultiDay(false)\n      setMultiDayWidth(null)\n      setDragHandlePosition(null)\n    }\n  }\n\n  return (\n    <DndContext\n      id={dndContextId}\n      sensors={sensors}\n      onDragStart={handleDragStart}\n      onDragOver={handleDragOver}\n      onDragEnd={handleDragEnd}\n    >\n      <CalendarDndContext.Provider\n        value={{\n          activeEvent,\n          activeId,\n          activeView,\n          currentTime,\n          eventHeight,\n          isMultiDay,\n          multiDayWidth,\n          dragHandlePosition,\n        }}\n      >\n        {children}\n\n        <DragOverlay adjustScale={false} dropAnimation={null}>\n          {activeEvent && activeView && (\n            <div\n              style={{\n                height: eventHeight ? `${eventHeight}px` : 'auto',\n                width: isMultiDay && multiDayWidth ? `${multiDayWidth}%` : '100%',\n                // Remove the transform that was causing the shift\n              }}\n            >\n              <EventItem\n                event={activeEvent}\n                view={activeView}\n                isDragging={true}\n                showTime={activeView !== 'month'}\n                currentTime={currentTime || undefined}\n                isFirstDay={dragHandlePosition?.data?.isFirstDay !== false}\n                isLastDay={dragHandlePosition?.data?.isLastDay !== false}\n              />\n            </div>\n          )}\n        </DragOverlay>\n      </CalendarDndContext.Provider>\n    </DndContext>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/event-calendar/constants.ts",
          "type": "registry:component",
          "target": "components/ui/event-calendar-01/constants.ts",
          "content": "// Height of calendar events in pixels - used in month, week and day views\nexport const EventHeight = 24\n\n// Vertical gap between events in pixels - controls spacing in month view\nexport const EventGap = 4\n\n// Height of hour cells in week and day views - controls the scale of time display\nexport const WeekCellsHeight = 64\n\n// Number of days to show in the agenda view\nexport const AgendaDaysToShow = 30\n\n// Start and end hours for the week and day views\nexport const StartHour = 0\nexport const EndHour = 24\n\n// Default start and end times\nexport const DefaultStartHour = 9 // 9 AM\nexport const DefaultEndHour = 10 // 10 AM\n"
        },
        {
          "path": "registry/default/components/event-calendar/day-view.tsx",
          "type": "registry:component",
          "target": "components/ui/day-view.tsx",
          "content": "'use client'\n\nimport React, { useMemo } from 'react'\nimport { cn } from '@timui/core'\nimport {\n  addHours,\n  areIntervalsOverlapping,\n  differenceInMinutes,\n  eachHourOfInterval,\n  format,\n  getHours,\n  getMinutes,\n  isSameDay,\n  startOfDay,\n} from 'date-fns'\n\nimport {\n  DraggableEvent,\n  DroppableCell,\n  EventItem,\n  isMultiDayEvent,\n  useCurrentTimeIndicator,\n  WeekCellsHeight,\n  type CalendarEvent,\n} from '@/registry/default/components/event-calendar'\nimport { EndHour, StartHour } from '@/registry/default/components/event-calendar/constants'\n\ninterface DayViewProps {\n  currentDate: Date\n  events: CalendarEvent[]\n  onEventSelect: (event: CalendarEvent) => void\n  onEventCreate: (startTime: Date) => void\n}\n\ninterface PositionedEvent {\n  event: CalendarEvent\n  top: number\n  height: number\n  left: number\n  width: number\n  zIndex: number\n}\n\nexport function DayView({ currentDate, events, onEventSelect, onEventCreate }: DayViewProps) {\n  const hours = useMemo(() => {\n    const dayStart = startOfDay(currentDate)\n    return eachHourOfInterval({\n      start: addHours(dayStart, StartHour),\n      end: addHours(dayStart, EndHour - 1),\n    })\n  }, [currentDate])\n\n  const dayEvents = useMemo(() => {\n    return events\n      .filter((event) => {\n        const eventStart = new Date(event.start)\n        const eventEnd = new Date(event.end)\n        return (\n          isSameDay(currentDate, eventStart) ||\n          isSameDay(currentDate, eventEnd) ||\n          (currentDate > eventStart && currentDate < eventEnd)\n        )\n      })\n      .sort((a, b) => new Date(a.start).getTime() - new Date(b.start).getTime())\n  }, [currentDate, events])\n\n  // Filter all-day events\n  const allDayEvents = useMemo(() => {\n    return dayEvents.filter((event) => {\n      // Include explicitly marked all-day events or multi-day events\n      return event.allDay || isMultiDayEvent(event)\n    })\n  }, [dayEvents])\n\n  // Get only single-day time-based events\n  const timeEvents = useMemo(() => {\n    return dayEvents.filter((event) => {\n      // Exclude all-day events and multi-day events\n      return !event.allDay && !isMultiDayEvent(event)\n    })\n  }, [dayEvents])\n\n  // Process events to calculate positions\n  const positionedEvents = useMemo(() => {\n    const result: PositionedEvent[] = []\n    const dayStart = startOfDay(currentDate)\n\n    // Sort events by start time and duration\n    const sortedEvents = [...timeEvents].sort((a, b) => {\n      const aStart = new Date(a.start)\n      const bStart = new Date(b.start)\n      const aEnd = new Date(a.end)\n      const bEnd = new Date(b.end)\n\n      // First sort by start time\n      if (aStart < bStart) return -1\n      if (aStart > bStart) return 1\n\n      // If start times are equal, sort by duration (longer events first)\n      const aDuration = differenceInMinutes(aEnd, aStart)\n      const bDuration = differenceInMinutes(bEnd, bStart)\n      return bDuration - aDuration\n    })\n\n    // Track columns for overlapping events\n    const columns: { event: CalendarEvent; end: Date }[][] = []\n\n    sortedEvents.forEach((event) => {\n      const eventStart = new Date(event.start)\n      const eventEnd = new Date(event.end)\n\n      // Adjust start and end times if they're outside this day\n      const adjustedStart = isSameDay(currentDate, eventStart) ? eventStart : dayStart\n      const adjustedEnd = isSameDay(currentDate, eventEnd) ? eventEnd : addHours(dayStart, 24)\n\n      // Calculate top position and height\n      const startHour = getHours(adjustedStart) + getMinutes(adjustedStart) / 60\n      const endHour = getHours(adjustedEnd) + getMinutes(adjustedEnd) / 60\n      const top = (startHour - StartHour) * WeekCellsHeight\n      const height = (endHour - startHour) * WeekCellsHeight\n\n      // Find a column for this event\n      let columnIndex = 0\n      let placed = false\n\n      while (!placed) {\n        const col = columns[columnIndex] || []\n        if (col.length === 0) {\n          columns[columnIndex] = col\n          placed = true\n        } else {\n          const overlaps = col.some((c) =>\n            areIntervalsOverlapping(\n              { start: adjustedStart, end: adjustedEnd },\n              { start: new Date(c.event.start), end: new Date(c.event.end) }\n            )\n          )\n          if (!overlaps) {\n            placed = true\n          } else {\n            columnIndex++\n          }\n        }\n      }\n\n      // Ensure column is initialized before pushing\n      const currentColumn = columns[columnIndex] || []\n      columns[columnIndex] = currentColumn\n      currentColumn.push({ event, end: adjustedEnd })\n\n      // First column takes full width, others are indented by 10% and take 90% width\n      const width = columnIndex === 0 ? 1 : 0.9\n      const left = columnIndex === 0 ? 0 : columnIndex * 0.1\n\n      result.push({\n        event,\n        top,\n        height,\n        left,\n        width,\n        zIndex: 10 + columnIndex, // Higher columns get higher z-index\n      })\n    })\n\n    return result\n  }, [currentDate, timeEvents])\n\n  const handleEventClick = (event: CalendarEvent, e: React.MouseEvent) => {\n    e.stopPropagation()\n    onEventSelect(event)\n  }\n\n  const showAllDaySection = allDayEvents.length > 0\n  const { currentTimePosition, currentTimeVisible } = useCurrentTimeIndicator(currentDate, 'day')\n\n  return (\n    <div data-slot=\"day-view\" className=\"contents\">\n      {showAllDaySection && (\n        <div className=\"border-border/70 bg-muted/50 border-t\">\n          <div className=\"grid grid-cols-[3rem_1fr] sm:grid-cols-[4rem_1fr]\">\n            <div className=\"relative\">\n              <span className=\"text-muted-foreground/70 absolute bottom-0 left-0 h-6 w-16 max-w-full pe-2 text-right text-[10px] sm:pe-4 sm:text-xs\">\n                All day\n              </span>\n            </div>\n            <div className=\"border-border/70 relative border-r p-1 last:border-r-0\">\n              {allDayEvents.map((event) => {\n                const eventStart = new Date(event.start)\n                const eventEnd = new Date(event.end)\n                const isFirstDay = isSameDay(currentDate, eventStart)\n                const isLastDay = isSameDay(currentDate, eventEnd)\n\n                return (\n                  <EventItem\n                    key={`spanning-${event.id}`}\n                    onClick={(e) => handleEventClick(event, e)}\n                    event={event}\n                    view=\"month\"\n                    isFirstDay={isFirstDay}\n                    isLastDay={isLastDay}\n                  >\n                    {/* Always show the title in day view for better usability */}\n                    <div>{event.title}</div>\n                  </EventItem>\n                )\n              })}\n            </div>\n          </div>\n        </div>\n      )}\n\n      <div className=\"border-border/70 grid flex-1 grid-cols-[3rem_1fr] overflow-hidden border-t sm:grid-cols-[4rem_1fr]\">\n        <div>\n          {hours.map((hour, index) => (\n            <div\n              key={hour.toString()}\n              className=\"border-border/70 relative h-[var(--week-cells-height)] border-b last:border-b-0\"\n            >\n              {index > 0 && (\n                <span className=\"bg-background text-muted-foreground/70 absolute -top-3 left-0 flex h-6 w-16 max-w-full items-center justify-end pe-2 text-[10px] sm:pe-4 sm:text-xs\">\n                  {format(hour, 'h a')}\n                </span>\n              )}\n            </div>\n          ))}\n        </div>\n\n        <div className=\"relative\">\n          {/* Positioned events */}\n          {positionedEvents.map((positionedEvent) => (\n            <div\n              key={positionedEvent.event.id}\n              className=\"absolute z-10 px-0.5\"\n              style={{\n                top: `${positionedEvent.top}px`,\n                height: `${positionedEvent.height}px`,\n                left: `${positionedEvent.left * 100}%`,\n                width: `${positionedEvent.width * 100}%`,\n                zIndex: positionedEvent.zIndex,\n              }}\n            >\n              <div className=\"size-full\">\n                <DraggableEvent\n                  event={positionedEvent.event}\n                  view=\"day\"\n                  onClick={(e) => handleEventClick(positionedEvent.event, e)}\n                  showTime\n                  height={positionedEvent.height}\n                />\n              </div>\n            </div>\n          ))}\n\n          {/* Current time indicator */}\n          {currentTimeVisible && (\n            <div\n              className=\"pointer-events-none absolute right-0 left-0 z-20\"\n              style={{ top: `${currentTimePosition}%` }}\n            >\n              <div className=\"relative flex items-center\">\n                <div className=\"bg-primary absolute -left-1 h-2 w-2 rounded-full\"></div>\n                <div className=\"bg-primary h-[2px] w-full\"></div>\n              </div>\n            </div>\n          )}\n\n          {/* Time grid */}\n          {hours.map((hour) => {\n            const hourValue = getHours(hour)\n            return (\n              <div\n                key={hour.toString()}\n                className=\"border-border/70 relative h-[var(--week-cells-height)] border-b last:border-b-0\"\n              >\n                {/* Quarter-hour intervals */}\n                {[0, 1, 2, 3].map((quarter) => {\n                  const quarterHourTime = hourValue + quarter * 0.25\n                  return (\n                    <DroppableCell\n                      key={`${hour.toString()}-${quarter}`}\n                      id={`day-cell-${currentDate.toISOString()}-${quarterHourTime}`}\n                      date={currentDate}\n                      time={quarterHourTime}\n                      className={cn(\n                        'absolute h-[calc(var(--week-cells-height)/4)] w-full',\n                        quarter === 0 && 'top-0',\n                        quarter === 1 && 'top-[calc(var(--week-cells-height)/4)]',\n                        quarter === 2 && 'top-[calc(var(--week-cells-height)/4*2)]',\n                        quarter === 3 && 'top-[calc(var(--week-cells-height)/4*3)]'\n                      )}\n                      onClick={() => {\n                        const startTime = new Date(currentDate)\n                        startTime.setHours(hourValue)\n                        startTime.setMinutes(quarter * 15)\n                        onEventCreate(startTime)\n                      }}\n                    />\n                  )\n                })}\n              </div>\n            )\n          })}\n        </div>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/event-calendar/draggable-event.tsx",
          "type": "registry:component",
          "target": "components/ui/draggable-event.tsx",
          "content": "'use client'\n\nimport { useRef, useState } from 'react'\nimport { useDraggable } from '@dnd-kit/core'\nimport { CSS } from '@dnd-kit/utilities'\nimport { differenceInDays } from 'date-fns'\n\nimport {\n  CalendarEvent,\n  EventItem,\n  useCalendarDnd,\n} from '@/registry/default/components/event-calendar'\n\ninterface DraggableEventProps {\n  event: CalendarEvent\n  view: 'month' | 'week' | 'day'\n  showTime?: boolean\n  onClick?: (e: React.MouseEvent) => void\n  height?: number\n  isMultiDay?: boolean\n  multiDayWidth?: number\n  isFirstDay?: boolean\n  isLastDay?: boolean\n  'aria-hidden'?: boolean | 'true' | 'false'\n}\n\nexport function DraggableEvent({\n  event,\n  view,\n  showTime,\n  onClick,\n  height,\n  isMultiDay,\n  multiDayWidth,\n  isFirstDay = true,\n  isLastDay = true,\n  'aria-hidden': ariaHidden,\n}: DraggableEventProps) {\n  const { activeId } = useCalendarDnd()\n  const elementRef = useRef<HTMLDivElement>(null)\n  const [dragHandlePosition, setDragHandlePosition] = useState<{\n    x: number\n    y: number\n  } | null>(null)\n\n  // Check if this is a multi-day event\n  const eventStart = new Date(event.start)\n  const eventEnd = new Date(event.end)\n  const isMultiDayEvent = isMultiDay || event.allDay || differenceInDays(eventEnd, eventStart) >= 1\n\n  const { attributes, listeners, setNodeRef, transform, isDragging } = useDraggable({\n    id: `${event.id}-${view}`,\n    data: {\n      event,\n      view,\n      height: height || elementRef.current?.offsetHeight || null,\n      isMultiDay: isMultiDayEvent,\n      multiDayWidth: multiDayWidth,\n      dragHandlePosition,\n      isFirstDay,\n      isLastDay,\n    },\n  })\n\n  // Handle mouse down to track where on the event the user clicked\n  const handleMouseDown = (e: React.MouseEvent) => {\n    if (elementRef.current) {\n      const rect = elementRef.current.getBoundingClientRect()\n      setDragHandlePosition({\n        x: e.clientX - rect.left,\n        y: e.clientY - rect.top,\n      })\n    }\n  }\n\n  // Don't render if this event is being dragged\n  if (isDragging || activeId === `${event.id}-${view}`) {\n    return <div ref={setNodeRef} className=\"opacity-0\" style={{ height: height || 'auto' }} />\n  }\n\n  const style = transform\n    ? {\n        transform: CSS.Translate.toString(transform),\n        height: height || 'auto',\n        width: isMultiDayEvent && multiDayWidth ? `${multiDayWidth}%` : undefined,\n      }\n    : {\n        height: height || 'auto',\n        width: isMultiDayEvent && multiDayWidth ? `${multiDayWidth}%` : undefined,\n      }\n\n  // Handle touch start to track where on the event the user touched\n  const handleTouchStart = (e: React.TouchEvent) => {\n    if (elementRef.current) {\n      const rect = elementRef.current.getBoundingClientRect()\n      const touch = e.touches[0]\n      if (touch) {\n        setDragHandlePosition({\n          x: touch.clientX - rect.left,\n          y: touch.clientY - rect.top,\n        })\n      }\n    }\n  }\n\n  return (\n    <div\n      ref={(node) => {\n        setNodeRef(node)\n        if (elementRef) elementRef.current = node\n      }}\n      style={style}\n      className=\"touch-none\"\n    >\n      <EventItem\n        event={event}\n        view={view}\n        showTime={showTime}\n        isFirstDay={isFirstDay}\n        isLastDay={isLastDay}\n        isDragging={isDragging}\n        onClick={onClick}\n        onMouseDown={handleMouseDown}\n        onTouchStart={handleTouchStart}\n        dndListeners={listeners}\n        dndAttributes={attributes}\n        aria-hidden={ariaHidden}\n      />\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/event-calendar/droppable-cell.tsx",
          "type": "registry:component",
          "target": "components/ui/droppable-cell.tsx",
          "content": "'use client'\n\nimport { useDroppable } from '@dnd-kit/core'\nimport { cn } from '@timui/core'\n\nimport { useCalendarDnd } from '@/registry/default/components/event-calendar'\n\ninterface DroppableCellProps {\n  id: string\n  date: Date\n  time?: number // For week/day views, represents hours (e.g., 9.25 for 9:15)\n  children?: React.ReactNode\n  className?: string\n  onClick?: () => void\n}\n\nexport function DroppableCell({\n  id,\n  date,\n  time,\n  children,\n  className,\n  onClick,\n}: DroppableCellProps) {\n  const { activeEvent } = useCalendarDnd()\n\n  const { setNodeRef, isOver } = useDroppable({\n    id,\n    data: {\n      date,\n      time,\n    },\n  })\n\n  // Format time for display in tooltip (only for debugging)\n  const formattedTime =\n    time !== undefined\n      ? `${Math.floor(time)}:${Math.round((time - Math.floor(time)) * 60)\n          .toString()\n          .padStart(2, '0')}`\n      : null\n\n  return (\n    <div\n      ref={setNodeRef}\n      onClick={onClick}\n      className={cn(\n        'data-dragging:bg-accent flex h-full flex-col overflow-hidden px-0.5 py-1 sm:px-1',\n        className\n      )}\n      title={formattedTime ? `${formattedTime}` : undefined}\n      data-dragging={isOver && activeEvent ? true : undefined}\n    >\n      {children}\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/event-calendar/event-dialog.tsx",
          "type": "registry:component",
          "target": "components/ui/event-dialog.tsx",
          "content": "'use client'\n\nimport { useEffect, useMemo, useState } from 'react'\nimport { RiCalendarLine, RiDeleteBinLine } from '@remixicon/react'\nimport { cn } from '@timui/core'\nimport {\n  Button,\n  Calendar,\n  Checkbox,\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n  Input,\n  Label,\n  Popover,\n  PopoverContent,\n  PopoverTrigger,\n  RadioGroup,\n  RadioGroupItem,\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n  Textarea,\n} from '@timui/react'\nimport { format, isBefore } from 'date-fns'\n\nimport type { CalendarEvent, EventColor } from '@/registry/default/components/event-calendar'\nimport {\n  DefaultEndHour,\n  DefaultStartHour,\n  EndHour,\n  StartHour,\n} from '@/registry/default/components/event-calendar/constants'\n\ninterface EventDialogProps {\n  event: CalendarEvent | null\n  isOpen: boolean\n  onClose: () => void\n  onSave: (event: CalendarEvent) => void\n  onDelete: (eventId: string) => void\n}\n\nexport function EventDialog({ event, isOpen, onClose, onSave, onDelete }: EventDialogProps) {\n  const [title, setTitle] = useState('')\n  const [description, setDescription] = useState('')\n  const [startDate, setStartDate] = useState<Date>(new Date())\n  const [endDate, setEndDate] = useState<Date>(new Date())\n  const [startTime, setStartTime] = useState(`${DefaultStartHour}:00`)\n  const [endTime, setEndTime] = useState(`${DefaultEndHour}:00`)\n  const [allDay, setAllDay] = useState(false)\n  const [location, setLocation] = useState('')\n  const [color, setColor] = useState<EventColor>('sky')\n  const [error, setError] = useState<string | null>(null)\n  const [startDateOpen, setStartDateOpen] = useState(false)\n  const [endDateOpen, setEndDateOpen] = useState(false)\n\n  // Debug log to check what event is being passed\n  useEffect(() => {\n    console.log('EventDialog received event:', event)\n  }, [event])\n\n  useEffect(() => {\n    if (event) {\n      setTitle(event.title || '')\n      setDescription(event.description || '')\n\n      const start = new Date(event.start)\n      const end = new Date(event.end)\n\n      setStartDate(start)\n      setEndDate(end)\n      setStartTime(formatTimeForInput(start))\n      setEndTime(formatTimeForInput(end))\n      setAllDay(event.allDay || false)\n      setLocation(event.location || '')\n      setColor((event.color as EventColor) || 'sky')\n      setError(null) // Reset error when opening dialog\n    } else {\n      resetForm()\n    }\n  }, [event])\n\n  const resetForm = () => {\n    setTitle('')\n    setDescription('')\n    setStartDate(new Date())\n    setEndDate(new Date())\n    setStartTime(`${DefaultStartHour}:00`)\n    setEndTime(`${DefaultEndHour}:00`)\n    setAllDay(false)\n    setLocation('')\n    setColor('sky')\n    setError(null)\n  }\n\n  const formatTimeForInput = (date: Date) => {\n    const hours = date.getHours().toString().padStart(2, '0')\n    const minutes = Math.floor(date.getMinutes() / 15) * 15\n    return `${hours}:${minutes.toString().padStart(2, '0')}`\n  }\n\n  // Memoize time options so they're only calculated once\n  const timeOptions = useMemo(() => {\n    const options = []\n    for (let hour = StartHour; hour <= EndHour; hour++) {\n      for (let minute = 0; minute < 60; minute += 15) {\n        const formattedHour = hour.toString().padStart(2, '0')\n        const formattedMinute = minute.toString().padStart(2, '0')\n        const value = `${formattedHour}:${formattedMinute}`\n        // Use a fixed date to avoid unnecessary date object creations\n        const date = new Date(2000, 0, 1, hour, minute)\n        const label = format(date, 'h:mm a')\n        options.push({ value, label })\n      }\n    }\n    return options\n  }, []) // Empty dependency array ensures this only runs once\n\n  const handleSave = () => {\n    const start = new Date(startDate)\n    const end = new Date(endDate)\n\n    if (!allDay) {\n      const [startHours = 0, startMinutes = 0] = startTime.split(':').map(Number)\n      const [endHours = 0, endMinutes = 0] = endTime.split(':').map(Number)\n\n      if (\n        startHours < StartHour ||\n        startHours > EndHour ||\n        endHours < StartHour ||\n        endHours > EndHour\n      ) {\n        setError(`Selected time must be between ${StartHour}:00 and ${EndHour}:00`)\n        return\n      }\n\n      start.setHours(startHours, startMinutes, 0)\n      end.setHours(endHours, endMinutes, 0)\n    } else {\n      start.setHours(0, 0, 0, 0)\n      end.setHours(23, 59, 59, 999)\n    }\n\n    // Validate that end date is not before start date\n    if (isBefore(end, start)) {\n      setError('End date cannot be before start date')\n      return\n    }\n\n    // Use generic title if empty\n    const eventTitle = title.trim() ? title : '(no title)'\n\n    onSave({\n      id: event?.id || '',\n      title: eventTitle,\n      description,\n      start,\n      end,\n      allDay,\n      location,\n      color,\n    })\n  }\n\n  const handleDelete = () => {\n    if (event?.id) {\n      onDelete(event.id)\n    }\n  }\n\n  // Updated color options to match types.ts\n  const colorOptions: Array<{\n    value: EventColor\n    label: string\n    bgClass: string\n    borderClass: string\n  }> = [\n    {\n      value: 'sky',\n      label: 'Sky',\n      bgClass: 'bg-sky-400 data-[state=checked]:bg-sky-400',\n      borderClass: 'border-sky-400 data-[state=checked]:border-sky-400',\n    },\n    {\n      value: 'amber',\n      label: 'Amber',\n      bgClass: 'bg-amber-400 data-[state=checked]:bg-amber-400',\n      borderClass: 'border-amber-400 data-[state=checked]:border-amber-400',\n    },\n    {\n      value: 'violet',\n      label: 'Violet',\n      bgClass: 'bg-violet-400 data-[state=checked]:bg-violet-400',\n      borderClass: 'border-violet-400 data-[state=checked]:border-violet-400',\n    },\n    {\n      value: 'rose',\n      label: 'Rose',\n      bgClass: 'bg-rose-400 data-[state=checked]:bg-rose-400',\n      borderClass: 'border-rose-400 data-[state=checked]:border-rose-400',\n    },\n    {\n      value: 'emerald',\n      label: 'Emerald',\n      bgClass: 'bg-emerald-400 data-[state=checked]:bg-emerald-400',\n      borderClass: 'border-emerald-400 data-[state=checked]:border-emerald-400',\n    },\n    {\n      value: 'orange',\n      label: 'Orange',\n      bgClass: 'bg-orange-400 data-[state=checked]:bg-orange-400',\n      borderClass: 'border-orange-400 data-[state=checked]:border-orange-400',\n    },\n  ]\n\n  const isEventColor = (value: string): value is EventColor =>\n    colorOptions.some((option) => option.value === value)\n\n  return (\n    <Dialog open={isOpen} onOpenChange={(open) => !open && onClose()}>\n      <DialogContent className=\"sm:max-w-[425px]\">\n        <DialogHeader>\n          <DialogTitle>{event?.id ? 'Edit Event' : 'Create Event'}</DialogTitle>\n          <DialogDescription className=\"sr-only\">\n            {event?.id ? 'Edit the details of this event' : 'Add a new event to your calendar'}\n          </DialogDescription>\n        </DialogHeader>\n        {error && (\n          <div className=\"bg-destructive/15 text-destructive rounded-md px-3 py-2 text-sm\">\n            {error}\n          </div>\n        )}\n        <div className=\"grid gap-4 py-4\">\n          <div className=\"*:not-first:mt-1.5\">\n            <Label htmlFor=\"title\">Title</Label>\n            <Input id=\"title\" value={title} onChange={(e) => setTitle(e.target.value)} />\n          </div>\n\n          <div className=\"*:not-first:mt-1.5\">\n            <Label htmlFor=\"description\">Description</Label>\n            <Textarea\n              id=\"description\"\n              value={description}\n              onChange={(e) => setDescription(e.target.value)}\n              rows={3}\n            />\n          </div>\n\n          <div className=\"flex gap-4\">\n            <div className=\"flex-1 *:not-first:mt-1.5\">\n              <Label htmlFor=\"start-date\">Start Date</Label>\n              <Popover open={startDateOpen} onOpenChange={setStartDateOpen}>\n                <PopoverTrigger asChild>\n                  <Button\n                    id=\"start-date\"\n                    variant={'outline'}\n                    className={cn(\n                      'group bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]',\n                      !startDate && 'text-muted-foreground'\n                    )}\n                  >\n                    <span className={cn('truncate', !startDate && 'text-muted-foreground')}>\n                      {startDate ? format(startDate, 'PPP') : 'Pick a date'}\n                    </span>\n                    <RiCalendarLine\n                      size={16}\n                      className=\"text-muted-foreground/80 shrink-0\"\n                      aria-hidden=\"true\"\n                    />\n                  </Button>\n                </PopoverTrigger>\n                <PopoverContent className=\"w-auto p-2\" align=\"start\">\n                  <Calendar\n                    mode=\"single\"\n                    selected={startDate}\n                    defaultMonth={startDate}\n                    onSelect={(date) => {\n                      if (date) {\n                        setStartDate(date)\n                        // If end date is before the new start date, update it to match the start date\n                        if (isBefore(endDate, date)) {\n                          setEndDate(date)\n                        }\n                        setError(null)\n                        setStartDateOpen(false)\n                      }\n                    }}\n                  />\n                </PopoverContent>\n              </Popover>\n            </div>\n\n            {!allDay && (\n              <div className=\"min-w-28 *:not-first:mt-1.5\">\n                <Label htmlFor=\"start-time\">Start Time</Label>\n                <Select value={startTime} onValueChange={setStartTime}>\n                  <SelectTrigger id=\"start-time\">\n                    <SelectValue placeholder=\"Select time\" />\n                  </SelectTrigger>\n                  <SelectContent>\n                    {timeOptions.map((option) => (\n                      <SelectItem key={option.value} value={option.value}>\n                        {option.label}\n                      </SelectItem>\n                    ))}\n                  </SelectContent>\n                </Select>\n              </div>\n            )}\n          </div>\n\n          <div className=\"flex gap-4\">\n            <div className=\"flex-1 *:not-first:mt-1.5\">\n              <Label htmlFor=\"end-date\">End Date</Label>\n              <Popover open={endDateOpen} onOpenChange={setEndDateOpen}>\n                <PopoverTrigger asChild>\n                  <Button\n                    id=\"end-date\"\n                    variant={'outline'}\n                    className={cn(\n                      'group bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]',\n                      !endDate && 'text-muted-foreground'\n                    )}\n                  >\n                    <span className={cn('truncate', !endDate && 'text-muted-foreground')}>\n                      {endDate ? format(endDate, 'PPP') : 'Pick a date'}\n                    </span>\n                    <RiCalendarLine\n                      size={16}\n                      className=\"text-muted-foreground/80 shrink-0\"\n                      aria-hidden=\"true\"\n                    />\n                  </Button>\n                </PopoverTrigger>\n                <PopoverContent className=\"w-auto p-2\" align=\"start\">\n                  <Calendar\n                    mode=\"single\"\n                    selected={endDate}\n                    defaultMonth={endDate}\n                    disabled={{ before: startDate }}\n                    onSelect={(date) => {\n                      if (date) {\n                        setEndDate(date)\n                        setError(null)\n                        setEndDateOpen(false)\n                      }\n                    }}\n                  />\n                </PopoverContent>\n              </Popover>\n            </div>\n\n            {!allDay && (\n              <div className=\"min-w-28 *:not-first:mt-1.5\">\n                <Label htmlFor=\"end-time\">End Time</Label>\n                <Select value={endTime} onValueChange={setEndTime}>\n                  <SelectTrigger id=\"end-time\">\n                    <SelectValue placeholder=\"Select time\" />\n                  </SelectTrigger>\n                  <SelectContent>\n                    {timeOptions.map((option) => (\n                      <SelectItem key={option.value} value={option.value}>\n                        {option.label}\n                      </SelectItem>\n                    ))}\n                  </SelectContent>\n                </Select>\n              </div>\n            )}\n          </div>\n\n          <div className=\"flex items-center gap-2\">\n            <Checkbox\n              id=\"all-day\"\n              checked={allDay}\n              onCheckedChange={(checked) => setAllDay(checked === true)}\n            />\n            <Label htmlFor=\"all-day\">All day</Label>\n          </div>\n\n          <div className=\"*:not-first:mt-1.5\">\n            <Label htmlFor=\"location\">Location</Label>\n            <Input id=\"location\" value={location} onChange={(e) => setLocation(e.target.value)} />\n          </div>\n          <fieldset className=\"space-y-4\">\n            <legend className=\"text-foreground text-sm leading-none font-medium\">Etiquette</legend>\n            <RadioGroup\n              className=\"flex gap-1.5\"\n              defaultValue={colorOptions[0]?.value}\n              value={color}\n              onValueChange={(value: string) => {\n                if (isEventColor(value)) {\n                  setColor(value)\n                }\n              }}\n            >\n              {colorOptions.map((colorOption) => (\n                <RadioGroupItem\n                  key={colorOption.value}\n                  id={`color-${colorOption.value}`}\n                  value={colorOption.value}\n                  aria-label={colorOption.label}\n                  className={cn('size-6 shadow-none', colorOption.bgClass, colorOption.borderClass)}\n                />\n              ))}\n            </RadioGroup>\n          </fieldset>\n        </div>\n        <DialogFooter className=\"flex-row sm:justify-between\">\n          {event?.id && (\n            <Button variant=\"outline\" size=\"icon\" onClick={handleDelete} aria-label=\"Delete event\">\n              <RiDeleteBinLine size={16} aria-hidden=\"true\" />\n            </Button>\n          )}\n          <div className=\"flex flex-1 justify-end gap-2\">\n            <Button variant=\"outline\" onClick={onClose}>\n              Cancel\n            </Button>\n            <Button onClick={handleSave}>Save</Button>\n          </div>\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/event-calendar/event-item.tsx",
          "type": "registry:component",
          "target": "components/ui/event-item.tsx",
          "content": "'use client'\n\nimport { useMemo } from 'react'\nimport type { DraggableAttributes } from '@dnd-kit/core'\nimport type { SyntheticListenerMap } from '@dnd-kit/core/dist/hooks/utilities'\nimport { cn } from '@timui/core'\nimport { differenceInMinutes, format, getMinutes, isPast } from 'date-fns'\n\nimport {\n  getBorderRadiusClasses,\n  getEventColorClasses,\n  type CalendarEvent,\n} from '@/registry/default/components/event-calendar'\n\n// Using date-fns format with custom formatting:\n// 'h' - hours (1-12)\n// 'a' - am/pm\n// ':mm' - minutes with leading zero (only if the token 'mm' is present)\nconst formatTimeWithOptionalMinutes = (date: Date) => {\n  return format(date, getMinutes(date) === 0 ? 'ha' : 'h:mma').toLowerCase()\n}\n\ninterface EventWrapperProps {\n  event: CalendarEvent\n  isFirstDay?: boolean\n  isLastDay?: boolean\n  isDragging?: boolean\n  onClick?: (e: React.MouseEvent) => void\n  className?: string\n  children: React.ReactNode\n  currentTime?: Date\n  dndListeners?: SyntheticListenerMap\n  dndAttributes?: DraggableAttributes\n  onMouseDown?: (e: React.MouseEvent) => void\n  onTouchStart?: (e: React.TouchEvent) => void\n}\n\n// Shared wrapper component for event styling\nfunction EventWrapper({\n  event,\n  isFirstDay = true,\n  isLastDay = true,\n  isDragging,\n  onClick,\n  className,\n  children,\n  currentTime,\n  dndListeners,\n  dndAttributes,\n  onMouseDown,\n  onTouchStart,\n}: EventWrapperProps) {\n  // Always use the currentTime (if provided) to determine if the event is in the past\n  const displayEnd = currentTime\n    ? new Date(\n        new Date(currentTime).getTime() +\n          (new Date(event.end).getTime() - new Date(event.start).getTime())\n      )\n    : new Date(event.end)\n\n  const isEventInPast = isPast(displayEnd)\n\n  return (\n    <button\n      className={cn(\n        'focus-visible:border-ring focus-visible:ring-ring/50 flex size-full overflow-hidden px-1 text-left font-medium backdrop-blur-md transition outline-none select-none focus-visible:ring-[3px] data-dragging:cursor-grabbing data-dragging:shadow-lg data-past-event:line-through sm:px-2',\n        getEventColorClasses(event.color),\n        getBorderRadiusClasses(isFirstDay, isLastDay),\n        className\n      )}\n      data-dragging={isDragging || undefined}\n      data-past-event={isEventInPast || undefined}\n      onClick={onClick}\n      onMouseDown={onMouseDown}\n      onTouchStart={onTouchStart}\n      {...dndListeners}\n      {...dndAttributes}\n    >\n      {children}\n    </button>\n  )\n}\n\ninterface EventItemProps {\n  event: CalendarEvent\n  view: 'month' | 'week' | 'day' | 'agenda'\n  isDragging?: boolean\n  onClick?: (e: React.MouseEvent) => void\n  showTime?: boolean\n  currentTime?: Date // For updating time during drag\n  isFirstDay?: boolean\n  isLastDay?: boolean\n  children?: React.ReactNode\n  className?: string\n  dndListeners?: SyntheticListenerMap\n  dndAttributes?: DraggableAttributes\n  onMouseDown?: (e: React.MouseEvent) => void\n  onTouchStart?: (e: React.TouchEvent) => void\n}\n\nexport function EventItem({\n  event,\n  view,\n  isDragging,\n  onClick,\n  showTime,\n  currentTime,\n  isFirstDay = true,\n  isLastDay = true,\n  children,\n  className,\n  dndListeners,\n  dndAttributes,\n  onMouseDown,\n  onTouchStart,\n}: EventItemProps) {\n  const eventColor = event.color\n\n  // Use the provided currentTime (for dragging) or the event's actual time\n  const displayStart = useMemo(() => {\n    return currentTime || new Date(event.start)\n  }, [currentTime, event.start])\n\n  const displayEnd = useMemo(() => {\n    return currentTime\n      ? new Date(\n          new Date(currentTime).getTime() +\n            (new Date(event.end).getTime() - new Date(event.start).getTime())\n        )\n      : new Date(event.end)\n  }, [currentTime, event.start, event.end])\n\n  // Calculate event duration in minutes\n  const durationMinutes = useMemo(() => {\n    return differenceInMinutes(displayEnd, displayStart)\n  }, [displayStart, displayEnd])\n\n  const getEventTime = () => {\n    if (event.allDay) return 'All day'\n\n    // For short events (less than 45 minutes), only show start time\n    if (durationMinutes < 45) {\n      return formatTimeWithOptionalMinutes(displayStart)\n    }\n\n    // For longer events, show both start and end time\n    return `${formatTimeWithOptionalMinutes(displayStart)} - ${formatTimeWithOptionalMinutes(displayEnd)}`\n  }\n\n  if (view === 'month') {\n    return (\n      <EventWrapper\n        event={event}\n        isFirstDay={isFirstDay}\n        isLastDay={isLastDay}\n        isDragging={isDragging}\n        onClick={onClick}\n        className={cn(\n          'mt-[var(--event-gap)] h-[var(--event-height)] items-center text-[10px] sm:text-xs',\n          className\n        )}\n        currentTime={currentTime}\n        dndListeners={dndListeners}\n        dndAttributes={dndAttributes}\n        onMouseDown={onMouseDown}\n        onTouchStart={onTouchStart}\n      >\n        {children || (\n          <span className=\"truncate\">\n            {!event.allDay && (\n              <span className=\"truncate font-normal opacity-70 sm:text-[11px]\">\n                {formatTimeWithOptionalMinutes(displayStart)}{' '}\n              </span>\n            )}\n            {event.title}\n          </span>\n        )}\n      </EventWrapper>\n    )\n  }\n\n  if (view === 'week' || view === 'day') {\n    return (\n      <EventWrapper\n        event={event}\n        isFirstDay={isFirstDay}\n        isLastDay={isLastDay}\n        isDragging={isDragging}\n        onClick={onClick}\n        className={cn(\n          'py-1',\n          durationMinutes < 45 ? 'items-center' : 'flex-col',\n          view === 'week' ? 'text-[10px] sm:text-xs' : 'text-xs',\n          className\n        )}\n        currentTime={currentTime}\n        dndListeners={dndListeners}\n        dndAttributes={dndAttributes}\n        onMouseDown={onMouseDown}\n        onTouchStart={onTouchStart}\n      >\n        {durationMinutes < 45 ? (\n          <div className=\"truncate\">\n            {event.title}{' '}\n            {showTime && (\n              <span className=\"opacity-70\">{formatTimeWithOptionalMinutes(displayStart)}</span>\n            )}\n          </div>\n        ) : (\n          <>\n            <div className=\"truncate font-medium\">{event.title}</div>\n            {showTime && (\n              <div className=\"truncate font-normal opacity-70 sm:text-[11px]\">{getEventTime()}</div>\n            )}\n          </>\n        )}\n      </EventWrapper>\n    )\n  }\n\n  // Agenda view - kept separate since it's significantly different\n  return (\n    <button\n      className={cn(\n        'focus-visible:border-ring focus-visible:ring-ring/50 flex w-full flex-col gap-1 rounded p-2 text-left transition outline-none focus-visible:ring-[3px] data-past-event:line-through data-past-event:opacity-90',\n        getEventColorClasses(eventColor),\n        className\n      )}\n      data-past-event={isPast(new Date(event.end)) || undefined}\n      onClick={onClick}\n      onMouseDown={onMouseDown}\n      onTouchStart={onTouchStart}\n      {...dndListeners}\n      {...dndAttributes}\n    >\n      <div className=\"text-sm font-medium\">{event.title}</div>\n      <div className=\"text-xs opacity-70\">\n        {event.allDay ? (\n          <span>All day</span>\n        ) : (\n          <span className=\"uppercase\">\n            {formatTimeWithOptionalMinutes(displayStart)} -{' '}\n            {formatTimeWithOptionalMinutes(displayEnd)}\n          </span>\n        )}\n        {event.location && (\n          <>\n            <span className=\"px-1 opacity-35\"> · </span>\n            <span>{event.location}</span>\n          </>\n        )}\n      </div>\n      {event.description && <div className=\"my-1 text-xs opacity-90\">{event.description}</div>}\n    </button>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/event-calendar/events-popup.tsx",
          "type": "registry:component",
          "target": "components/ui/events-popup.tsx",
          "content": "'use client'\n\nimport { useEffect, useMemo, useRef } from 'react'\nimport { format, isSameDay } from 'date-fns'\nimport { XIcon } from 'lucide-react'\n\nimport { EventItem, type CalendarEvent } from '@/registry/default/components/event-calendar'\n\ninterface EventsPopupProps {\n  date: Date\n  events: CalendarEvent[]\n  position: { top: number; left: number }\n  onClose: () => void\n  onEventSelect: (event: CalendarEvent) => void\n}\n\nexport function EventsPopup({ date, events, position, onClose, onEventSelect }: EventsPopupProps) {\n  const popupRef = useRef<HTMLDivElement>(null)\n\n  // Handle click outside to close popup\n  useEffect(() => {\n    const handleClickOutside = (event: MouseEvent) => {\n      if (popupRef.current && !popupRef.current.contains(event.target as Node)) {\n        onClose()\n      }\n    }\n\n    document.addEventListener('mousedown', handleClickOutside)\n    return () => {\n      document.removeEventListener('mousedown', handleClickOutside)\n    }\n  }, [onClose])\n\n  // Handle escape key to close popup\n  useEffect(() => {\n    const handleEscKey = (event: KeyboardEvent) => {\n      if (event.key === 'Escape') {\n        onClose()\n      }\n    }\n\n    document.addEventListener('keydown', handleEscKey)\n    return () => {\n      document.removeEventListener('keydown', handleEscKey)\n    }\n  }, [onClose])\n\n  const handleEventClick = (event: CalendarEvent) => {\n    onEventSelect(event)\n    onClose()\n  }\n\n  // Adjust position to ensure popup stays within viewport\n  const adjustedPosition = useMemo(() => {\n    const positionCopy = { ...position }\n\n    // Check if we need to adjust the position to fit in the viewport\n    if (popupRef.current) {\n      const rect = popupRef.current.getBoundingClientRect()\n      const viewportWidth = window.innerWidth\n      const viewportHeight = window.innerHeight\n\n      // Adjust horizontally if needed\n      if (positionCopy.left + rect.width > viewportWidth) {\n        positionCopy.left = Math.max(0, viewportWidth - rect.width)\n      }\n\n      // Adjust vertically if needed\n      if (positionCopy.top + rect.height > viewportHeight) {\n        positionCopy.top = Math.max(0, viewportHeight - rect.height)\n      }\n    }\n\n    return positionCopy\n  }, [position])\n\n  return (\n    <div\n      ref={popupRef}\n      className=\"bg-background absolute z-50 max-h-96 w-80 overflow-auto rounded-md border shadow-lg\"\n      style={{\n        top: `${adjustedPosition.top}px`,\n        left: `${adjustedPosition.left}px`,\n      }}\n    >\n      <div className=\"bg-background sticky top-0 flex items-center justify-between border-b p-3\">\n        <h3 className=\"font-medium\">{format(date, 'd MMMM yyyy')}</h3>\n        <button onClick={onClose} className=\"hover:bg-muted rounded-full p-1\" aria-label=\"Close\">\n          <XIcon className=\"h-4 w-4\" />\n        </button>\n      </div>\n\n      <div className=\"space-y-2 p-3\">\n        {events.length === 0 ? (\n          <div className=\"text-muted-foreground py-2 text-sm\">No events</div>\n        ) : (\n          events.map((event) => {\n            const eventStart = new Date(event.start)\n            const eventEnd = new Date(event.end)\n            const isFirstDay = isSameDay(date, eventStart)\n            const isLastDay = isSameDay(date, eventEnd)\n\n            return (\n              <div\n                key={event.id}\n                className=\"cursor-pointer\"\n                onClick={() => handleEventClick(event)}\n              >\n                <EventItem\n                  event={event}\n                  view=\"agenda\"\n                  isFirstDay={isFirstDay}\n                  isLastDay={isLastDay}\n                />\n              </div>\n            )\n          })\n        )}\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/event-calendar/event-calendar.tsx",
          "type": "registry:component",
          "target": "components/ui/event-calendar.tsx",
          "content": "'use client'\n\nimport { useEffect, useMemo, useState } from 'react'\nimport { RiCalendarCheckLine } from '@remixicon/react'\nimport { cn } from '@timui/core'\nimport {\n  Button,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuShortcut,\n  DropdownMenuTrigger,\n} from '@timui/react'\nimport {\n  addDays,\n  addMonths,\n  addWeeks,\n  endOfWeek,\n  format,\n  isSameMonth,\n  startOfWeek,\n  subMonths,\n  subWeeks,\n} from 'date-fns'\nimport { ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, PlusIcon } from 'lucide-react'\nimport { toast } from 'sonner'\n\nimport {\n  addHoursToDate,\n  AgendaDaysToShow,\n  AgendaView,\n  CalendarDndProvider,\n  CalendarEvent,\n  CalendarView,\n  DayView,\n  EventDialog,\n  EventGap,\n  EventHeight,\n  MonthView,\n  WeekCellsHeight,\n  WeekView,\n} from '@/registry/default/components/event-calendar'\n\nexport interface EventCalendarProps {\n  events?: CalendarEvent[]\n  onEventAdd?: (event: CalendarEvent) => void\n  onEventUpdate?: (event: CalendarEvent) => void\n  onEventDelete?: (eventId: string) => void\n  className?: string\n  initialView?: CalendarView\n}\n\nexport function EventCalendar({\n  events = [],\n  onEventAdd,\n  onEventUpdate,\n  onEventDelete,\n  className,\n  initialView = 'month',\n}: EventCalendarProps) {\n  const [currentDate, setCurrentDate] = useState(new Date())\n  const [view, setView] = useState<CalendarView>(initialView)\n  const [isEventDialogOpen, setIsEventDialogOpen] = useState(false)\n  const [selectedEvent, setSelectedEvent] = useState<CalendarEvent | null>(null)\n\n  // Add keyboard shortcuts for view switching\n  useEffect(() => {\n    const handleKeyDown = (e: KeyboardEvent) => {\n      // Skip if user is typing in an input, textarea or contentEditable element\n      // or if the event dialog is open\n      if (\n        isEventDialogOpen ||\n        e.target instanceof HTMLInputElement ||\n        e.target instanceof HTMLTextAreaElement ||\n        (e.target instanceof HTMLElement && e.target.isContentEditable)\n      ) {\n        return\n      }\n\n      switch (e.key.toLowerCase()) {\n        case 'm':\n          setView('month')\n          break\n        case 'w':\n          setView('week')\n          break\n        case 'd':\n          setView('day')\n          break\n        case 'a':\n          setView('agenda')\n          break\n      }\n    }\n\n    window.addEventListener('keydown', handleKeyDown)\n\n    return () => {\n      window.removeEventListener('keydown', handleKeyDown)\n    }\n  }, [isEventDialogOpen])\n\n  const handlePrevious = () => {\n    if (view === 'month') {\n      setCurrentDate(subMonths(currentDate, 1))\n    } else if (view === 'week') {\n      setCurrentDate(subWeeks(currentDate, 1))\n    } else if (view === 'day') {\n      setCurrentDate(addDays(currentDate, -1))\n    } else if (view === 'agenda') {\n      // For agenda view, go back 30 days (a full month)\n      setCurrentDate(addDays(currentDate, -AgendaDaysToShow))\n    }\n  }\n\n  const handleNext = () => {\n    if (view === 'month') {\n      setCurrentDate(addMonths(currentDate, 1))\n    } else if (view === 'week') {\n      setCurrentDate(addWeeks(currentDate, 1))\n    } else if (view === 'day') {\n      setCurrentDate(addDays(currentDate, 1))\n    } else if (view === 'agenda') {\n      // For agenda view, go forward 30 days (a full month)\n      setCurrentDate(addDays(currentDate, AgendaDaysToShow))\n    }\n  }\n\n  const handleToday = () => {\n    setCurrentDate(new Date())\n  }\n\n  const handleEventSelect = (event: CalendarEvent) => {\n    console.log('Event selected:', event) // Debug log\n    setSelectedEvent(event)\n    setIsEventDialogOpen(true)\n  }\n\n  const handleEventCreate = (startTime: Date) => {\n    console.log('Creating new event at:', startTime) // Debug log\n\n    // Snap to 15-minute intervals\n    const minutes = startTime.getMinutes()\n    const remainder = minutes % 15\n    if (remainder !== 0) {\n      if (remainder < 7.5) {\n        // Round down to nearest 15 min\n        startTime.setMinutes(minutes - remainder)\n      } else {\n        // Round up to nearest 15 min\n        startTime.setMinutes(minutes + (15 - remainder))\n      }\n      startTime.setSeconds(0)\n      startTime.setMilliseconds(0)\n    }\n\n    const newEvent: CalendarEvent = {\n      id: '',\n      title: '',\n      start: startTime,\n      end: addHoursToDate(startTime, 1),\n      allDay: false,\n    }\n    setSelectedEvent(newEvent)\n    setIsEventDialogOpen(true)\n  }\n\n  const handleEventSave = (event: CalendarEvent) => {\n    if (event.id) {\n      onEventUpdate?.(event)\n      // Show toast notification when an event is updated\n      toast(`Event \"${event.title}\" updated`, {\n        description: format(new Date(event.start), 'MMM d, yyyy'),\n        position: 'bottom-left',\n      })\n    } else {\n      onEventAdd?.({\n        ...event,\n        id: Math.random().toString(36).substring(2, 11),\n      })\n      // Show toast notification when an event is added\n      toast(`Event \"${event.title}\" added`, {\n        description: format(new Date(event.start), 'MMM d, yyyy'),\n        position: 'bottom-left',\n      })\n    }\n    setIsEventDialogOpen(false)\n    setSelectedEvent(null)\n  }\n\n  const handleEventDelete = (eventId: string) => {\n    const deletedEvent = events.find((e) => e.id === eventId)\n    onEventDelete?.(eventId)\n    setIsEventDialogOpen(false)\n    setSelectedEvent(null)\n\n    // Show toast notification when an event is deleted\n    if (deletedEvent) {\n      toast(`Event \"${deletedEvent.title}\" deleted`, {\n        description: format(new Date(deletedEvent.start), 'MMM d, yyyy'),\n        position: 'bottom-left',\n      })\n    }\n  }\n\n  const handleEventUpdate = (updatedEvent: CalendarEvent) => {\n    onEventUpdate?.(updatedEvent)\n\n    // Show toast notification when an event is updated via drag and drop\n    toast(`Event \"${updatedEvent.title}\" moved`, {\n      description: format(new Date(updatedEvent.start), 'MMM d, yyyy'),\n      position: 'bottom-left',\n    })\n  }\n\n  const viewTitle = useMemo(() => {\n    if (view === 'month') {\n      return format(currentDate, 'MMMM yyyy')\n    } else if (view === 'week') {\n      const start = startOfWeek(currentDate, { weekStartsOn: 0 })\n      const end = endOfWeek(currentDate, { weekStartsOn: 0 })\n      if (isSameMonth(start, end)) {\n        return format(start, 'MMMM yyyy')\n      } else {\n        return `${format(start, 'MMM')} - ${format(end, 'MMM yyyy')}`\n      }\n    } else if (view === 'day') {\n      return (\n        <>\n          <span className=\"min-[480px]:hidden\" aria-hidden=\"true\">\n            {format(currentDate, 'MMM d, yyyy')}\n          </span>\n          <span className=\"max-[479px]:hidden min-md:hidden\" aria-hidden=\"true\">\n            {format(currentDate, 'MMMM d, yyyy')}\n          </span>\n          <span className=\"max-md:hidden\">{format(currentDate, 'EEE MMMM d, yyyy')}</span>\n        </>\n      )\n    } else if (view === 'agenda') {\n      // Show the month range for agenda view\n      const start = currentDate\n      const end = addDays(currentDate, AgendaDaysToShow - 1)\n\n      if (isSameMonth(start, end)) {\n        return format(start, 'MMMM yyyy')\n      } else {\n        return `${format(start, 'MMM')} - ${format(end, 'MMM yyyy')}`\n      }\n    } else {\n      return format(currentDate, 'MMMM yyyy')\n    }\n  }, [currentDate, view])\n\n  return (\n    <div\n      className=\"flex flex-col rounded-lg border has-data-[slot=month-view]:flex-1\"\n      style={\n        {\n          '--event-height': `${EventHeight}px`,\n          '--event-gap': `${EventGap}px`,\n          '--week-cells-height': `${WeekCellsHeight}px`,\n        } as React.CSSProperties\n      }\n    >\n      <CalendarDndProvider onEventUpdate={handleEventUpdate}>\n        <div className={cn('flex items-center justify-between p-2 sm:p-4', className)}>\n          <div className=\"flex items-center gap-1 sm:gap-4\">\n            <Button\n              variant=\"outline\"\n              className=\"aspect-square max-[479px]:p-0!\"\n              onClick={handleToday}\n            >\n              <RiCalendarCheckLine className=\"min-[480px]:hidden\" size={16} aria-hidden=\"true\" />\n              <span className=\"max-[479px]:sr-only\">Today</span>\n            </Button>\n            <div className=\"flex items-center sm:gap-2\">\n              <Button variant=\"ghost\" size=\"icon\" onClick={handlePrevious} aria-label=\"Previous\">\n                <ChevronLeftIcon size={16} aria-hidden=\"true\" />\n              </Button>\n              <Button variant=\"ghost\" size=\"icon\" onClick={handleNext} aria-label=\"Next\">\n                <ChevronRightIcon size={16} aria-hidden=\"true\" />\n              </Button>\n            </div>\n            <h2 className=\"text-sm font-semibold sm:text-lg md:text-xl\">{viewTitle}</h2>\n          </div>\n          <div className=\"flex items-center gap-2\">\n            <DropdownMenu>\n              <DropdownMenuTrigger asChild>\n                <Button variant=\"outline\" className=\"gap-1.5 max-[479px]:h-8\">\n                  <span>\n                    <span className=\"min-[480px]:hidden\" aria-hidden=\"true\">\n                      {view.charAt(0).toUpperCase()}\n                    </span>\n                    <span className=\"max-[479px]:sr-only\">\n                      {view.charAt(0).toUpperCase() + view.slice(1)}\n                    </span>\n                  </span>\n                  <ChevronDownIcon className=\"-me-1 opacity-60\" size={16} aria-hidden=\"true\" />\n                </Button>\n              </DropdownMenuTrigger>\n              <DropdownMenuContent align=\"end\" className=\"min-w-32\">\n                <DropdownMenuItem onClick={() => setView('month')}>\n                  Month <DropdownMenuShortcut>M</DropdownMenuShortcut>\n                </DropdownMenuItem>\n                <DropdownMenuItem onClick={() => setView('week')}>\n                  Week <DropdownMenuShortcut>W</DropdownMenuShortcut>\n                </DropdownMenuItem>\n                <DropdownMenuItem onClick={() => setView('day')}>\n                  Day <DropdownMenuShortcut>D</DropdownMenuShortcut>\n                </DropdownMenuItem>\n                <DropdownMenuItem onClick={() => setView('agenda')}>\n                  Agenda <DropdownMenuShortcut>A</DropdownMenuShortcut>\n                </DropdownMenuItem>\n              </DropdownMenuContent>\n            </DropdownMenu>\n            <Button\n              className=\"aspect-square max-[479px]:p-0!\"\n              onClick={() => {\n                setSelectedEvent(null) // Ensure we're creating a new event\n                setIsEventDialogOpen(true)\n              }}\n            >\n              <PlusIcon className=\"opacity-60 sm:-ms-1\" size={16} aria-hidden=\"true\" />\n              <span className=\"max-sm:sr-only\">New event</span>\n            </Button>\n          </div>\n        </div>\n\n        <div className=\"flex flex-1 flex-col\">\n          {view === 'month' && (\n            <MonthView\n              currentDate={currentDate}\n              events={events}\n              onEventSelect={handleEventSelect}\n              onEventCreate={handleEventCreate}\n            />\n          )}\n          {view === 'week' && (\n            <WeekView\n              currentDate={currentDate}\n              events={events}\n              onEventSelect={handleEventSelect}\n              onEventCreate={handleEventCreate}\n            />\n          )}\n          {view === 'day' && (\n            <DayView\n              currentDate={currentDate}\n              events={events}\n              onEventSelect={handleEventSelect}\n              onEventCreate={handleEventCreate}\n            />\n          )}\n          {view === 'agenda' && (\n            <AgendaView\n              currentDate={currentDate}\n              events={events}\n              onEventSelect={handleEventSelect}\n            />\n          )}\n        </div>\n\n        <EventDialog\n          event={selectedEvent}\n          isOpen={isEventDialogOpen}\n          onClose={() => {\n            setIsEventDialogOpen(false)\n            setSelectedEvent(null)\n          }}\n          onSave={handleEventSave}\n          onDelete={handleEventDelete}\n        />\n      </CalendarDndProvider>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/event-calendar/index.ts",
          "type": "registry:component",
          "target": "components/ui/event-calendar-01/index.ts",
          "content": "'use client'\n\n// Component exports\nexport { AgendaView } from './agenda-view'\nexport { DayView } from './day-view'\nexport { DraggableEvent } from './draggable-event'\nexport { DroppableCell } from './droppable-cell'\nexport { EventDialog } from './event-dialog'\nexport { EventItem } from './event-item'\nexport { EventsPopup } from './events-popup'\nexport { EventCalendar } from './event-calendar'\nexport { MonthView } from './month-view'\nexport { WeekView } from './week-view'\nexport { CalendarDndProvider, useCalendarDnd } from './calendar-dnd-context'\n\n// Constants and utility exports\nexport * from './constants'\nexport * from './utils'\n\n// Hook exports\nexport * from './hooks/use-current-time-indicator'\nexport * from './hooks/use-event-visibility'\n\n// Type exports\nexport type { CalendarEvent, CalendarView, EventColor } from './types'\n"
        },
        {
          "path": "registry/default/components/event-calendar/month-view.tsx",
          "type": "registry:component",
          "target": "components/ui/month-view.tsx",
          "content": "'use client'\n\nimport React, { useEffect, useMemo, useState } from 'react'\nimport { Popover, PopoverContent, PopoverTrigger } from '@timui/react'\nimport {\n  addDays,\n  eachDayOfInterval,\n  endOfMonth,\n  endOfWeek,\n  format,\n  isSameDay,\n  isSameMonth,\n  isToday,\n  startOfMonth,\n  startOfWeek,\n} from 'date-fns'\n\nimport {\n  DraggableEvent,\n  DroppableCell,\n  EventGap,\n  EventHeight,\n  EventItem,\n  getAllEventsForDay,\n  getEventsForDay,\n  getSpanningEventsForDay,\n  sortEvents,\n  useEventVisibility,\n  type CalendarEvent,\n} from '@/registry/default/components/event-calendar'\nimport { DefaultStartHour } from '@/registry/default/components/event-calendar/constants'\n\ninterface MonthViewProps {\n  currentDate: Date\n  events: CalendarEvent[]\n  onEventSelect: (event: CalendarEvent) => void\n  onEventCreate: (startTime: Date) => void\n}\n\nexport function MonthView({ currentDate, events, onEventSelect, onEventCreate }: MonthViewProps) {\n  const days = useMemo(() => {\n    const monthStart = startOfMonth(currentDate)\n    const monthEnd = endOfMonth(monthStart)\n    const calendarStart = startOfWeek(monthStart, { weekStartsOn: 0 })\n    const calendarEnd = endOfWeek(monthEnd, { weekStartsOn: 0 })\n\n    return eachDayOfInterval({ start: calendarStart, end: calendarEnd })\n  }, [currentDate])\n\n  const weekdays = useMemo(() => {\n    return Array.from({ length: 7 }).map((_, i) => {\n      const date = addDays(startOfWeek(new Date()), i)\n      return format(date, 'EEE')\n    })\n  }, [])\n\n  const weeks = useMemo(() => {\n    const result = []\n    let week = []\n\n    for (let i = 0; i < days.length; i++) {\n      week.push(days[i])\n      if (week.length === 7 || i === days.length - 1) {\n        result.push(week)\n        week = []\n      }\n    }\n\n    return result\n  }, [days])\n\n  const handleEventClick = (event: CalendarEvent, e: React.MouseEvent) => {\n    e.stopPropagation()\n    onEventSelect(event)\n  }\n\n  const [isMounted, setIsMounted] = useState(false)\n  const { contentRef, getVisibleEventCount } = useEventVisibility({\n    eventHeight: EventHeight,\n    eventGap: EventGap,\n  })\n\n  useEffect(() => {\n    setIsMounted(true)\n  }, [])\n\n  return (\n    <div data-slot=\"month-view\" className=\"contents\">\n      <div className=\"border-border/70 grid grid-cols-7 border-b\">\n        {weekdays.map((day) => (\n          <div key={day} className=\"text-muted-foreground/70 py-2 text-center text-sm\">\n            {day}\n          </div>\n        ))}\n      </div>\n      <div className=\"grid flex-1 auto-rows-fr\">\n        {weeks.map((week, weekIndex) => (\n          <div key={`week-${weekIndex}`} className=\"grid grid-cols-7 [&:last-child>*]:border-b-0\">\n            {week.map((day, dayIndex) => {\n              if (!day) return null // Skip if day is undefined\n\n              const dayEvents = getEventsForDay(events, day)\n              const spanningEvents = getSpanningEventsForDay(events, day)\n              const isCurrentMonth = isSameMonth(day, currentDate)\n              const cellId = `month-cell-${day.toISOString()}`\n              const allDayEvents = [...spanningEvents, ...dayEvents]\n              const allEvents = getAllEventsForDay(events, day)\n\n              const isReferenceCell = weekIndex === 0 && dayIndex === 0\n              const visibleCount = isMounted ? getVisibleEventCount(allDayEvents.length) : undefined\n              const hasMore = visibleCount !== undefined && allDayEvents.length > visibleCount\n              const remainingCount = hasMore ? allDayEvents.length - visibleCount : 0\n\n              return (\n                <div\n                  key={day.toString()}\n                  className=\"group border-border/70 data-outside-cell:bg-muted/25 data-outside-cell:text-muted-foreground/70 border-r border-b last:border-r-0\"\n                  data-today={isToday(day) || undefined}\n                  data-outside-cell={!isCurrentMonth || undefined}\n                >\n                  <DroppableCell\n                    id={cellId}\n                    date={day}\n                    onClick={() => {\n                      const startTime = new Date(day)\n                      startTime.setHours(DefaultStartHour, 0, 0)\n                      onEventCreate(startTime)\n                    }}\n                  >\n                    <div className=\"group-data-today:bg-primary group-data-today:text-primary-foreground mt-1 inline-flex size-6 items-center justify-center rounded-full text-sm\">\n                      {format(day, 'd')}\n                    </div>\n                    <div\n                      ref={isReferenceCell ? contentRef : null}\n                      className=\"min-h-[calc((var(--event-height)+var(--event-gap))*2)] sm:min-h-[calc((var(--event-height)+var(--event-gap))*3)] lg:min-h-[calc((var(--event-height)+var(--event-gap))*4)]\"\n                    >\n                      {sortEvents(allDayEvents).map((event, index) => {\n                        const eventStart = new Date(event.start)\n                        const eventEnd = new Date(event.end)\n                        const isFirstDay = isSameDay(day, eventStart)\n                        const isLastDay = isSameDay(day, eventEnd)\n\n                        const isHidden = isMounted && visibleCount && index >= visibleCount\n\n                        if (!visibleCount) return null\n\n                        if (!isFirstDay) {\n                          return (\n                            <div\n                              key={`spanning-${event.id}-${day.toISOString().slice(0, 10)}`}\n                              className=\"aria-hidden:hidden\"\n                              aria-hidden={isHidden ? 'true' : undefined}\n                            >\n                              <EventItem\n                                onClick={(e) => handleEventClick(event, e)}\n                                event={event}\n                                view=\"month\"\n                                isFirstDay={isFirstDay}\n                                isLastDay={isLastDay}\n                              >\n                                <div className=\"invisible\" aria-hidden={true}>\n                                  {!event.allDay && (\n                                    <span>{format(new Date(event.start), 'h:mm')} </span>\n                                  )}\n                                  {event.title}\n                                </div>\n                              </EventItem>\n                            </div>\n                          )\n                        }\n\n                        return (\n                          <div\n                            key={event.id}\n                            className=\"aria-hidden:hidden\"\n                            aria-hidden={isHidden ? 'true' : undefined}\n                          >\n                            <DraggableEvent\n                              event={event}\n                              view=\"month\"\n                              onClick={(e) => handleEventClick(event, e)}\n                              isFirstDay={isFirstDay}\n                              isLastDay={isLastDay}\n                            />\n                          </div>\n                        )\n                      })}\n\n                      {hasMore && (\n                        <Popover modal>\n                          <PopoverTrigger asChild>\n                            <button\n                              className=\"focus-visible:border-ring focus-visible:ring-ring/50 text-muted-foreground hover:text-foreground hover:bg-muted/50 mt-[var(--event-gap)] flex h-[var(--event-height)] w-full items-center overflow-hidden px-1 text-left text-[10px] backdrop-blur-md transition outline-none select-none focus-visible:ring-[3px] sm:px-2 sm:text-xs\"\n                              onClick={(e) => e.stopPropagation()}\n                            >\n                              <span>\n                                + {remainingCount} <span className=\"max-sm:sr-only\">more</span>\n                              </span>\n                            </button>\n                          </PopoverTrigger>\n                          <PopoverContent\n                            align=\"center\"\n                            className=\"max-w-52 p-3\"\n                            style={\n                              {\n                                '--event-height': `${EventHeight}px`,\n                              } as React.CSSProperties\n                            }\n                          >\n                            <div className=\"space-y-2\">\n                              <div className=\"text-sm font-medium\">{format(day, 'EEE d')}</div>\n                              <div className=\"space-y-1\">\n                                {sortEvents(allEvents).map((event) => {\n                                  const eventStart = new Date(event.start)\n                                  const eventEnd = new Date(event.end)\n                                  const isFirstDay = isSameDay(day, eventStart)\n                                  const isLastDay = isSameDay(day, eventEnd)\n\n                                  return (\n                                    <EventItem\n                                      key={event.id}\n                                      onClick={(e) => handleEventClick(event, e)}\n                                      event={event}\n                                      view=\"month\"\n                                      isFirstDay={isFirstDay}\n                                      isLastDay={isLastDay}\n                                    />\n                                  )\n                                })}\n                              </div>\n                            </div>\n                          </PopoverContent>\n                        </Popover>\n                      )}\n                    </div>\n                  </DroppableCell>\n                </div>\n              )\n            })}\n          </div>\n        ))}\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/event-calendar/types.ts",
          "type": "registry:component",
          "target": "components/ui/event-calendar-01/types.ts",
          "content": "export type CalendarView = 'month' | 'week' | 'day' | 'agenda'\n\nexport interface CalendarEvent {\n  id: string\n  title: string\n  description?: string\n  start: Date\n  end: Date\n  allDay?: boolean\n  color?: EventColor\n  location?: string\n}\n\nexport type EventColor = 'sky' | 'amber' | 'violet' | 'rose' | 'emerald' | 'orange'\n"
        },
        {
          "path": "registry/default/components/event-calendar/utils.ts",
          "type": "registry:component",
          "target": "components/ui/event-calendar-01/utils.ts",
          "content": "import { isSameDay } from 'date-fns'\n\nimport type { CalendarEvent, EventColor } from '@/registry/default/components/event-calendar'\n\n/**\n * Get CSS classes for event colors\n */\nexport function getEventColorClasses(color?: EventColor | string): string {\n  const eventColor = color || 'sky'\n\n  switch (eventColor) {\n    case 'sky':\n      return 'bg-sky-200/50 hover:bg-sky-200/40 text-sky-950/80 dark:bg-sky-400/25 dark:hover:bg-sky-400/20 dark:text-sky-200 shadow-sky-700/8'\n    case 'amber':\n      return 'bg-amber-200/50 hover:bg-amber-200/40 text-amber-950/80 dark:bg-amber-400/25 dark:hover:bg-amber-400/20 dark:text-amber-200 shadow-amber-700/8'\n    case 'violet':\n      return 'bg-violet-200/50 hover:bg-violet-200/40 text-violet-950/80 dark:bg-violet-400/25 dark:hover:bg-violet-400/20 dark:text-violet-200 shadow-violet-700/8'\n    case 'rose':\n      return 'bg-rose-200/50 hover:bg-rose-200/40 text-rose-950/80 dark:bg-rose-400/25 dark:hover:bg-rose-400/20 dark:text-rose-200 shadow-rose-700/8'\n    case 'emerald':\n      return 'bg-emerald-200/50 hover:bg-emerald-200/40 text-emerald-950/80 dark:bg-emerald-400/25 dark:hover:bg-emerald-400/20 dark:text-emerald-200 shadow-emerald-700/8'\n    case 'orange':\n      return 'bg-orange-200/50 hover:bg-orange-200/40 text-orange-950/80 dark:bg-orange-400/25 dark:hover:bg-orange-400/20 dark:text-orange-200 shadow-orange-700/8'\n    default:\n      return 'bg-sky-200/50 hover:bg-sky-200/40 text-sky-950/80 dark:bg-sky-400/25 dark:hover:bg-sky-400/20 dark:text-sky-200 shadow-sky-700/8'\n  }\n}\n\n/**\n * Get CSS classes for border radius based on event position in multi-day events\n */\nexport function getBorderRadiusClasses(isFirstDay: boolean, isLastDay: boolean): string {\n  if (isFirstDay && isLastDay) {\n    return 'rounded' // Both ends rounded\n  } else if (isFirstDay) {\n    return 'rounded-l rounded-r-none' // Only left end rounded\n  } else if (isLastDay) {\n    return 'rounded-r rounded-l-none' // Only right end rounded\n  } else {\n    return 'rounded-none' // No rounded corners\n  }\n}\n\n/**\n * Check if an event is a multi-day event\n */\nexport function isMultiDayEvent(event: CalendarEvent): boolean {\n  const eventStart = new Date(event.start)\n  const eventEnd = new Date(event.end)\n  return event.allDay || eventStart.getDate() !== eventEnd.getDate()\n}\n\n/**\n * Filter events for a specific day\n */\nexport function getEventsForDay(events: CalendarEvent[], day: Date): CalendarEvent[] {\n  return events\n    .filter((event) => {\n      const eventStart = new Date(event.start)\n      return isSameDay(day, eventStart)\n    })\n    .sort((a, b) => new Date(a.start).getTime() - new Date(b.start).getTime())\n}\n\n/**\n * Sort events with multi-day events first, then by start time\n */\nexport function sortEvents(events: CalendarEvent[]): CalendarEvent[] {\n  return [...events].sort((a, b) => {\n    const aIsMultiDay = isMultiDayEvent(a)\n    const bIsMultiDay = isMultiDayEvent(b)\n\n    if (aIsMultiDay && !bIsMultiDay) return -1\n    if (!aIsMultiDay && bIsMultiDay) return 1\n\n    return new Date(a.start).getTime() - new Date(b.start).getTime()\n  })\n}\n\n/**\n * Get multi-day events that span across a specific day (but don't start on that day)\n */\nexport function getSpanningEventsForDay(events: CalendarEvent[], day: Date): CalendarEvent[] {\n  return events.filter((event) => {\n    if (!isMultiDayEvent(event)) return false\n\n    const eventStart = new Date(event.start)\n    const eventEnd = new Date(event.end)\n\n    // Only include if it's not the start day but is either the end day or a middle day\n    return (\n      !isSameDay(day, eventStart) &&\n      (isSameDay(day, eventEnd) || (day > eventStart && day < eventEnd))\n    )\n  })\n}\n\n/**\n * Get all events visible on a specific day (starting, ending, or spanning)\n */\nexport function getAllEventsForDay(events: CalendarEvent[], day: Date): CalendarEvent[] {\n  return events.filter((event) => {\n    const eventStart = new Date(event.start)\n    const eventEnd = new Date(event.end)\n    return (\n      isSameDay(day, eventStart) || isSameDay(day, eventEnd) || (day > eventStart && day < eventEnd)\n    )\n  })\n}\n\n/**\n * Get all events for a day (for agenda view)\n */\nexport function getAgendaEventsForDay(events: CalendarEvent[], day: Date): CalendarEvent[] {\n  return events\n    .filter((event) => {\n      const eventStart = new Date(event.start)\n      const eventEnd = new Date(event.end)\n      return (\n        isSameDay(day, eventStart) ||\n        isSameDay(day, eventEnd) ||\n        (day > eventStart && day < eventEnd)\n      )\n    })\n    .sort((a, b) => new Date(a.start).getTime() - new Date(b.start).getTime())\n}\n\n/**\n * Add hours to a date\n */\nexport function addHoursToDate(date: Date, hours: number): Date {\n  const result = new Date(date)\n  result.setHours(result.getHours() + hours)\n  return result\n}\n"
        },
        {
          "path": "registry/default/components/event-calendar/week-view.tsx",
          "type": "registry:component",
          "target": "components/ui/week-view.tsx",
          "content": "'use client'\n\nimport React, { useMemo } from 'react'\nimport { cn } from '@timui/core'\nimport {\n  addHours,\n  areIntervalsOverlapping,\n  differenceInMinutes,\n  eachDayOfInterval,\n  eachHourOfInterval,\n  endOfWeek,\n  format,\n  getHours,\n  getMinutes,\n  isBefore,\n  isSameDay,\n  isToday,\n  startOfDay,\n  startOfWeek,\n} from 'date-fns'\n\nimport {\n  DraggableEvent,\n  DroppableCell,\n  EventItem,\n  isMultiDayEvent,\n  useCurrentTimeIndicator,\n  WeekCellsHeight,\n  type CalendarEvent,\n} from '@/registry/default/components/event-calendar'\nimport { EndHour, StartHour } from '@/registry/default/components/event-calendar/constants'\n\ninterface WeekViewProps {\n  currentDate: Date\n  events: CalendarEvent[]\n  onEventSelect: (event: CalendarEvent) => void\n  onEventCreate: (startTime: Date) => void\n}\n\ninterface PositionedEvent {\n  event: CalendarEvent\n  top: number\n  height: number\n  left: number\n  width: number\n  zIndex: number\n}\n\nexport function WeekView({ currentDate, events, onEventSelect, onEventCreate }: WeekViewProps) {\n  const days = useMemo(() => {\n    const weekStart = startOfWeek(currentDate, { weekStartsOn: 0 })\n    const weekEnd = endOfWeek(currentDate, { weekStartsOn: 0 })\n    return eachDayOfInterval({ start: weekStart, end: weekEnd })\n  }, [currentDate])\n\n  const weekStart = useMemo(() => startOfWeek(currentDate, { weekStartsOn: 0 }), [currentDate])\n\n  const hours = useMemo(() => {\n    const dayStart = startOfDay(currentDate)\n    return eachHourOfInterval({\n      start: addHours(dayStart, StartHour),\n      end: addHours(dayStart, EndHour - 1),\n    })\n  }, [currentDate])\n\n  // Get all-day events and multi-day events for the week\n  const allDayEvents = useMemo(() => {\n    return events\n      .filter((event) => {\n        // Include explicitly marked all-day events or multi-day events\n        return event.allDay || isMultiDayEvent(event)\n      })\n      .filter((event) => {\n        const eventStart = new Date(event.start)\n        const eventEnd = new Date(event.end)\n        return days.some(\n          (day) =>\n            isSameDay(day, eventStart) ||\n            isSameDay(day, eventEnd) ||\n            (day > eventStart && day < eventEnd)\n        )\n      })\n  }, [events, days])\n\n  // Process events for each day to calculate positions\n  const processedDayEvents = useMemo(() => {\n    const result = days.map((day) => {\n      // Get events for this day that are not all-day events or multi-day events\n      const dayEvents = events.filter((event) => {\n        // Skip all-day events and multi-day events\n        if (event.allDay || isMultiDayEvent(event)) return false\n\n        const eventStart = new Date(event.start)\n        const eventEnd = new Date(event.end)\n\n        // Check if event is on this day\n        return (\n          isSameDay(day, eventStart) ||\n          isSameDay(day, eventEnd) ||\n          (eventStart < day && eventEnd > day)\n        )\n      })\n\n      // Sort events by start time and duration\n      const sortedEvents = [...dayEvents].sort((a, b) => {\n        const aStart = new Date(a.start)\n        const bStart = new Date(b.start)\n        const aEnd = new Date(a.end)\n        const bEnd = new Date(b.end)\n\n        // First sort by start time\n        if (aStart < bStart) return -1\n        if (aStart > bStart) return 1\n\n        // If start times are equal, sort by duration (longer events first)\n        const aDuration = differenceInMinutes(aEnd, aStart)\n        const bDuration = differenceInMinutes(bEnd, bStart)\n        return bDuration - aDuration\n      })\n\n      // Calculate positions for each event\n      const positionedEvents: PositionedEvent[] = []\n      const dayStart = startOfDay(day)\n\n      // Track columns for overlapping events\n      const columns: { event: CalendarEvent; end: Date }[][] = []\n\n      sortedEvents.forEach((event) => {\n        const eventStart = new Date(event.start)\n        const eventEnd = new Date(event.end)\n\n        // Adjust start and end times if they're outside this day\n        const adjustedStart = isSameDay(day, eventStart) ? eventStart : dayStart\n        const adjustedEnd = isSameDay(day, eventEnd) ? eventEnd : addHours(dayStart, 24)\n\n        // Calculate top position and height\n        const startHour = getHours(adjustedStart) + getMinutes(adjustedStart) / 60\n        const endHour = getHours(adjustedEnd) + getMinutes(adjustedEnd) / 60\n\n        // Adjust the top calculation to account for the new start time\n        const top = (startHour - StartHour) * WeekCellsHeight\n        const height = (endHour - startHour) * WeekCellsHeight\n\n        // Find a column for this event\n        let columnIndex = 0\n        let placed = false\n\n        while (!placed) {\n          const col = columns[columnIndex] || []\n          if (col.length === 0) {\n            columns[columnIndex] = col\n            placed = true\n          } else {\n            const overlaps = col.some((c) =>\n              areIntervalsOverlapping(\n                { start: adjustedStart, end: adjustedEnd },\n                {\n                  start: new Date(c.event.start),\n                  end: new Date(c.event.end),\n                }\n              )\n            )\n            if (!overlaps) {\n              placed = true\n            } else {\n              columnIndex++\n            }\n          }\n        }\n\n        // Ensure column is initialized before pushing\n        const currentColumn = columns[columnIndex] || []\n        columns[columnIndex] = currentColumn\n        currentColumn.push({ event, end: adjustedEnd })\n\n        // Calculate width and left position based on number of columns\n        const width = columnIndex === 0 ? 1 : 0.9\n        const left = columnIndex === 0 ? 0 : columnIndex * 0.1\n\n        positionedEvents.push({\n          event,\n          top,\n          height,\n          left,\n          width,\n          zIndex: 10 + columnIndex, // Higher columns get higher z-index\n        })\n      })\n\n      return positionedEvents\n    })\n\n    return result\n  }, [days, events])\n\n  const handleEventClick = (event: CalendarEvent, e: React.MouseEvent) => {\n    e.stopPropagation()\n    onEventSelect(event)\n  }\n\n  const showAllDaySection = allDayEvents.length > 0\n  const { currentTimePosition, currentTimeVisible } = useCurrentTimeIndicator(currentDate, 'week')\n\n  return (\n    <div data-slot=\"week-view\" className=\"flex h-full flex-col\">\n      <div className=\"bg-background/80 border-border/70 sticky top-0 z-30 grid grid-cols-8 border-b backdrop-blur-md\">\n        <div className=\"text-muted-foreground/70 py-2 text-center text-sm\">\n          <span className=\"max-[479px]:sr-only\">{format(new Date(), 'O')}</span>\n        </div>\n        {days.map((day) => (\n          <div\n            key={day.toString()}\n            className=\"data-today:text-foreground text-muted-foreground/70 py-2 text-center text-sm data-today:font-medium\"\n            data-today={isToday(day) || undefined}\n          >\n            <span className=\"sm:hidden\" aria-hidden=\"true\">\n              {format(day, 'E')[0]} {format(day, 'd')}\n            </span>\n            <span className=\"max-sm:hidden\">{format(day, 'EEE dd')}</span>\n          </div>\n        ))}\n      </div>\n\n      {showAllDaySection && (\n        <div className=\"border-border/70 bg-muted/50 border-b\">\n          <div className=\"grid grid-cols-8\">\n            <div className=\"border-border/70 relative border-r\">\n              <span className=\"text-muted-foreground/70 absolute bottom-0 left-0 h-6 w-16 max-w-full pe-2 text-right text-[10px] sm:pe-4 sm:text-xs\">\n                All day\n              </span>\n            </div>\n            {days.map((day, dayIndex) => {\n              const dayAllDayEvents = allDayEvents.filter((event) => {\n                const eventStart = new Date(event.start)\n                const eventEnd = new Date(event.end)\n                return (\n                  isSameDay(day, eventStart) ||\n                  (day > eventStart && day < eventEnd) ||\n                  isSameDay(day, eventEnd)\n                )\n              })\n\n              return (\n                <div\n                  key={day.toString()}\n                  className=\"border-border/70 relative border-r p-1 last:border-r-0\"\n                  data-today={isToday(day) || undefined}\n                >\n                  {dayAllDayEvents.map((event) => {\n                    const eventStart = new Date(event.start)\n                    const eventEnd = new Date(event.end)\n                    const isFirstDay = isSameDay(day, eventStart)\n                    const isLastDay = isSameDay(day, eventEnd)\n\n                    // Check if this is the first day in the current week view\n                    const isFirstVisibleDay = dayIndex === 0 && isBefore(eventStart, weekStart)\n                    const shouldShowTitle = isFirstDay || isFirstVisibleDay\n\n                    return (\n                      <EventItem\n                        key={`spanning-${event.id}`}\n                        onClick={(e) => handleEventClick(event, e)}\n                        event={event}\n                        view=\"month\"\n                        isFirstDay={isFirstDay}\n                        isLastDay={isLastDay}\n                      >\n                        {/* Show title if it's the first day of the event or the first visible day in the week */}\n                        <div\n                          className={cn('truncate', !shouldShowTitle && 'invisible')}\n                          aria-hidden={!shouldShowTitle}\n                        >\n                          {event.title}\n                        </div>\n                      </EventItem>\n                    )\n                  })}\n                </div>\n              )\n            })}\n          </div>\n        </div>\n      )}\n\n      <div className=\"grid flex-1 grid-cols-8 overflow-hidden\">\n        <div className=\"border-border/70 grid auto-cols-fr border-r\">\n          {hours.map((hour, index) => (\n            <div\n              key={hour.toString()}\n              className=\"border-border/70 relative min-h-[var(--week-cells-height)] border-b last:border-b-0\"\n            >\n              {index > 0 && (\n                <span className=\"bg-background text-muted-foreground/70 absolute -top-3 left-0 flex h-6 w-16 max-w-full items-center justify-end pe-2 text-[10px] sm:pe-4 sm:text-xs\">\n                  {format(hour, 'h a')}\n                </span>\n              )}\n            </div>\n          ))}\n        </div>\n\n        {days.map((day, dayIndex) => (\n          <div\n            key={day.toString()}\n            className=\"border-border/70 relative grid auto-cols-fr border-r last:border-r-0\"\n            data-today={isToday(day) || undefined}\n          >\n            {/* Positioned events */}\n            {(processedDayEvents[dayIndex] ?? []).map((positionedEvent) => (\n              <div\n                key={positionedEvent.event.id}\n                className=\"absolute z-10 px-0.5\"\n                style={{\n                  top: `${positionedEvent.top}px`,\n                  height: `${positionedEvent.height}px`,\n                  left: `${positionedEvent.left * 100}%`,\n                  width: `${positionedEvent.width * 100}%`,\n                  zIndex: positionedEvent.zIndex,\n                }}\n                onClick={(e) => e.stopPropagation()}\n              >\n                <div className=\"size-full\">\n                  <DraggableEvent\n                    event={positionedEvent.event}\n                    view=\"week\"\n                    onClick={(e) => handleEventClick(positionedEvent.event, e)}\n                    showTime\n                    height={positionedEvent.height}\n                  />\n                </div>\n              </div>\n            ))}\n\n            {/* Current time indicator - only show for today's column */}\n            {currentTimeVisible && isToday(day) && (\n              <div\n                className=\"pointer-events-none absolute right-0 left-0 z-20\"\n                style={{ top: `${currentTimePosition}%` }}\n              >\n                <div className=\"relative flex items-center\">\n                  <div className=\"bg-primary absolute -left-1 h-2 w-2 rounded-full\"></div>\n                  <div className=\"bg-primary h-[2px] w-full\"></div>\n                </div>\n              </div>\n            )}\n            {hours.map((hour) => {\n              const hourValue = getHours(hour)\n              return (\n                <div\n                  key={hour.toString()}\n                  className=\"border-border/70 relative min-h-[var(--week-cells-height)] border-b last:border-b-0\"\n                >\n                  {/* Quarter-hour intervals */}\n                  {[0, 1, 2, 3].map((quarter) => {\n                    const quarterHourTime = hourValue + quarter * 0.25\n                    return (\n                      <DroppableCell\n                        key={`${hour.toString()}-${quarter}`}\n                        id={`week-cell-${day.toISOString()}-${quarterHourTime}`}\n                        date={day}\n                        time={quarterHourTime}\n                        className={cn(\n                          'absolute h-[calc(var(--week-cells-height)/4)] w-full',\n                          quarter === 0 && 'top-0',\n                          quarter === 1 && 'top-[calc(var(--week-cells-height)/4)]',\n                          quarter === 2 && 'top-[calc(var(--week-cells-height)/4*2)]',\n                          quarter === 3 && 'top-[calc(var(--week-cells-height)/4*3)]'\n                        )}\n                        onClick={() => {\n                          const startTime = new Date(day)\n                          startTime.setHours(hourValue)\n                          startTime.setMinutes(quarter * 15)\n                          onEventCreate(startTime)\n                        }}\n                      />\n                    )\n                  })}\n                </div>\n              )\n            })}\n          </div>\n        ))}\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/event-calendar/hooks/use-current-time-indicator.ts",
          "type": "registry:component",
          "target": "components/ui/event-calendar-01/use-current-time-indicator.ts",
          "content": "'use client'\n\nimport { useEffect, useState } from 'react'\nimport { endOfWeek, isSameDay, isWithinInterval, startOfWeek } from 'date-fns'\n\nimport { EndHour, StartHour } from '@/registry/default/components/event-calendar/constants'\n\nexport function useCurrentTimeIndicator(currentDate: Date, view: 'day' | 'week') {\n  const [currentTimePosition, setCurrentTimePosition] = useState<number>(0)\n  const [currentTimeVisible, setCurrentTimeVisible] = useState<boolean>(false)\n\n  useEffect(() => {\n    const calculateTimePosition = () => {\n      const now = new Date()\n      const hours = now.getHours()\n      const minutes = now.getMinutes()\n      const totalMinutes = (hours - StartHour) * 60 + minutes\n      const dayStartMinutes = 0 // 12am\n      const dayEndMinutes = (EndHour - StartHour) * 60 // 12am next day\n\n      // Calculate position as percentage of day\n      const position = ((totalMinutes - dayStartMinutes) / (dayEndMinutes - dayStartMinutes)) * 100\n\n      // Check if current day is in view based on the calendar view\n      let isCurrentTimeVisible = false\n\n      if (view === 'day') {\n        isCurrentTimeVisible = isSameDay(now, currentDate)\n      } else if (view === 'week') {\n        const startOfWeekDate = startOfWeek(currentDate, { weekStartsOn: 0 })\n        const endOfWeekDate = endOfWeek(currentDate, { weekStartsOn: 0 })\n        isCurrentTimeVisible = isWithinInterval(now, {\n          start: startOfWeekDate,\n          end: endOfWeekDate,\n        })\n      }\n\n      setCurrentTimePosition(position)\n      setCurrentTimeVisible(isCurrentTimeVisible)\n    }\n\n    // Calculate immediately\n    calculateTimePosition()\n\n    // Update every minute\n    const interval = setInterval(calculateTimePosition, 60000)\n\n    return () => clearInterval(interval)\n  }, [currentDate, view])\n\n  return { currentTimePosition, currentTimeVisible }\n}\n"
        },
        {
          "path": "registry/default/components/event-calendar/hooks/use-event-visibility.ts",
          "type": "registry:component",
          "target": "components/ui/event-calendar-01/use-event-visibility.ts",
          "content": "'use client'\n\nimport { useLayoutEffect, useMemo, useRef, useState } from 'react'\n\ninterface EventVisibilityOptions {\n  eventHeight: number\n  eventGap: number\n}\n\ninterface EventVisibilityResult {\n  contentRef: React.RefObject<HTMLDivElement>\n  contentHeight: number | null\n  getVisibleEventCount: (totalEvents: number) => number\n}\n\n/**\n * Hook for calculating event visibility based on container height\n * Uses ResizeObserver for efficient updates\n */\nexport function useEventVisibility({\n  eventHeight,\n  eventGap,\n}: EventVisibilityOptions): EventVisibilityResult {\n  // Use the standard pattern for React refs\n  const contentRef = useRef<HTMLDivElement>(null)\n  const observerRef = useRef<ResizeObserver | null>(null)\n  const [contentHeight, setContentHeight] = useState<number | null>(null)\n\n  // Use layout effect for synchronous measurement before paint\n  useLayoutEffect(() => {\n    if (!contentRef.current) return\n\n    // Function to update the content height\n    const updateHeight = () => {\n      if (contentRef.current) {\n        setContentHeight(contentRef.current.clientHeight)\n      }\n    }\n\n    // Initial measurement (synchronous)\n    updateHeight()\n\n    // Create observer only once and reuse it\n    if (!observerRef.current) {\n      observerRef.current = new ResizeObserver(() => {\n        // Just call updateHeight when resize is detected\n        updateHeight()\n      })\n    }\n\n    // Start observing the content container\n    observerRef.current.observe(contentRef.current)\n\n    // Clean up function\n    return () => {\n      if (observerRef.current) {\n        observerRef.current.disconnect()\n      }\n    }\n  }, [])\n\n  // Function to calculate visible events for a cell\n  const getVisibleEventCount = useMemo(() => {\n    return (totalEvents: number): number => {\n      if (!contentHeight) return totalEvents\n\n      // Calculate how many events can fit in the container\n      const maxEvents = Math.floor(contentHeight / (eventHeight + eventGap))\n\n      // If all events fit, show them all\n      if (totalEvents <= maxEvents) {\n        return totalEvents\n      } else {\n        // Otherwise, reserve space for \"more\" button by showing one less\n        return maxEvents > 0 ? maxEvents - 1 : 0\n      }\n    }\n  }, [contentHeight, eventHeight, eventGap])\n\n  // Use type assertion to satisfy TypeScript\n  return {\n    contentRef,\n    contentHeight,\n    getVisibleEventCount,\n  } as EventVisibilityResult\n}\n"
        },
        {
          "path": "registry/default/components/event-calendar/event-calendar-01.vue",
          "target": "components/ui/event-calendar-01.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { addDays, setHours, setMinutes, subDays } from 'date-fns'\nimport { Button } from '@timui/vue'\nimport EventCalendar from '@/registry/default/components/event-calendar/event-calendar.vue'\n\ntype CalendarEvent = {\n  id: string\n  title: string\n  start: Date\n  end: Date\n  allDay?: boolean\n  color?: 'sky' | 'amber' | 'orange' | 'emerald' | 'violet' | 'rose'\n  description?: string\n  location?: string\n}\n\nconst events = ref<CalendarEvent[]>([\n  {\n    id: '1',\n    title: 'Annual Planning',\n    description: 'Strategic planning for next year',\n    start: subDays(new Date(), 2),\n    end: subDays(new Date(), 1),\n    allDay: true,\n    color: 'sky',\n    location: 'Main Conference Hall',\n  },\n  {\n    id: '2',\n    title: 'Team Meeting',\n    description: 'Weekly sync',\n    start: setMinutes(setHours(new Date(), 10), 0),\n    end: setMinutes(setHours(new Date(), 11), 0),\n    color: 'amber',\n    location: 'Conference Room A',\n  },\n  {\n    id: '3',\n    title: 'Product Launch',\n    start: addDays(new Date(), 3),\n    end: addDays(new Date(), 4),\n    allDay: true,\n    color: 'violet',\n  },\n])\n\nconst addEvent = () => {\n  const id = String(Date.now())\n  events.value = [\n    ...events.value,\n    {\n      id,\n      title: `New Event ${events.value.length + 1}`,\n      start: addDays(new Date(), 1),\n      end: addDays(new Date(), 1),\n      allDay: true,\n      color: 'emerald',\n    },\n  ]\n}\n\nconst removeLast = () => {\n  events.value = events.value.slice(0, -1)\n}\n</script>\n\n<template>\n  <div class=\"space-y-3\">\n    <div class=\"flex items-center gap-2\">\n      <Button size=\"sm\" variant=\"outline\" @click=\"addEvent\">Add event</Button>\n      <Button size=\"sm\" variant=\"outline\" :disabled=\"events.length === 0\" @click=\"removeLast\">\n        Remove last\n      </Button>\n    </div>\n    <EventCalendar :events=\"events\" />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/event-calendar/event-calendar-01.html",
          "target": "components/ui/event-calendar-01.html",
          "type": "registry:component",
          "content": "<template>\n  <EventCalendar events=\"${events}\" oneventadd=\"${handleEventAdd}\" oneventupdate=\"${handleEventUpdate}\" oneventdelete=\"${handleEventDelete}\" />\n</template>"
        },
        {
          "path": "registry/default/components/event-calendar/event-calendar-01.wxml",
          "target": "components/ui/event-calendar-01/event-calendar-01.wxml",
          "type": "registry:component",
          "content": "<view>\n  <eventcalendar events=\"{{events}}\" oneventadd=\"{{handleEventAdd}}\" oneventupdate=\"{{handleEventUpdate}}\" oneventdelete=\"{{handleEventDelete}}\" />\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "calendar"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "event-calendar-01",
          "group": "event-calendar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "event-calendar-01",
              "path": "registry/default/components/event-calendar/event-calendar-01.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "event-calendar-01",
              "path": "registry/default/components/event-calendar/event-calendar-01.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "event-calendar-01",
              "path": "registry/default/components/event-calendar/event-calendar-01.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "event-calendar-01",
              "path": "registry/default/components/event-calendar/event-calendar-01.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@dnd-kit/core",
              "@dnd-kit/core/dist/hooks/utilities",
              "@dnd-kit/utilities",
              "@remixicon/react",
              "@timui/core",
              "@timui/react",
              "date-fns"
            ],
            "optionalPeerDependencies": [
              "lucide-react",
              "sonner"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue",
              "date-fns"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "event-calendar",
        "title": "Event Calendar · No events found"
      },
      "categories": [
        "event-calendar"
      ]
    },
    {
      "name": "file-upload-03",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/file-upload/file-upload-03.tsx",
          "type": "registry:component",
          "target": "components/ui/file-upload-03.tsx",
          "content": "'use client'\n\nimport { Button } from '@timui/react'\nimport { CircleUserRoundIcon, XIcon } from 'lucide-react'\n\nimport { useFileUpload } from '@/registry/default/hooks/use-file-upload'\n\nexport default function Component() {\n  const [\n    { files, isDragging },\n    {\n      removeFile,\n      openFileDialog,\n      getInputProps,\n      handleDragEnter,\n      handleDragLeave,\n      handleDragOver,\n      handleDrop,\n    },\n  ] = useFileUpload({\n    accept: 'image/*',\n  })\n\n  const previewUrl = files[0]?.preview || null\n\n  return (\n    <div className=\"flex flex-col items-center gap-2\">\n      <div className=\"relative inline-flex\">\n        {/* Drop area */}\n        <button\n          className=\"border-input hover:bg-accent/50 data-[dragging=true]:bg-accent/50 focus-visible:border-ring focus-visible:ring-ring/50 relative flex size-16 items-center justify-center overflow-hidden rounded-full border border-dashed transition-colors outline-none focus-visible:ring-[3px] has-disabled:pointer-events-none has-disabled:opacity-50 has-[img]:border-none\"\n          onClick={openFileDialog}\n          onDragEnter={handleDragEnter}\n          onDragLeave={handleDragLeave}\n          onDragOver={handleDragOver}\n          onDrop={handleDrop}\n          data-dragging={isDragging || undefined}\n          aria-label={previewUrl ? 'Change image' : 'Upload image'}\n        >\n          {previewUrl ? (\n            <img\n              className=\"size-full object-cover\"\n              src={previewUrl}\n              alt={files[0]?.file?.name || 'Uploaded image'}\n              width={64}\n              height={64}\n              style={{ objectFit: 'cover' }}\n            />\n          ) : (\n            <div aria-hidden=\"true\">\n              <CircleUserRoundIcon className=\"size-4 opacity-60\" />\n            </div>\n          )}\n        </button>\n        {previewUrl && (\n          <Button\n            onClick={() => removeFile(files[0]?.id)}\n            size=\"icon\"\n            className=\"border-background focus-visible:border-background absolute -top-1 -right-1 size-6 rounded-full border-2 shadow-none\"\n            aria-label=\"Remove image\"\n          >\n            <XIcon className=\"size-3.5\" />\n          </Button>\n        )}\n        <input\n          {...getInputProps()}\n          className=\"sr-only\"\n          aria-label=\"Upload image file\"\n          tabIndex={-1}\n        />\n      </div>\n      <p aria-live=\"polite\" role=\"region\" className=\"text-muted-foreground mt-2 text-xs\">\n        Avatar uploader with droppable area ∙{' '}\n        <a\n          href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\"\n          className=\"hover:text-foreground underline\"\n        >\n          API\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/hooks/use-file-upload.ts",
          "type": "registry:hook",
          "target": "components/ui/file-upload-03/use-file-upload.ts",
          "content": "'use client'\n\nimport type React from 'react'\nimport {\n  useCallback,\n  useRef,\n  useState,\n  type ChangeEvent,\n  type DragEvent,\n  type InputHTMLAttributes,\n} from 'react'\n\nexport type FileMetadata = {\n  name: string\n  size: number\n  type: string\n  url: string\n  id: string\n}\n\nexport type FileWithPreview = {\n  file: File | FileMetadata\n  id: string\n  preview?: string\n}\n\nexport type FileUploadOptions = {\n  maxFiles?: number // Only used when multiple is true, defaults to Infinity\n  maxSize?: number // in bytes\n  accept?: string\n  multiple?: boolean // Defaults to false\n  initialFiles?: FileMetadata[]\n  onFilesChange?: (files: FileWithPreview[]) => void // Callback when files change\n  onFilesAdded?: (addedFiles: FileWithPreview[]) => void // Callback when new files are added\n}\n\nexport type FileUploadState = {\n  files: FileWithPreview[]\n  isDragging: boolean\n  errors: string[]\n}\n\nexport type FileUploadActions = {\n  addFiles: (files: FileList | File[]) => void\n  removeFile: (id: string) => void\n  clearFiles: () => void\n  clearErrors: () => void\n  handleDragEnter: (e: DragEvent<HTMLElement>) => void\n  handleDragLeave: (e: DragEvent<HTMLElement>) => void\n  handleDragOver: (e: DragEvent<HTMLElement>) => void\n  handleDrop: (e: DragEvent<HTMLElement>) => void\n  handleFileChange: (e: ChangeEvent<HTMLInputElement>) => void\n  openFileDialog: () => void\n  getInputProps: (\n    props?: InputHTMLAttributes<HTMLInputElement>\n  ) => InputHTMLAttributes<HTMLInputElement> & {\n    ref: React.Ref<HTMLInputElement>\n  }\n}\n\nexport const useFileUpload = (\n  options: FileUploadOptions = {}\n): [FileUploadState, FileUploadActions] => {\n  const {\n    maxFiles = Infinity,\n    maxSize = Infinity,\n    accept = '*',\n    multiple = false,\n    initialFiles = [],\n    onFilesChange,\n    onFilesAdded,\n  } = options\n\n  const [state, setState] = useState<FileUploadState>({\n    files: initialFiles.map((file) => ({\n      file,\n      id: file.id,\n      preview: file.url,\n    })),\n    isDragging: false,\n    errors: [],\n  })\n\n  const inputRef = useRef<HTMLInputElement>(null)\n\n  const validateFile = useCallback(\n    (file: File | FileMetadata): string | null => {\n      if (file instanceof File) {\n        if (file.size > maxSize) {\n          return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n        }\n      } else {\n        if (file.size > maxSize) {\n          return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n        }\n      }\n\n      if (accept !== '*') {\n        const acceptedTypes = accept.split(',').map((type) => type.trim())\n        const fileType = file instanceof File ? file.type || '' : file.type\n        const fileExtension = `.${file instanceof File ? file.name.split('.').pop() : file.name.split('.').pop()}`\n\n        const isAccepted = acceptedTypes.some((type) => {\n          if (type.startsWith('.')) {\n            return fileExtension.toLowerCase() === type.toLowerCase()\n          }\n          if (type.endsWith('/*')) {\n            const baseType = type.split('/')[0]\n            return fileType.startsWith(`${baseType}/`)\n          }\n          return fileType === type\n        })\n\n        if (!isAccepted) {\n          return `File \"${file instanceof File ? file.name : file.name}\" is not an accepted file type.`\n        }\n      }\n\n      return null\n    },\n    [accept, maxSize]\n  )\n\n  const createPreview = useCallback((file: File | FileMetadata): string | undefined => {\n    if (file instanceof File) {\n      return URL.createObjectURL(file)\n    }\n    return file.url\n  }, [])\n\n  const generateUniqueId = useCallback((file: File | FileMetadata): string => {\n    if (file instanceof File) {\n      return `${file.name}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`\n    }\n    return file.id\n  }, [])\n\n  const clearFiles = useCallback(() => {\n    setState((prev) => {\n      // Clean up object URLs\n      prev.files.forEach((file) => {\n        if (file.preview && file.file instanceof File && file.file.type.startsWith('image/')) {\n          URL.revokeObjectURL(file.preview)\n        }\n      })\n\n      if (inputRef.current) {\n        inputRef.current.value = ''\n      }\n\n      const newState = {\n        ...prev,\n        files: [],\n        errors: [],\n      }\n\n      onFilesChange?.(newState.files)\n      return newState\n    })\n  }, [onFilesChange])\n\n  const addFiles = useCallback(\n    (newFiles: FileList | File[]) => {\n      if (!newFiles || newFiles.length === 0) return\n\n      const newFilesArray = Array.from(newFiles)\n      const errors: string[] = []\n\n      // Clear existing errors when new files are uploaded\n      setState((prev) => ({ ...prev, errors: [] }))\n\n      // In single file mode, clear existing files first\n      if (!multiple) {\n        clearFiles()\n      }\n\n      // Check if adding these files would exceed maxFiles (only in multiple mode)\n      if (\n        multiple &&\n        maxFiles !== Infinity &&\n        state.files.length + newFilesArray.length > maxFiles\n      ) {\n        errors.push(`You can only upload a maximum of ${maxFiles} files.`)\n        setState((prev) => ({ ...prev, errors }))\n        return\n      }\n\n      const validFiles: FileWithPreview[] = []\n\n      newFilesArray.forEach((file) => {\n        // Only check for duplicates if multiple files are allowed\n        if (multiple) {\n          const isDuplicate = state.files.some(\n            (existingFile) =>\n              existingFile.file.name === file.name && existingFile.file.size === file.size\n          )\n\n          // Skip duplicate files silently\n          if (isDuplicate) {\n            return\n          }\n        }\n\n        // Check file size\n        if (file.size > maxSize) {\n          errors.push(\n            multiple\n              ? `Some files exceed the maximum size of ${formatBytes(maxSize)}.`\n              : `File exceeds the maximum size of ${formatBytes(maxSize)}.`\n          )\n          return\n        }\n\n        const error = validateFile(file)\n        if (error) {\n          errors.push(error)\n        } else {\n          validFiles.push({\n            file,\n            id: generateUniqueId(file),\n            preview: createPreview(file),\n          })\n        }\n      })\n\n      // Only update state if we have valid files to add\n      if (validFiles.length > 0) {\n        // Call the onFilesAdded callback with the newly added valid files\n        onFilesAdded?.(validFiles)\n\n        setState((prev) => {\n          const newFiles = !multiple ? validFiles : [...prev.files, ...validFiles]\n          onFilesChange?.(newFiles)\n          return {\n            ...prev,\n            files: newFiles,\n            errors,\n          }\n        })\n      } else if (errors.length > 0) {\n        setState((prev) => ({\n          ...prev,\n          errors,\n        }))\n      }\n\n      // Reset input value after handling files\n      if (inputRef.current) {\n        inputRef.current.value = ''\n      }\n    },\n    [\n      state.files,\n      maxFiles,\n      multiple,\n      maxSize,\n      validateFile,\n      createPreview,\n      generateUniqueId,\n      clearFiles,\n      onFilesChange,\n      onFilesAdded,\n    ]\n  )\n\n  const removeFile = useCallback(\n    (id: string) => {\n      setState((prev) => {\n        const fileToRemove = prev.files.find((file) => file.id === id)\n        if (\n          fileToRemove &&\n          fileToRemove.preview &&\n          fileToRemove.file instanceof File &&\n          fileToRemove.file.type.startsWith('image/')\n        ) {\n          URL.revokeObjectURL(fileToRemove.preview)\n        }\n\n        const newFiles = prev.files.filter((file) => file.id !== id)\n        onFilesChange?.(newFiles)\n\n        return {\n          ...prev,\n          files: newFiles,\n          errors: [],\n        }\n      })\n    },\n    [onFilesChange]\n  )\n\n  const clearErrors = useCallback(() => {\n    setState((prev) => ({\n      ...prev,\n      errors: [],\n    }))\n  }, [])\n\n  const handleDragEnter = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n    setState((prev) => ({ ...prev, isDragging: true }))\n  }, [])\n\n  const handleDragLeave = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n\n    if (e.currentTarget.contains(e.relatedTarget as Node)) {\n      return\n    }\n\n    setState((prev) => ({ ...prev, isDragging: false }))\n  }, [])\n\n  const handleDragOver = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n  }, [])\n\n  const handleDrop = useCallback(\n    (e: DragEvent<HTMLElement>) => {\n      e.preventDefault()\n      e.stopPropagation()\n      setState((prev) => ({ ...prev, isDragging: false }))\n\n      // Don't process files if the input is disabled\n      if (inputRef.current?.disabled) {\n        return\n      }\n\n      if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n        // In single file mode, only use the first file\n        if (!multiple) {\n          const file = e.dataTransfer.files[0]\n          addFiles([file])\n        } else {\n          addFiles(e.dataTransfer.files)\n        }\n      }\n    },\n    [addFiles, multiple]\n  )\n\n  const handleFileChange = useCallback(\n    (e: ChangeEvent<HTMLInputElement>) => {\n      if (e.target.files && e.target.files.length > 0) {\n        addFiles(e.target.files)\n      }\n    },\n    [addFiles]\n  )\n\n  const openFileDialog = useCallback(() => {\n    if (inputRef.current) {\n      inputRef.current.click()\n    }\n  }, [])\n\n  const getInputProps = useCallback(\n    (props: InputHTMLAttributes<HTMLInputElement> = {}) => {\n      return {\n        ...props,\n        type: 'file' as const,\n        onChange: handleFileChange,\n        accept: props.accept || accept,\n        multiple: props.multiple !== undefined ? props.multiple : multiple,\n        ref: inputRef,\n      }\n    },\n    [accept, multiple, handleFileChange]\n  )\n\n  return [\n    state,\n    {\n      addFiles,\n      removeFile,\n      clearFiles,\n      clearErrors,\n      handleDragEnter,\n      handleDragLeave,\n      handleDragOver,\n      handleDrop,\n      handleFileChange,\n      openFileDialog,\n      getInputProps,\n    },\n  ]\n}\n\n// Helper function to format bytes to human-readable format\nexport const formatBytes = (bytes: number, decimals = 2): string => {\n  if (bytes === 0) return '0 Bytes'\n\n  const k = 1024\n  const dm = decimals < 0 ? 0 : decimals\n  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']\n\n  const i = Math.floor(Math.log(bytes) / Math.log(k))\n\n  return Number.parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + sizes[i]\n}\n"
        },
        {
          "path": "registry/default/components/file-upload/file-upload-03.vue",
          "target": "components/ui/file-upload-03.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { CircleUserRoundIcon, XIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { useFileUpload } from '@/registry/default/hooks/use-file-upload-vue';\n\nconst [\n  { files, isDragging },\n  {\n    removeFile,\n    openFileDialog,\n    getInputProps,\n    handleDragEnter,\n    handleDragLeave,\n    handleDragOver,\n    handleDrop,\n  },\n] = useFileUpload({\n  accept: 'image/*',\n});\n\nconst previewUrl = computed(() => files.value[0]?.preview ?? null);\n\nfunction removeCurrentFile() {\n  const fileId = files.value[0]?.id;\n  if (fileId) {\n    removeFile(fileId);\n  }\n}\n</script>\n\n<template>\n  <div class=\"flex flex-col items-center gap-2\">\n    <div class=\"relative inline-flex\">\n      <button\n        class=\"border-input hover:bg-accent/50 data-[dragging=true]:bg-accent/50 focus-visible:border-ring focus-visible:ring-ring/50 relative flex size-16 items-center justify-center overflow-hidden rounded-full border border-dashed transition-colors outline-none focus-visible:ring-[3px] has-disabled:pointer-events-none has-disabled:opacity-50 has-[img]:border-none\"\n        @click=\"openFileDialog\"\n        @dragenter=\"handleDragEnter\"\n        @dragleave=\"handleDragLeave\"\n        @dragover=\"handleDragOver\"\n        @drop=\"handleDrop\"\n        :data-dragging=\"isDragging || undefined\"\n        :aria-label=\"previewUrl ? 'Change image' : 'Upload image'\"\n      >\n        <template v-if=\"previewUrl\">\n          <img\n            class=\"size-full object-cover\"\n            :src=\"previewUrl\"\n            :alt=\"files[0]?.file?.name || 'Uploaded image'\"\n            :width=\"64\"\n            :height=\"64\"\n            :style=\"{ objectFit: 'cover' }\"\n          />\n        </template>\n        <template v-else>\n          <div aria-hidden=\"true\">\n            <CircleUserRoundIcon class=\"size-4 opacity-60\" />\n          </div>\n        </template>\n      </button>\n      <Button\n        v-if=\"previewUrl\"\n        @click=\"removeCurrentFile\"\n        size=\"icon\"\n        class=\"border-background focus-visible:border-background absolute -top-1 -right-1 size-6 rounded-full border-2 shadow-none\"\n        aria-label=\"Remove image\"\n      >\n        <XIcon class=\"size-3.5\" />\n      </Button>\n      <input\n        v-bind=\"getInputProps()\"\n        class=\"sr-only\"\n        aria-label=\"Upload image file\"\n        :tabIndex=\"-1\"\n      />\n    </div>\n    <p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">\n      Avatar uploader with droppable area ∙\n      <a\n        href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\"\n        class=\"hover:text-foreground underline\"\n      >\n        API\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/file-upload/file-upload-03.html",
          "target": "components/ui/file-upload-03.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex flex-col items-center gap-2\"><div class=\"relative inline-flex\"><button class=\"border-input hover:bg-accent/50 data-[dragging=true]:bg-accent/50 focus-visible:border-ring focus-visible:ring-ring/50 relative flex size-16 items-center justify-center overflow-hidden rounded-full border border-dashed transition-colors outline-none focus-visible:ring-[3px] has-disabled:pointer-events-none has-disabled:opacity-50 has-[img]:border-none\" on-click=\"${openFileDialog}\" ondragenter=\"${handleDragEnter}\" ondragleave=\"${handleDragLeave}\" ondragover=\"${handleDragOver}\" ondrop=\"${handleDrop}\" data-dragging=\"${isDragging || undefined}\" aria-label=\"${previewUrl ? 'Change image' : 'Upload image'}\"><!-- if previewUrl -->\n<img class=\"size-full object-cover\" src=\"${previewUrl}\" alt=\"${files[0]?.file?.name || 'Uploaded image'}\" width=\"${64}\" height=\"${64}\" style=\"${{ objectFit: 'cover' }}\" />\n<!-- else -->\n<div aria-hidden=\"true\"><CircleUserRoundIcon class=\"size-4 opacity-60\" /></div>\n<!-- endif --></button><!-- if previewUrl -->\n<Button on-click=\"${() => removeFile(files[0]?.id)}\" size=\"icon\" class=\"border-background focus-visible:border-background absolute -top-1 -right-1 size-6 rounded-full border-2 shadow-none\" aria-label=\"Remove image\"><XIcon class=\"size-3.5\" /></Button>\n<!-- endif --><input class=\"sr-only\" aria-label=\"Upload image file\" tabindex=\"${-1}\" /></div><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Avatar uploader with droppable area ∙${' '}<a href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\" class=\"hover:text-foreground underline\">API\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/file-upload/file-upload-03.wxml",
          "target": "components/ui/file-upload-03/file-upload-03.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex flex-col items-center gap-2\"><view class=\"relative inline-flex\"><button class=\"border-input hover:bg-accent/50 data-[dragging=true]:bg-accent/50 focus-visible:border-ring focus-visible:ring-ring/50 relative flex size-16 items-center justify-center overflow-hidden rounded-full border border-dashed transition-colors outline-none focus-visible:ring-[3px] has-disabled:pointer-events-none has-disabled:opacity-50 has-[img]:border-none\" bindtap=\"openFileDialog\" ondragenter=\"{{handleDragEnter}}\" ondragleave=\"{{handleDragLeave}}\" ondragover=\"{{handleDragOver}}\" ondrop=\"{{handleDrop}}\" data-dragging=\"{{isDragging || undefined}}\" aria-label=\"{{previewUrl ? 'Change image' : 'Upload image'}}\"><block wx:if=\"{{previewUrl}}\">\n<image class=\"size-full object-cover\" src=\"{{previewUrl}}\" alt=\"{{files[0]?.file?.name || 'Uploaded image'}}\" width=\"{{64}}\" height=\"{{64}}\" style=\"{{{ objectFit: 'cover' }}}\" />\n</block>\n<block wx:else>\n<view aria-hidden=\"true\"><circleuserroundicon class=\"size-4 opacity-60\" /></view>\n</block></button><button wx:if=\"{{previewUrl}}\" bindtap=\"removeFile(files[0]?.id)\" size=\"icon\" class=\"border-background focus-visible:border-background absolute -top-1 -right-1 size-6 rounded-full border-2 shadow-none\" aria-label=\"Remove image\"><xicon class=\"size-3.5\" /></button><input class=\"sr-only\" aria-label=\"Upload image file\" tabindex=\"{{-1}}\" /></view><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Avatar uploader with droppable area ∙{{ ' ' }}<a href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\" class=\"hover:text-foreground underline\">API\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "upload",
          "file",
          "image",
          "drag and drop",
          "avatar"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "file-upload-03",
          "group": "file-upload",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "file-upload-03",
              "path": "registry/default/components/file-upload/file-upload-03.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "file-upload-03",
              "path": "registry/default/components/file-upload/file-upload-03.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "file-upload-03",
              "path": "registry/default/components/file-upload/file-upload-03.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "file-upload-03",
              "path": "registry/default/components/file-upload/file-upload-03.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "file-upload",
        "title": "File Upload · Remove image"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "file-upload"
      ]
    },
    {
      "name": "file-upload-04",
      "type": "registry:component",
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/file-upload/file-upload-04.tsx",
          "type": "registry:component",
          "target": "components/ui/file-upload-04.tsx",
          "content": "'use client'\n\nimport { Button } from '@timui/react'\nimport { AlertCircleIcon, ImageUpIcon, XIcon } from 'lucide-react'\n\nimport { useFileUpload } from '@/registry/default/hooks/use-file-upload'\n\nexport default function Component() {\n  const maxSizeMB = 5\n  const maxSize = maxSizeMB * 1024 * 1024\n\n  const [\n    { files, isDragging, errors },\n    {\n      handleDragEnter,\n      handleDragLeave,\n      handleDragOver,\n      handleDrop,\n      openFileDialog,\n      removeFile,\n      getInputProps,\n    },\n  ] = useFileUpload({\n    accept: 'image/*',\n    maxSize,\n  })\n\n  const previewUrl = files[0]?.preview || null\n\n  return (\n    <div className=\"flex flex-col gap-2\">\n      <div className=\"relative\">\n        <div\n          role=\"button\"\n          onClick={openFileDialog}\n          onDragEnter={handleDragEnter}\n          onDragLeave={handleDragLeave}\n          onDragOver={handleDragOver}\n          onDrop={handleDrop}\n          data-dragging={isDragging || undefined}\n          className=\"border-input hover:bg-accent/50 data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 relative flex min-h-52 flex-col items-center justify-center overflow-hidden rounded-xl border border-dashed p-4 transition-colors has-disabled:pointer-events-none has-disabled:opacity-50 has-[img]:border-none has-[input:focus]:ring-[3px]\"\n        >\n          <input {...getInputProps()} className=\"sr-only\" aria-label=\"Upload file\" />\n          {previewUrl ? (\n            <div className=\"absolute inset-0\">\n              <img\n                src={previewUrl}\n                alt={files[0]?.file?.name || 'Uploaded image'}\n                className=\"size-full object-cover\"\n              />\n            </div>\n          ) : (\n            <div className=\"flex flex-col items-center justify-center px-4 py-3 text-center\">\n              <div\n                className=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\"\n                aria-hidden=\"true\"\n              >\n                <ImageUpIcon className=\"size-4 opacity-60\" />\n              </div>\n              <p className=\"mb-1.5 text-sm font-medium\">Drop your image here or click to browse</p>\n              <p className=\"text-muted-foreground text-xs\">Max size: {maxSizeMB}MB</p>\n            </div>\n          )}\n        </div>\n\n        {previewUrl ? (\n          <div className=\"absolute top-4 right-4\">\n            <Button\n              size=\"icon\"\n              type=\"button\"\n              className=\"size-8 rounded-full bg-black/60 text-white shadow-none hover:bg-black/80\"\n              onClick={() => removeFile(files[0]?.id)}\n              aria-label=\"Remove image\"\n            >\n              <XIcon className=\"size-4\" aria-hidden=\"true\" />\n            </Button>\n          </div>\n        ) : null}\n      </div>\n\n      {errors.length > 0 ? (\n        <div className=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\">\n          <AlertCircleIcon className=\"size-3 shrink-0\" />\n          <span>{errors[0]}</span>\n        </div>\n      ) : null}\n\n      <p\n        aria-live=\"polite\"\n        role=\"region\"\n        className=\"text-muted-foreground mt-2 text-center text-xs\"\n      >\n        Single image uploader w/ max size ∙{' '}\n        <a\n          href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\"\n          className=\"hover:text-foreground underline\"\n        >\n          API\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/hooks/use-file-upload.ts",
          "type": "registry:hook",
          "target": "components/ui/file-upload-04/use-file-upload.ts",
          "content": "'use client'\n\nimport type React from 'react'\nimport {\n  useCallback,\n  useRef,\n  useState,\n  type ChangeEvent,\n  type DragEvent,\n  type InputHTMLAttributes,\n} from 'react'\n\nexport type FileMetadata = {\n  name: string\n  size: number\n  type: string\n  url: string\n  id: string\n}\n\nexport type FileWithPreview = {\n  file: File | FileMetadata\n  id: string\n  preview?: string\n}\n\nexport type FileUploadOptions = {\n  maxFiles?: number // Only used when multiple is true, defaults to Infinity\n  maxSize?: number // in bytes\n  accept?: string\n  multiple?: boolean // Defaults to false\n  initialFiles?: FileMetadata[]\n  onFilesChange?: (files: FileWithPreview[]) => void // Callback when files change\n  onFilesAdded?: (addedFiles: FileWithPreview[]) => void // Callback when new files are added\n}\n\nexport type FileUploadState = {\n  files: FileWithPreview[]\n  isDragging: boolean\n  errors: string[]\n}\n\nexport type FileUploadActions = {\n  addFiles: (files: FileList | File[]) => void\n  removeFile: (id: string) => void\n  clearFiles: () => void\n  clearErrors: () => void\n  handleDragEnter: (e: DragEvent<HTMLElement>) => void\n  handleDragLeave: (e: DragEvent<HTMLElement>) => void\n  handleDragOver: (e: DragEvent<HTMLElement>) => void\n  handleDrop: (e: DragEvent<HTMLElement>) => void\n  handleFileChange: (e: ChangeEvent<HTMLInputElement>) => void\n  openFileDialog: () => void\n  getInputProps: (\n    props?: InputHTMLAttributes<HTMLInputElement>\n  ) => InputHTMLAttributes<HTMLInputElement> & {\n    ref: React.Ref<HTMLInputElement>\n  }\n}\n\nexport const useFileUpload = (\n  options: FileUploadOptions = {}\n): [FileUploadState, FileUploadActions] => {\n  const {\n    maxFiles = Infinity,\n    maxSize = Infinity,\n    accept = '*',\n    multiple = false,\n    initialFiles = [],\n    onFilesChange,\n    onFilesAdded,\n  } = options\n\n  const [state, setState] = useState<FileUploadState>({\n    files: initialFiles.map((file) => ({\n      file,\n      id: file.id,\n      preview: file.url,\n    })),\n    isDragging: false,\n    errors: [],\n  })\n\n  const inputRef = useRef<HTMLInputElement>(null)\n\n  const validateFile = useCallback(\n    (file: File | FileMetadata): string | null => {\n      if (file instanceof File) {\n        if (file.size > maxSize) {\n          return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n        }\n      } else {\n        if (file.size > maxSize) {\n          return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n        }\n      }\n\n      if (accept !== '*') {\n        const acceptedTypes = accept.split(',').map((type) => type.trim())\n        const fileType = file instanceof File ? file.type || '' : file.type\n        const fileExtension = `.${file instanceof File ? file.name.split('.').pop() : file.name.split('.').pop()}`\n\n        const isAccepted = acceptedTypes.some((type) => {\n          if (type.startsWith('.')) {\n            return fileExtension.toLowerCase() === type.toLowerCase()\n          }\n          if (type.endsWith('/*')) {\n            const baseType = type.split('/')[0]\n            return fileType.startsWith(`${baseType}/`)\n          }\n          return fileType === type\n        })\n\n        if (!isAccepted) {\n          return `File \"${file instanceof File ? file.name : file.name}\" is not an accepted file type.`\n        }\n      }\n\n      return null\n    },\n    [accept, maxSize]\n  )\n\n  const createPreview = useCallback((file: File | FileMetadata): string | undefined => {\n    if (file instanceof File) {\n      return URL.createObjectURL(file)\n    }\n    return file.url\n  }, [])\n\n  const generateUniqueId = useCallback((file: File | FileMetadata): string => {\n    if (file instanceof File) {\n      return `${file.name}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`\n    }\n    return file.id\n  }, [])\n\n  const clearFiles = useCallback(() => {\n    setState((prev) => {\n      // Clean up object URLs\n      prev.files.forEach((file) => {\n        if (file.preview && file.file instanceof File && file.file.type.startsWith('image/')) {\n          URL.revokeObjectURL(file.preview)\n        }\n      })\n\n      if (inputRef.current) {\n        inputRef.current.value = ''\n      }\n\n      const newState = {\n        ...prev,\n        files: [],\n        errors: [],\n      }\n\n      onFilesChange?.(newState.files)\n      return newState\n    })\n  }, [onFilesChange])\n\n  const addFiles = useCallback(\n    (newFiles: FileList | File[]) => {\n      if (!newFiles || newFiles.length === 0) return\n\n      const newFilesArray = Array.from(newFiles)\n      const errors: string[] = []\n\n      // Clear existing errors when new files are uploaded\n      setState((prev) => ({ ...prev, errors: [] }))\n\n      // In single file mode, clear existing files first\n      if (!multiple) {\n        clearFiles()\n      }\n\n      // Check if adding these files would exceed maxFiles (only in multiple mode)\n      if (\n        multiple &&\n        maxFiles !== Infinity &&\n        state.files.length + newFilesArray.length > maxFiles\n      ) {\n        errors.push(`You can only upload a maximum of ${maxFiles} files.`)\n        setState((prev) => ({ ...prev, errors }))\n        return\n      }\n\n      const validFiles: FileWithPreview[] = []\n\n      newFilesArray.forEach((file) => {\n        // Only check for duplicates if multiple files are allowed\n        if (multiple) {\n          const isDuplicate = state.files.some(\n            (existingFile) =>\n              existingFile.file.name === file.name && existingFile.file.size === file.size\n          )\n\n          // Skip duplicate files silently\n          if (isDuplicate) {\n            return\n          }\n        }\n\n        // Check file size\n        if (file.size > maxSize) {\n          errors.push(\n            multiple\n              ? `Some files exceed the maximum size of ${formatBytes(maxSize)}.`\n              : `File exceeds the maximum size of ${formatBytes(maxSize)}.`\n          )\n          return\n        }\n\n        const error = validateFile(file)\n        if (error) {\n          errors.push(error)\n        } else {\n          validFiles.push({\n            file,\n            id: generateUniqueId(file),\n            preview: createPreview(file),\n          })\n        }\n      })\n\n      // Only update state if we have valid files to add\n      if (validFiles.length > 0) {\n        // Call the onFilesAdded callback with the newly added valid files\n        onFilesAdded?.(validFiles)\n\n        setState((prev) => {\n          const newFiles = !multiple ? validFiles : [...prev.files, ...validFiles]\n          onFilesChange?.(newFiles)\n          return {\n            ...prev,\n            files: newFiles,\n            errors,\n          }\n        })\n      } else if (errors.length > 0) {\n        setState((prev) => ({\n          ...prev,\n          errors,\n        }))\n      }\n\n      // Reset input value after handling files\n      if (inputRef.current) {\n        inputRef.current.value = ''\n      }\n    },\n    [\n      state.files,\n      maxFiles,\n      multiple,\n      maxSize,\n      validateFile,\n      createPreview,\n      generateUniqueId,\n      clearFiles,\n      onFilesChange,\n      onFilesAdded,\n    ]\n  )\n\n  const removeFile = useCallback(\n    (id: string) => {\n      setState((prev) => {\n        const fileToRemove = prev.files.find((file) => file.id === id)\n        if (\n          fileToRemove &&\n          fileToRemove.preview &&\n          fileToRemove.file instanceof File &&\n          fileToRemove.file.type.startsWith('image/')\n        ) {\n          URL.revokeObjectURL(fileToRemove.preview)\n        }\n\n        const newFiles = prev.files.filter((file) => file.id !== id)\n        onFilesChange?.(newFiles)\n\n        return {\n          ...prev,\n          files: newFiles,\n          errors: [],\n        }\n      })\n    },\n    [onFilesChange]\n  )\n\n  const clearErrors = useCallback(() => {\n    setState((prev) => ({\n      ...prev,\n      errors: [],\n    }))\n  }, [])\n\n  const handleDragEnter = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n    setState((prev) => ({ ...prev, isDragging: true }))\n  }, [])\n\n  const handleDragLeave = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n\n    if (e.currentTarget.contains(e.relatedTarget as Node)) {\n      return\n    }\n\n    setState((prev) => ({ ...prev, isDragging: false }))\n  }, [])\n\n  const handleDragOver = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n  }, [])\n\n  const handleDrop = useCallback(\n    (e: DragEvent<HTMLElement>) => {\n      e.preventDefault()\n      e.stopPropagation()\n      setState((prev) => ({ ...prev, isDragging: false }))\n\n      // Don't process files if the input is disabled\n      if (inputRef.current?.disabled) {\n        return\n      }\n\n      if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n        // In single file mode, only use the first file\n        if (!multiple) {\n          const file = e.dataTransfer.files[0]\n          addFiles([file])\n        } else {\n          addFiles(e.dataTransfer.files)\n        }\n      }\n    },\n    [addFiles, multiple]\n  )\n\n  const handleFileChange = useCallback(\n    (e: ChangeEvent<HTMLInputElement>) => {\n      if (e.target.files && e.target.files.length > 0) {\n        addFiles(e.target.files)\n      }\n    },\n    [addFiles]\n  )\n\n  const openFileDialog = useCallback(() => {\n    if (inputRef.current) {\n      inputRef.current.click()\n    }\n  }, [])\n\n  const getInputProps = useCallback(\n    (props: InputHTMLAttributes<HTMLInputElement> = {}) => {\n      return {\n        ...props,\n        type: 'file' as const,\n        onChange: handleFileChange,\n        accept: props.accept || accept,\n        multiple: props.multiple !== undefined ? props.multiple : multiple,\n        ref: inputRef,\n      }\n    },\n    [accept, multiple, handleFileChange]\n  )\n\n  return [\n    state,\n    {\n      addFiles,\n      removeFile,\n      clearFiles,\n      clearErrors,\n      handleDragEnter,\n      handleDragLeave,\n      handleDragOver,\n      handleDrop,\n      handleFileChange,\n      openFileDialog,\n      getInputProps,\n    },\n  ]\n}\n\n// Helper function to format bytes to human-readable format\nexport const formatBytes = (bytes: number, decimals = 2): string => {\n  if (bytes === 0) return '0 Bytes'\n\n  const k = 1024\n  const dm = decimals < 0 ? 0 : decimals\n  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']\n\n  const i = Math.floor(Math.log(bytes) / Math.log(k))\n\n  return Number.parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + sizes[i]\n}\n"
        },
        {
          "path": "registry/default/components/file-upload/file-upload-04.vue",
          "target": "components/ui/file-upload-04.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { AlertCircleIcon, ImageUpIcon, XIcon } from 'lucide-vue-next'\nimport { Button } from '@timui/vue'\nimport { useFileUpload } from '@/registry/default/hooks/use-file-upload-vue'\n\nconst maxSizeMB = 5\nconst maxSize = maxSizeMB * 1024 * 1024\n\nconst [\n  { files, isDragging, errors },\n  {\n    handleDragEnter,\n    handleDragLeave,\n    handleDragOver,\n    handleDrop,\n    openFileDialog,\n    removeFile,\n    getInputProps,\n  },\n] = useFileUpload({\n  accept: 'image/*',\n  maxSize,\n})\n\nconst previewUrl = computed(() => files.value[0]?.preview ?? null)\n\nfunction removeCurrentFile() {\n  const fileId = files.value[0]?.id\n  if (fileId) {\n    removeFile(fileId)\n  }\n}\n</script>\n\n<template>\n  <div class=\"flex flex-col gap-2\">\n    <div class=\"relative\">\n      <div\n        role=\"button\"\n        @click=\"openFileDialog\"\n        @dragenter=\"handleDragEnter\"\n        @dragleave=\"handleDragLeave\"\n        @dragover=\"handleDragOver\"\n        @drop=\"handleDrop\"\n        :data-dragging=\"isDragging || undefined\"\n        class=\"border-input hover:bg-accent/50 data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 relative flex min-h-52 flex-col items-center justify-center overflow-hidden rounded-xl border border-dashed p-4 transition-colors has-disabled:pointer-events-none has-disabled:opacity-50 has-[img]:border-none has-[input:focus]:ring-[3px]\"\n      >\n        <input v-bind=\"getInputProps()\" class=\"sr-only\" aria-label=\"Upload file\" />\n        <template v-if=\"previewUrl\">\n          <div class=\"absolute inset-0\">\n            <img :src=\"previewUrl\" :alt=\"files[0]?.file?.name || 'Uploaded image'\" class=\"size-full object-cover\" />\n          </div>\n        </template>\n        <template v-else>\n          <div class=\"flex flex-col items-center justify-center px-4 py-3 text-center\">\n            <div\n              class=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\"\n              aria-hidden=\"true\"\n            >\n              <ImageUpIcon class=\"size-4 opacity-60\" />\n            </div>\n            <p class=\"mb-1.5 text-sm font-medium\">Drop your image here or click to browse</p>\n            <p class=\"text-muted-foreground text-xs\">Max size: {{ maxSizeMB }}MB</p>\n          </div>\n        </template>\n      </div>\n\n      <div v-if=\"previewUrl\" class=\"absolute top-4 right-4\">\n        <Button\n          size=\"icon\"\n          type=\"button\"\n          class=\"size-8 rounded-full bg-black/60 text-white shadow-none hover:bg-black/80\"\n          @click=\"removeCurrentFile\"\n          aria-label=\"Remove image\"\n        >\n          <XIcon class=\"size-4\" aria-hidden=\"true\" />\n        </Button>\n      </div>\n    </div>\n\n    <div v-if=\"errors.length > 0\" class=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\">\n      <AlertCircleIcon class=\"size-3 shrink-0\" />\n      <span>{{ errors[0] }}</span>\n    </div>\n\n    <p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-center text-xs\">\n      Single image uploader w/ max size ∙\n      <a\n        href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\"\n        class=\"hover:text-foreground underline\"\n      >\n        API\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/file-upload/file-upload-04.html",
          "target": "components/ui/file-upload-04.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex flex-col gap-2\"><div class=\"relative\"><div role=\"button\" on-click=\"${openFileDialog}\" ondragenter=\"${handleDragEnter}\" ondragleave=\"${handleDragLeave}\" ondragover=\"${handleDragOver}\" ondrop=\"${handleDrop}\" data-dragging=\"${isDragging || undefined}\" class=\"border-input hover:bg-accent/50 data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 relative flex min-h-52 flex-col items-center justify-center overflow-hidden rounded-xl border border-dashed p-4 transition-colors has-disabled:pointer-events-none has-disabled:opacity-50 has-[img]:border-none has-[input:focus]:ring-[3px]\"><input class=\"sr-only\" aria-label=\"Upload file\" /><!-- if previewUrl -->\n<div class=\"absolute inset-0\"><img src=\"${previewUrl}\" alt=\"${files[0]?.file?.name || 'Uploaded image'}\" class=\"size-full object-cover\" /></div>\n<!-- else -->\n<div class=\"flex flex-col items-center justify-center px-4 py-3 text-center\"><div class=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><ImageUpIcon class=\"size-4 opacity-60\" /></div><p class=\"mb-1.5 text-sm font-medium\">Drop your image here or click to browse</p><p class=\"text-muted-foreground text-xs\">Max size: ${maxSizeMB}MB</p></div>\n<!-- endif --></div><!-- if previewUrl -->\n<div class=\"absolute top-4 right-4\"><button type=\"button\" class=\"focus-visible:border-ring focus-visible:ring-ring/50 z-50 flex size-8 cursor-pointer items-center justify-center rounded-full bg-black/60 text-white transition-[color,box-shadow] outline-none hover:bg-black/80 focus-visible:ring-[3px]\" on-click=\"${() => removeFile(files[0]?.id)}\" aria-label=\"Remove image\"><XIcon class=\"size-4\" aria-hidden=\"true\" /></button></div>\n<!-- endif --></div><!-- if errors.length > 0 -->\n<div class=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\"><AlertCircleIcon class=\"size-3 shrink-0\" /><span>${errors[0]}</span></div>\n<!-- endif --><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-center text-xs\">Single image uploader w/ max size ∙${' '}<a href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\" class=\"hover:text-foreground underline\">API\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/file-upload/file-upload-04.wxml",
          "target": "components/ui/file-upload-04/file-upload-04.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex flex-col gap-2\"><view class=\"relative\"><view role=\"button\" bindtap=\"openFileDialog\" ondragenter=\"{{handleDragEnter}}\" ondragleave=\"{{handleDragLeave}}\" ondragover=\"{{handleDragOver}}\" ondrop=\"{{handleDrop}}\" data-dragging=\"{{isDragging || undefined}}\" class=\"border-input hover:bg-accent/50 data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 relative flex min-h-52 flex-col items-center justify-center overflow-hidden rounded-xl border border-dashed p-4 transition-colors has-disabled:pointer-events-none has-disabled:opacity-50 has-[img]:border-none has-[input:focus]:ring-[3px]\"><input class=\"sr-only\" aria-label=\"Upload file\" /><block wx:if=\"{{previewUrl}}\">\n<view class=\"absolute inset-0\"><image src=\"{{previewUrl}}\" alt=\"{{files[0]?.file?.name || 'Uploaded image'}}\" class=\"size-full object-cover\" /></view>\n</block>\n<block wx:else>\n<view class=\"flex flex-col items-center justify-center px-4 py-3 text-center\"><view class=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><imageupicon class=\"size-4 opacity-60\" /></view><text class=\"mb-1.5 text-sm font-medium\">Drop your image here or click to browse</text><text class=\"text-muted-foreground text-xs\">Max size: {{ maxSizeMB }}MB</text></view>\n</block></view><view wx:if=\"{{previewUrl}}\" class=\"absolute top-4 right-4\"><button type=\"button\" class=\"focus-visible:border-ring focus-visible:ring-ring/50 z-50 flex size-8 cursor-pointer items-center justify-center rounded-full bg-black/60 text-white transition-[color,box-shadow] outline-none hover:bg-black/80 focus-visible:ring-[3px]\" bindtap=\"removeFile(files[0]?.id)\" aria-label=\"Remove image\"><xicon class=\"size-4\" aria-hidden=\"true\" /></button></view></view><view wx:if=\"{{errors.length > 0}}\" class=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\"><alertcircleicon class=\"size-3 shrink-0\" /><text>{{ errors[0] }}</text></view><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-center text-xs\">Single image uploader w/ max size ∙{{ ' ' }}<a href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\" class=\"hover:text-foreground underline\">API\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "upload",
          "file",
          "image",
          "drag and drop"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "file-upload-04",
          "group": "file-upload",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "file-upload-04",
              "path": "registry/default/components/file-upload/file-upload-04.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "file-upload-04",
              "path": "registry/default/components/file-upload/file-upload-04.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "file-upload-04",
              "path": "registry/default/components/file-upload/file-upload-04.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "file-upload-04",
              "path": "registry/default/components/file-upload/file-upload-04.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "file-upload",
        "title": "File Upload · Upload file"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "file-upload"
      ]
    },
    {
      "name": "file-upload-05",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/file-upload/file-upload-05.tsx",
          "type": "registry:component",
          "target": "components/ui/file-upload-05.tsx",
          "content": "'use client'\n\nimport { Button } from '@timui/react'\nimport { AlertCircleIcon, ImageIcon, UploadIcon, XIcon } from 'lucide-react'\n\nimport { useFileUpload } from '@/registry/default/hooks/use-file-upload'\n\nexport default function Component() {\n  const maxSizeMB = 2\n  const maxSize = maxSizeMB * 1024 * 1024 // 2MB default\n\n  const [\n    { files, isDragging, errors },\n    {\n      handleDragEnter,\n      handleDragLeave,\n      handleDragOver,\n      handleDrop,\n      openFileDialog,\n      removeFile,\n      getInputProps,\n    },\n  ] = useFileUpload({\n    accept: 'image/svg+xml,image/png,image/jpeg,image/jpg,image/gif',\n    maxSize,\n  })\n  const previewUrl = files[0]?.preview || null\n  const fileName = files[0]?.file.name || null\n\n  return (\n    <div className=\"flex flex-col gap-2\">\n      <div className=\"relative\">\n        {/* Drop area */}\n        <div\n          onDragEnter={handleDragEnter}\n          onDragLeave={handleDragLeave}\n          onDragOver={handleDragOver}\n          onDrop={handleDrop}\n          data-dragging={isDragging || undefined}\n          className=\"border-input data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 relative flex min-h-52 flex-col items-center justify-center overflow-hidden rounded-xl border border-dashed p-4 transition-colors has-[input:focus]:ring-[3px]\"\n        >\n          <input {...getInputProps()} className=\"sr-only\" aria-label=\"Upload image file\" />\n          {previewUrl ? (\n            <div className=\"absolute inset-0 flex items-center justify-center p-4\">\n              <img\n                src={previewUrl}\n                alt={files[0]?.file?.name || 'Uploaded image'}\n                className=\"mx-auto max-h-full rounded object-contain\"\n              />\n            </div>\n          ) : (\n            <div className=\"flex flex-col items-center justify-center px-4 py-3 text-center\">\n              <div\n                className=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\"\n                aria-hidden=\"true\"\n              >\n                <ImageIcon className=\"size-4 opacity-60\" />\n              </div>\n              <p className=\"mb-1.5 text-sm font-medium\">Drop your image here</p>\n              <p className=\"text-muted-foreground text-xs\">\n                SVG, PNG, JPG or GIF (max. {maxSizeMB}MB)\n              </p>\n              <Button variant=\"outline\" className=\"mt-4\" onClick={openFileDialog}>\n                <UploadIcon className=\"-ms-1 size-4 opacity-60\" aria-hidden=\"true\" />\n                Select image\n              </Button>\n            </div>\n          )}\n        </div>\n\n        {previewUrl && (\n          <div className=\"absolute top-4 right-4\">\n            <button\n              type=\"button\"\n              className=\"focus-visible:border-ring focus-visible:ring-ring/50 z-50 flex size-8 cursor-pointer items-center justify-center rounded-full bg-black/60 text-white transition-[color,box-shadow] outline-none hover:bg-black/80 focus-visible:ring-[3px]\"\n              onClick={() => removeFile(files[0]?.id)}\n              aria-label=\"Remove image\"\n            >\n              <XIcon className=\"size-4\" aria-hidden=\"true\" />\n            </button>\n          </div>\n        )}\n      </div>\n\n      {errors.length > 0 && (\n        <div className=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\">\n          <AlertCircleIcon className=\"size-3 shrink-0\" />\n          <span>{errors[0]}</span>\n        </div>\n      )}\n\n      <p\n        aria-live=\"polite\"\n        role=\"region\"\n        className=\"text-muted-foreground mt-2 text-center text-xs\"\n      >\n        Single image uploader w/ max size (drop area + button) ∙{' '}\n        <a\n          href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\"\n          className=\"hover:text-foreground underline\"\n        >\n          API\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/hooks/use-file-upload.ts",
          "type": "registry:hook",
          "target": "components/ui/file-upload-05/use-file-upload.ts",
          "content": "'use client'\n\nimport type React from 'react'\nimport {\n  useCallback,\n  useRef,\n  useState,\n  type ChangeEvent,\n  type DragEvent,\n  type InputHTMLAttributes,\n} from 'react'\n\nexport type FileMetadata = {\n  name: string\n  size: number\n  type: string\n  url: string\n  id: string\n}\n\nexport type FileWithPreview = {\n  file: File | FileMetadata\n  id: string\n  preview?: string\n}\n\nexport type FileUploadOptions = {\n  maxFiles?: number // Only used when multiple is true, defaults to Infinity\n  maxSize?: number // in bytes\n  accept?: string\n  multiple?: boolean // Defaults to false\n  initialFiles?: FileMetadata[]\n  onFilesChange?: (files: FileWithPreview[]) => void // Callback when files change\n  onFilesAdded?: (addedFiles: FileWithPreview[]) => void // Callback when new files are added\n}\n\nexport type FileUploadState = {\n  files: FileWithPreview[]\n  isDragging: boolean\n  errors: string[]\n}\n\nexport type FileUploadActions = {\n  addFiles: (files: FileList | File[]) => void\n  removeFile: (id: string) => void\n  clearFiles: () => void\n  clearErrors: () => void\n  handleDragEnter: (e: DragEvent<HTMLElement>) => void\n  handleDragLeave: (e: DragEvent<HTMLElement>) => void\n  handleDragOver: (e: DragEvent<HTMLElement>) => void\n  handleDrop: (e: DragEvent<HTMLElement>) => void\n  handleFileChange: (e: ChangeEvent<HTMLInputElement>) => void\n  openFileDialog: () => void\n  getInputProps: (\n    props?: InputHTMLAttributes<HTMLInputElement>\n  ) => InputHTMLAttributes<HTMLInputElement> & {\n    ref: React.Ref<HTMLInputElement>\n  }\n}\n\nexport const useFileUpload = (\n  options: FileUploadOptions = {}\n): [FileUploadState, FileUploadActions] => {\n  const {\n    maxFiles = Infinity,\n    maxSize = Infinity,\n    accept = '*',\n    multiple = false,\n    initialFiles = [],\n    onFilesChange,\n    onFilesAdded,\n  } = options\n\n  const [state, setState] = useState<FileUploadState>({\n    files: initialFiles.map((file) => ({\n      file,\n      id: file.id,\n      preview: file.url,\n    })),\n    isDragging: false,\n    errors: [],\n  })\n\n  const inputRef = useRef<HTMLInputElement>(null)\n\n  const validateFile = useCallback(\n    (file: File | FileMetadata): string | null => {\n      if (file instanceof File) {\n        if (file.size > maxSize) {\n          return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n        }\n      } else {\n        if (file.size > maxSize) {\n          return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n        }\n      }\n\n      if (accept !== '*') {\n        const acceptedTypes = accept.split(',').map((type) => type.trim())\n        const fileType = file instanceof File ? file.type || '' : file.type\n        const fileExtension = `.${file instanceof File ? file.name.split('.').pop() : file.name.split('.').pop()}`\n\n        const isAccepted = acceptedTypes.some((type) => {\n          if (type.startsWith('.')) {\n            return fileExtension.toLowerCase() === type.toLowerCase()\n          }\n          if (type.endsWith('/*')) {\n            const baseType = type.split('/')[0]\n            return fileType.startsWith(`${baseType}/`)\n          }\n          return fileType === type\n        })\n\n        if (!isAccepted) {\n          return `File \"${file instanceof File ? file.name : file.name}\" is not an accepted file type.`\n        }\n      }\n\n      return null\n    },\n    [accept, maxSize]\n  )\n\n  const createPreview = useCallback((file: File | FileMetadata): string | undefined => {\n    if (file instanceof File) {\n      return URL.createObjectURL(file)\n    }\n    return file.url\n  }, [])\n\n  const generateUniqueId = useCallback((file: File | FileMetadata): string => {\n    if (file instanceof File) {\n      return `${file.name}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`\n    }\n    return file.id\n  }, [])\n\n  const clearFiles = useCallback(() => {\n    setState((prev) => {\n      // Clean up object URLs\n      prev.files.forEach((file) => {\n        if (file.preview && file.file instanceof File && file.file.type.startsWith('image/')) {\n          URL.revokeObjectURL(file.preview)\n        }\n      })\n\n      if (inputRef.current) {\n        inputRef.current.value = ''\n      }\n\n      const newState = {\n        ...prev,\n        files: [],\n        errors: [],\n      }\n\n      onFilesChange?.(newState.files)\n      return newState\n    })\n  }, [onFilesChange])\n\n  const addFiles = useCallback(\n    (newFiles: FileList | File[]) => {\n      if (!newFiles || newFiles.length === 0) return\n\n      const newFilesArray = Array.from(newFiles)\n      const errors: string[] = []\n\n      // Clear existing errors when new files are uploaded\n      setState((prev) => ({ ...prev, errors: [] }))\n\n      // In single file mode, clear existing files first\n      if (!multiple) {\n        clearFiles()\n      }\n\n      // Check if adding these files would exceed maxFiles (only in multiple mode)\n      if (\n        multiple &&\n        maxFiles !== Infinity &&\n        state.files.length + newFilesArray.length > maxFiles\n      ) {\n        errors.push(`You can only upload a maximum of ${maxFiles} files.`)\n        setState((prev) => ({ ...prev, errors }))\n        return\n      }\n\n      const validFiles: FileWithPreview[] = []\n\n      newFilesArray.forEach((file) => {\n        // Only check for duplicates if multiple files are allowed\n        if (multiple) {\n          const isDuplicate = state.files.some(\n            (existingFile) =>\n              existingFile.file.name === file.name && existingFile.file.size === file.size\n          )\n\n          // Skip duplicate files silently\n          if (isDuplicate) {\n            return\n          }\n        }\n\n        // Check file size\n        if (file.size > maxSize) {\n          errors.push(\n            multiple\n              ? `Some files exceed the maximum size of ${formatBytes(maxSize)}.`\n              : `File exceeds the maximum size of ${formatBytes(maxSize)}.`\n          )\n          return\n        }\n\n        const error = validateFile(file)\n        if (error) {\n          errors.push(error)\n        } else {\n          validFiles.push({\n            file,\n            id: generateUniqueId(file),\n            preview: createPreview(file),\n          })\n        }\n      })\n\n      // Only update state if we have valid files to add\n      if (validFiles.length > 0) {\n        // Call the onFilesAdded callback with the newly added valid files\n        onFilesAdded?.(validFiles)\n\n        setState((prev) => {\n          const newFiles = !multiple ? validFiles : [...prev.files, ...validFiles]\n          onFilesChange?.(newFiles)\n          return {\n            ...prev,\n            files: newFiles,\n            errors,\n          }\n        })\n      } else if (errors.length > 0) {\n        setState((prev) => ({\n          ...prev,\n          errors,\n        }))\n      }\n\n      // Reset input value after handling files\n      if (inputRef.current) {\n        inputRef.current.value = ''\n      }\n    },\n    [\n      state.files,\n      maxFiles,\n      multiple,\n      maxSize,\n      validateFile,\n      createPreview,\n      generateUniqueId,\n      clearFiles,\n      onFilesChange,\n      onFilesAdded,\n    ]\n  )\n\n  const removeFile = useCallback(\n    (id: string) => {\n      setState((prev) => {\n        const fileToRemove = prev.files.find((file) => file.id === id)\n        if (\n          fileToRemove &&\n          fileToRemove.preview &&\n          fileToRemove.file instanceof File &&\n          fileToRemove.file.type.startsWith('image/')\n        ) {\n          URL.revokeObjectURL(fileToRemove.preview)\n        }\n\n        const newFiles = prev.files.filter((file) => file.id !== id)\n        onFilesChange?.(newFiles)\n\n        return {\n          ...prev,\n          files: newFiles,\n          errors: [],\n        }\n      })\n    },\n    [onFilesChange]\n  )\n\n  const clearErrors = useCallback(() => {\n    setState((prev) => ({\n      ...prev,\n      errors: [],\n    }))\n  }, [])\n\n  const handleDragEnter = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n    setState((prev) => ({ ...prev, isDragging: true }))\n  }, [])\n\n  const handleDragLeave = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n\n    if (e.currentTarget.contains(e.relatedTarget as Node)) {\n      return\n    }\n\n    setState((prev) => ({ ...prev, isDragging: false }))\n  }, [])\n\n  const handleDragOver = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n  }, [])\n\n  const handleDrop = useCallback(\n    (e: DragEvent<HTMLElement>) => {\n      e.preventDefault()\n      e.stopPropagation()\n      setState((prev) => ({ ...prev, isDragging: false }))\n\n      // Don't process files if the input is disabled\n      if (inputRef.current?.disabled) {\n        return\n      }\n\n      if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n        // In single file mode, only use the first file\n        if (!multiple) {\n          const file = e.dataTransfer.files[0]\n          addFiles([file])\n        } else {\n          addFiles(e.dataTransfer.files)\n        }\n      }\n    },\n    [addFiles, multiple]\n  )\n\n  const handleFileChange = useCallback(\n    (e: ChangeEvent<HTMLInputElement>) => {\n      if (e.target.files && e.target.files.length > 0) {\n        addFiles(e.target.files)\n      }\n    },\n    [addFiles]\n  )\n\n  const openFileDialog = useCallback(() => {\n    if (inputRef.current) {\n      inputRef.current.click()\n    }\n  }, [])\n\n  const getInputProps = useCallback(\n    (props: InputHTMLAttributes<HTMLInputElement> = {}) => {\n      return {\n        ...props,\n        type: 'file' as const,\n        onChange: handleFileChange,\n        accept: props.accept || accept,\n        multiple: props.multiple !== undefined ? props.multiple : multiple,\n        ref: inputRef,\n      }\n    },\n    [accept, multiple, handleFileChange]\n  )\n\n  return [\n    state,\n    {\n      addFiles,\n      removeFile,\n      clearFiles,\n      clearErrors,\n      handleDragEnter,\n      handleDragLeave,\n      handleDragOver,\n      handleDrop,\n      handleFileChange,\n      openFileDialog,\n      getInputProps,\n    },\n  ]\n}\n\n// Helper function to format bytes to human-readable format\nexport const formatBytes = (bytes: number, decimals = 2): string => {\n  if (bytes === 0) return '0 Bytes'\n\n  const k = 1024\n  const dm = decimals < 0 ? 0 : decimals\n  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']\n\n  const i = Math.floor(Math.log(bytes) / Math.log(k))\n\n  return Number.parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + sizes[i]\n}\n"
        },
        {
          "path": "registry/default/components/file-upload/file-upload-05.vue",
          "target": "components/ui/file-upload-05.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { AlertCircleIcon, ImageIcon, UploadIcon, XIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { useFileUpload } from '@/registry/default/hooks/use-file-upload-vue';\n\nconst maxSizeMB = 2;\nconst maxSize = maxSizeMB * 1024 * 1024;\n\nconst [\n  { files, isDragging, errors },\n  {\n    handleDragEnter,\n    handleDragLeave,\n    handleDragOver,\n    handleDrop,\n    openFileDialog,\n    removeFile,\n    getInputProps,\n  },\n] = useFileUpload({\n  accept: 'image/svg+xml,image/png,image/jpeg,image/jpg,image/gif',\n  maxSize,\n});\n\nconst previewUrl = computed(() => files.value[0]?.preview ?? null);\n\nfunction removeCurrentFile() {\n  const fileId = files.value[0]?.id;\n  if (fileId) {\n    removeFile(fileId);\n  }\n}\n</script>\n\n<template>\n  <div class=\"flex flex-col gap-2\">\n    <div class=\"relative\">\n      <div\n        @dragenter=\"handleDragEnter\"\n        @dragleave=\"handleDragLeave\"\n        @dragover=\"handleDragOver\"\n        @drop=\"handleDrop\"\n        :data-dragging=\"isDragging || undefined\"\n        class=\"border-input data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 relative flex min-h-52 flex-col items-center justify-center overflow-hidden rounded-xl border border-dashed p-4 transition-colors has-[input:focus]:ring-[3px]\"\n      >\n        <input v-bind=\"getInputProps()\" class=\"sr-only\" aria-label=\"Upload image file\" />\n        <template v-if=\"previewUrl\">\n          <div class=\"absolute inset-0 flex items-center justify-center p-4\">\n            <img\n              :src=\"previewUrl\"\n              :alt=\"files[0]?.file?.name || 'Uploaded image'\"\n              class=\"mx-auto max-h-full rounded object-contain\"\n            />\n          </div>\n        </template>\n        <template v-else>\n          <div class=\"flex flex-col items-center justify-center px-4 py-3 text-center\">\n            <div class=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\">\n              <ImageIcon class=\"size-4 opacity-60\" />\n            </div>\n            <p class=\"mb-1.5 text-sm font-medium\">Drop your image here</p>\n            <p class=\"text-muted-foreground text-xs\">SVG, PNG, JPG or GIF (max. {{ maxSizeMB }}MB)</p>\n            <Button variant=\"outline\" class=\"mt-4\" @click=\"openFileDialog\">\n              <UploadIcon class=\"-ms-1 size-4 opacity-60\" aria-hidden=\"true\" />\n              Select image\n            </Button>\n          </div>\n        </template>\n      </div>\n\n      <div v-if=\"previewUrl\" class=\"absolute top-4 right-4\">\n        <button\n          type=\"button\"\n          class=\"focus-visible:border-ring focus-visible:ring-ring/50 z-50 flex size-8 cursor-pointer items-center justify-center rounded-full bg-black/60 text-white transition-[color,box-shadow] outline-none hover:bg-black/80 focus-visible:ring-[3px]\"\n          @click=\"removeCurrentFile\"\n          aria-label=\"Remove image\"\n        >\n          <XIcon class=\"size-4\" aria-hidden=\"true\" />\n        </button>\n      </div>\n    </div>\n\n    <div v-if=\"errors.length > 0\" class=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\">\n      <AlertCircleIcon class=\"size-3 shrink-0\" />\n      <span>{{ errors[0] }}</span>\n    </div>\n\n    <p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-center text-xs\">\n      Single image uploader w/ max size (drop area + button) ∙\n      <a\n        href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\"\n        class=\"hover:text-foreground underline\"\n      >\n        API\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/file-upload/file-upload-05.html",
          "target": "components/ui/file-upload-05.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex flex-col gap-2\"><div class=\"relative\"><div ondragenter=\"${handleDragEnter}\" ondragleave=\"${handleDragLeave}\" ondragover=\"${handleDragOver}\" ondrop=\"${handleDrop}\" data-dragging=\"${isDragging || undefined}\" class=\"border-input data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 relative flex min-h-52 flex-col items-center justify-center overflow-hidden rounded-xl border border-dashed p-4 transition-colors has-[input:focus]:ring-[3px]\"><input class=\"sr-only\" aria-label=\"Upload image file\" /><!-- if previewUrl -->\n<div class=\"absolute inset-0 flex items-center justify-center p-4\"><img src=\"${previewUrl}\" alt=\"${files[0]?.file?.name || 'Uploaded image'}\" class=\"mx-auto max-h-full rounded object-contain\" /></div>\n<!-- else -->\n<div class=\"flex flex-col items-center justify-center px-4 py-3 text-center\"><div class=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><ImageIcon class=\"size-4 opacity-60\" /></div><p class=\"mb-1.5 text-sm font-medium\">Drop your image here</p><p class=\"text-muted-foreground text-xs\">SVG, PNG, JPG or GIF (max. ${maxSizeMB}MB)\n              </p><Button variant=\"outline\" class=\"mt-4\" on-click=\"${openFileDialog}\"><UploadIcon class=\"-ms-1 size-4 opacity-60\" aria-hidden=\"true\" />Select image\n              </Button></div>\n<!-- endif --></div><!-- if previewUrl -->\n<div class=\"absolute top-4 right-4\"><button type=\"button\" class=\"focus-visible:border-ring focus-visible:ring-ring/50 z-50 flex size-8 cursor-pointer items-center justify-center rounded-full bg-black/60 text-white transition-[color,box-shadow] outline-none hover:bg-black/80 focus-visible:ring-[3px]\" on-click=\"${() => removeFile(files[0]?.id)}\" aria-label=\"Remove image\"><XIcon class=\"size-4\" aria-hidden=\"true\" /></button></div>\n<!-- endif --></div><!-- if errors.length > 0 -->\n<div class=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\"><AlertCircleIcon class=\"size-3 shrink-0\" /><span>${errors[0]}</span></div>\n<!-- endif --><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-center text-xs\">Single image uploader w/ max size (drop area + button) ∙${' '}<a href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\" class=\"hover:text-foreground underline\">API\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/file-upload/file-upload-05.wxml",
          "target": "components/ui/file-upload-05/file-upload-05.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex flex-col gap-2\"><view class=\"relative\"><view ondragenter=\"{{handleDragEnter}}\" ondragleave=\"{{handleDragLeave}}\" ondragover=\"{{handleDragOver}}\" ondrop=\"{{handleDrop}}\" data-dragging=\"{{isDragging || undefined}}\" class=\"border-input data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 relative flex min-h-52 flex-col items-center justify-center overflow-hidden rounded-xl border border-dashed p-4 transition-colors has-[input:focus]:ring-[3px]\"><input class=\"sr-only\" aria-label=\"Upload image file\" /><block wx:if=\"{{previewUrl}}\">\n<view class=\"absolute inset-0 flex items-center justify-center p-4\"><image src=\"{{previewUrl}}\" alt=\"{{files[0]?.file?.name || 'Uploaded image'}}\" class=\"mx-auto max-h-full rounded object-contain\" /></view>\n</block>\n<block wx:else>\n<view class=\"flex flex-col items-center justify-center px-4 py-3 text-center\"><view class=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><imageicon class=\"size-4 opacity-60\" /></view><text class=\"mb-1.5 text-sm font-medium\">Drop your image here</text><text class=\"text-muted-foreground text-xs\">SVG, PNG, JPG or GIF (max. {{ maxSizeMB }}MB)\n              </text><button variant=\"outline\" class=\"mt-4\" bindtap=\"openFileDialog\"><uploadicon class=\"-ms-1 size-4 opacity-60\" aria-hidden=\"true\" />Select image\n              </button></view>\n</block></view><view wx:if=\"{{previewUrl}}\" class=\"absolute top-4 right-4\"><button type=\"button\" class=\"focus-visible:border-ring focus-visible:ring-ring/50 z-50 flex size-8 cursor-pointer items-center justify-center rounded-full bg-black/60 text-white transition-[color,box-shadow] outline-none hover:bg-black/80 focus-visible:ring-[3px]\" bindtap=\"removeFile(files[0]?.id)\" aria-label=\"Remove image\"><xicon class=\"size-4\" aria-hidden=\"true\" /></button></view></view><view wx:if=\"{{errors.length > 0}}\" class=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\"><alertcircleicon class=\"size-3 shrink-0\" /><text>{{ errors[0] }}</text></view><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-center text-xs\">Single image uploader w/ max size (drop area + button) ∙{{ ' ' }}<a href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\" class=\"hover:text-foreground underline\">API\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "upload",
          "file",
          "image",
          "drag and drop"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "file-upload-05",
          "group": "file-upload",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "file-upload-05",
              "path": "registry/default/components/file-upload/file-upload-05.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "file-upload-05",
              "path": "registry/default/components/file-upload/file-upload-05.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "file-upload-05",
              "path": "registry/default/components/file-upload/file-upload-05.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "file-upload-05",
              "path": "registry/default/components/file-upload/file-upload-05.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "file-upload",
        "title": "File Upload · Upload image file"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "file-upload"
      ]
    },
    {
      "name": "file-upload-06",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/file-upload/file-upload-06.tsx",
          "type": "registry:component",
          "target": "components/ui/file-upload-06.tsx",
          "content": "'use client'\n\nimport { Button } from '@timui/react'\nimport { AlertCircleIcon, ImageIcon, UploadIcon, XIcon } from 'lucide-react'\n\nimport { useFileUpload } from '@/registry/default/hooks/use-file-upload'\n\n// Create some dummy initial files\nconst initialFiles = [\n  {\n    name: 'image-01.jpg',\n    size: 1528737,\n    type: 'image/jpeg',\n    url: 'https://picsum.photos/1000/800?grayscale&random=1',\n    id: 'image-01-123456789',\n  },\n  {\n    name: 'image-02.jpg',\n    size: 1528737,\n    type: 'image/jpeg',\n    url: 'https://picsum.photos/1000/800?grayscale&random=2',\n    id: 'image-02-123456789',\n  },\n  {\n    name: 'image-03.jpg',\n    size: 1528737,\n    type: 'image/jpeg',\n    url: 'https://picsum.photos/1000/800?grayscale&random=3',\n    id: 'image-03-123456789',\n  },\n  {\n    name: 'image-04.jpg',\n    size: 1528737,\n    type: 'image/jpeg',\n    url: 'https://picsum.photos/1000/800?grayscale&random=4',\n    id: 'image-04-123456789',\n  },\n]\n\nexport default function Component() {\n  const maxSizeMB = 5\n  const maxSize = maxSizeMB * 1024 * 1024 // 5MB default\n  const maxFiles = 6\n\n  const [\n    { files, isDragging, errors },\n    {\n      handleDragEnter,\n      handleDragLeave,\n      handleDragOver,\n      handleDrop,\n      openFileDialog,\n      removeFile,\n      getInputProps,\n    },\n  ] = useFileUpload({\n    accept: 'image/svg+xml,image/png,image/jpeg,image/jpg,image/gif',\n    maxSize,\n    multiple: true,\n    maxFiles,\n    initialFiles,\n  })\n\n  return (\n    <div className=\"flex flex-col gap-2\">\n      {/* Drop area */}\n      <div\n        onDragEnter={handleDragEnter}\n        onDragLeave={handleDragLeave}\n        onDragOver={handleDragOver}\n        onDrop={handleDrop}\n        data-dragging={isDragging || undefined}\n        data-files={files.length > 0 || undefined}\n        className=\"border-input data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 relative flex min-h-52 flex-col items-center overflow-hidden rounded-xl border border-dashed p-4 transition-colors not-data-[files]:justify-center has-[input:focus]:ring-[3px]\"\n      >\n        <input {...getInputProps()} className=\"sr-only\" aria-label=\"Upload image file\" />\n        {files.length > 0 ? (\n          <div className=\"flex w-full flex-col gap-3\">\n            <div className=\"flex items-center justify-between gap-2\">\n              <h3 className=\"truncate text-sm font-medium\">Uploaded Files ({files.length})</h3>\n              <Button\n                variant=\"outline\"\n                size=\"sm\"\n                onClick={openFileDialog}\n                disabled={files.length >= maxFiles}\n              >\n                <UploadIcon className=\"-ms-0.5 size-3.5 opacity-60\" aria-hidden=\"true\" />\n                Add more\n              </Button>\n            </div>\n\n            <div className=\"grid grid-cols-2 gap-4 md:grid-cols-3\">\n              {files.map((file) => (\n                <div key={file.id} className=\"bg-accent relative aspect-square rounded-md\">\n                  <img\n                    src={file.preview}\n                    alt={file.file.name}\n                    className=\"size-full rounded-[inherit] object-cover\"\n                  />\n                  <Button\n                    onClick={() => removeFile(file.id)}\n                    size=\"icon\"\n                    className=\"border-background focus-visible:border-background absolute -top-2 -right-2 size-6 rounded-full border-2 shadow-none\"\n                    aria-label=\"Remove image\"\n                  >\n                    <XIcon className=\"size-3.5\" />\n                  </Button>\n                </div>\n              ))}\n            </div>\n          </div>\n        ) : (\n          <div className=\"flex flex-col items-center justify-center px-4 py-3 text-center\">\n            <div\n              className=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\"\n              aria-hidden=\"true\"\n            >\n              <ImageIcon className=\"size-4 opacity-60\" />\n            </div>\n            <p className=\"mb-1.5 text-sm font-medium\">Drop your images here</p>\n            <p className=\"text-muted-foreground text-xs\">\n              SVG, PNG, JPG or GIF (max. {maxSizeMB}MB)\n            </p>\n            <Button variant=\"outline\" className=\"mt-4\" onClick={openFileDialog}>\n              <UploadIcon className=\"-ms-1 opacity-60\" aria-hidden=\"true\" />\n              Select images\n            </Button>\n          </div>\n        )}\n      </div>\n\n      {errors.length > 0 && (\n        <div className=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\">\n          <AlertCircleIcon className=\"size-3 shrink-0\" />\n          <span>{errors[0]}</span>\n        </div>\n      )}\n\n      <p\n        aria-live=\"polite\"\n        role=\"region\"\n        className=\"text-muted-foreground mt-2 text-center text-xs\"\n      >\n        Multiple image uploader w/ image grid ∙{' '}\n        <a\n          href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\"\n          className=\"hover:text-foreground underline\"\n        >\n          API\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/hooks/use-file-upload.ts",
          "type": "registry:hook",
          "target": "components/ui/file-upload-06/use-file-upload.ts",
          "content": "'use client'\n\nimport type React from 'react'\nimport {\n  useCallback,\n  useRef,\n  useState,\n  type ChangeEvent,\n  type DragEvent,\n  type InputHTMLAttributes,\n} from 'react'\n\nexport type FileMetadata = {\n  name: string\n  size: number\n  type: string\n  url: string\n  id: string\n}\n\nexport type FileWithPreview = {\n  file: File | FileMetadata\n  id: string\n  preview?: string\n}\n\nexport type FileUploadOptions = {\n  maxFiles?: number // Only used when multiple is true, defaults to Infinity\n  maxSize?: number // in bytes\n  accept?: string\n  multiple?: boolean // Defaults to false\n  initialFiles?: FileMetadata[]\n  onFilesChange?: (files: FileWithPreview[]) => void // Callback when files change\n  onFilesAdded?: (addedFiles: FileWithPreview[]) => void // Callback when new files are added\n}\n\nexport type FileUploadState = {\n  files: FileWithPreview[]\n  isDragging: boolean\n  errors: string[]\n}\n\nexport type FileUploadActions = {\n  addFiles: (files: FileList | File[]) => void\n  removeFile: (id: string) => void\n  clearFiles: () => void\n  clearErrors: () => void\n  handleDragEnter: (e: DragEvent<HTMLElement>) => void\n  handleDragLeave: (e: DragEvent<HTMLElement>) => void\n  handleDragOver: (e: DragEvent<HTMLElement>) => void\n  handleDrop: (e: DragEvent<HTMLElement>) => void\n  handleFileChange: (e: ChangeEvent<HTMLInputElement>) => void\n  openFileDialog: () => void\n  getInputProps: (\n    props?: InputHTMLAttributes<HTMLInputElement>\n  ) => InputHTMLAttributes<HTMLInputElement> & {\n    ref: React.Ref<HTMLInputElement>\n  }\n}\n\nexport const useFileUpload = (\n  options: FileUploadOptions = {}\n): [FileUploadState, FileUploadActions] => {\n  const {\n    maxFiles = Infinity,\n    maxSize = Infinity,\n    accept = '*',\n    multiple = false,\n    initialFiles = [],\n    onFilesChange,\n    onFilesAdded,\n  } = options\n\n  const [state, setState] = useState<FileUploadState>({\n    files: initialFiles.map((file) => ({\n      file,\n      id: file.id,\n      preview: file.url,\n    })),\n    isDragging: false,\n    errors: [],\n  })\n\n  const inputRef = useRef<HTMLInputElement>(null)\n\n  const validateFile = useCallback(\n    (file: File | FileMetadata): string | null => {\n      if (file instanceof File) {\n        if (file.size > maxSize) {\n          return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n        }\n      } else {\n        if (file.size > maxSize) {\n          return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n        }\n      }\n\n      if (accept !== '*') {\n        const acceptedTypes = accept.split(',').map((type) => type.trim())\n        const fileType = file instanceof File ? file.type || '' : file.type\n        const fileExtension = `.${file instanceof File ? file.name.split('.').pop() : file.name.split('.').pop()}`\n\n        const isAccepted = acceptedTypes.some((type) => {\n          if (type.startsWith('.')) {\n            return fileExtension.toLowerCase() === type.toLowerCase()\n          }\n          if (type.endsWith('/*')) {\n            const baseType = type.split('/')[0]\n            return fileType.startsWith(`${baseType}/`)\n          }\n          return fileType === type\n        })\n\n        if (!isAccepted) {\n          return `File \"${file instanceof File ? file.name : file.name}\" is not an accepted file type.`\n        }\n      }\n\n      return null\n    },\n    [accept, maxSize]\n  )\n\n  const createPreview = useCallback((file: File | FileMetadata): string | undefined => {\n    if (file instanceof File) {\n      return URL.createObjectURL(file)\n    }\n    return file.url\n  }, [])\n\n  const generateUniqueId = useCallback((file: File | FileMetadata): string => {\n    if (file instanceof File) {\n      return `${file.name}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`\n    }\n    return file.id\n  }, [])\n\n  const clearFiles = useCallback(() => {\n    setState((prev) => {\n      // Clean up object URLs\n      prev.files.forEach((file) => {\n        if (file.preview && file.file instanceof File && file.file.type.startsWith('image/')) {\n          URL.revokeObjectURL(file.preview)\n        }\n      })\n\n      if (inputRef.current) {\n        inputRef.current.value = ''\n      }\n\n      const newState = {\n        ...prev,\n        files: [],\n        errors: [],\n      }\n\n      onFilesChange?.(newState.files)\n      return newState\n    })\n  }, [onFilesChange])\n\n  const addFiles = useCallback(\n    (newFiles: FileList | File[]) => {\n      if (!newFiles || newFiles.length === 0) return\n\n      const newFilesArray = Array.from(newFiles)\n      const errors: string[] = []\n\n      // Clear existing errors when new files are uploaded\n      setState((prev) => ({ ...prev, errors: [] }))\n\n      // In single file mode, clear existing files first\n      if (!multiple) {\n        clearFiles()\n      }\n\n      // Check if adding these files would exceed maxFiles (only in multiple mode)\n      if (\n        multiple &&\n        maxFiles !== Infinity &&\n        state.files.length + newFilesArray.length > maxFiles\n      ) {\n        errors.push(`You can only upload a maximum of ${maxFiles} files.`)\n        setState((prev) => ({ ...prev, errors }))\n        return\n      }\n\n      const validFiles: FileWithPreview[] = []\n\n      newFilesArray.forEach((file) => {\n        // Only check for duplicates if multiple files are allowed\n        if (multiple) {\n          const isDuplicate = state.files.some(\n            (existingFile) =>\n              existingFile.file.name === file.name && existingFile.file.size === file.size\n          )\n\n          // Skip duplicate files silently\n          if (isDuplicate) {\n            return\n          }\n        }\n\n        // Check file size\n        if (file.size > maxSize) {\n          errors.push(\n            multiple\n              ? `Some files exceed the maximum size of ${formatBytes(maxSize)}.`\n              : `File exceeds the maximum size of ${formatBytes(maxSize)}.`\n          )\n          return\n        }\n\n        const error = validateFile(file)\n        if (error) {\n          errors.push(error)\n        } else {\n          validFiles.push({\n            file,\n            id: generateUniqueId(file),\n            preview: createPreview(file),\n          })\n        }\n      })\n\n      // Only update state if we have valid files to add\n      if (validFiles.length > 0) {\n        // Call the onFilesAdded callback with the newly added valid files\n        onFilesAdded?.(validFiles)\n\n        setState((prev) => {\n          const newFiles = !multiple ? validFiles : [...prev.files, ...validFiles]\n          onFilesChange?.(newFiles)\n          return {\n            ...prev,\n            files: newFiles,\n            errors,\n          }\n        })\n      } else if (errors.length > 0) {\n        setState((prev) => ({\n          ...prev,\n          errors,\n        }))\n      }\n\n      // Reset input value after handling files\n      if (inputRef.current) {\n        inputRef.current.value = ''\n      }\n    },\n    [\n      state.files,\n      maxFiles,\n      multiple,\n      maxSize,\n      validateFile,\n      createPreview,\n      generateUniqueId,\n      clearFiles,\n      onFilesChange,\n      onFilesAdded,\n    ]\n  )\n\n  const removeFile = useCallback(\n    (id: string) => {\n      setState((prev) => {\n        const fileToRemove = prev.files.find((file) => file.id === id)\n        if (\n          fileToRemove &&\n          fileToRemove.preview &&\n          fileToRemove.file instanceof File &&\n          fileToRemove.file.type.startsWith('image/')\n        ) {\n          URL.revokeObjectURL(fileToRemove.preview)\n        }\n\n        const newFiles = prev.files.filter((file) => file.id !== id)\n        onFilesChange?.(newFiles)\n\n        return {\n          ...prev,\n          files: newFiles,\n          errors: [],\n        }\n      })\n    },\n    [onFilesChange]\n  )\n\n  const clearErrors = useCallback(() => {\n    setState((prev) => ({\n      ...prev,\n      errors: [],\n    }))\n  }, [])\n\n  const handleDragEnter = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n    setState((prev) => ({ ...prev, isDragging: true }))\n  }, [])\n\n  const handleDragLeave = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n\n    if (e.currentTarget.contains(e.relatedTarget as Node)) {\n      return\n    }\n\n    setState((prev) => ({ ...prev, isDragging: false }))\n  }, [])\n\n  const handleDragOver = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n  }, [])\n\n  const handleDrop = useCallback(\n    (e: DragEvent<HTMLElement>) => {\n      e.preventDefault()\n      e.stopPropagation()\n      setState((prev) => ({ ...prev, isDragging: false }))\n\n      // Don't process files if the input is disabled\n      if (inputRef.current?.disabled) {\n        return\n      }\n\n      if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n        // In single file mode, only use the first file\n        if (!multiple) {\n          const file = e.dataTransfer.files[0]\n          addFiles([file])\n        } else {\n          addFiles(e.dataTransfer.files)\n        }\n      }\n    },\n    [addFiles, multiple]\n  )\n\n  const handleFileChange = useCallback(\n    (e: ChangeEvent<HTMLInputElement>) => {\n      if (e.target.files && e.target.files.length > 0) {\n        addFiles(e.target.files)\n      }\n    },\n    [addFiles]\n  )\n\n  const openFileDialog = useCallback(() => {\n    if (inputRef.current) {\n      inputRef.current.click()\n    }\n  }, [])\n\n  const getInputProps = useCallback(\n    (props: InputHTMLAttributes<HTMLInputElement> = {}) => {\n      return {\n        ...props,\n        type: 'file' as const,\n        onChange: handleFileChange,\n        accept: props.accept || accept,\n        multiple: props.multiple !== undefined ? props.multiple : multiple,\n        ref: inputRef,\n      }\n    },\n    [accept, multiple, handleFileChange]\n  )\n\n  return [\n    state,\n    {\n      addFiles,\n      removeFile,\n      clearFiles,\n      clearErrors,\n      handleDragEnter,\n      handleDragLeave,\n      handleDragOver,\n      handleDrop,\n      handleFileChange,\n      openFileDialog,\n      getInputProps,\n    },\n  ]\n}\n\n// Helper function to format bytes to human-readable format\nexport const formatBytes = (bytes: number, decimals = 2): string => {\n  if (bytes === 0) return '0 Bytes'\n\n  const k = 1024\n  const dm = decimals < 0 ? 0 : decimals\n  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']\n\n  const i = Math.floor(Math.log(bytes) / Math.log(k))\n\n  return Number.parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + sizes[i]\n}\n"
        },
        {
          "path": "registry/default/components/file-upload/file-upload-06.vue",
          "target": "components/ui/file-upload-06.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { AlertCircleIcon, ImageIcon, UploadIcon, XIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { useFileUpload } from '@/registry/default/hooks/use-file-upload-vue';\n\nconst initialFiles = [\n  {\n    name: 'image-01.jpg',\n    size: 1528737,\n    type: 'image/jpeg',\n    url: 'https://picsum.photos/1000/800?grayscale&random=1',\n    id: 'image-01-123456789',\n  },\n  {\n    name: 'image-02.jpg',\n    size: 1528737,\n    type: 'image/jpeg',\n    url: 'https://picsum.photos/1000/800?grayscale&random=2',\n    id: 'image-02-123456789',\n  },\n  {\n    name: 'image-03.jpg',\n    size: 1528737,\n    type: 'image/jpeg',\n    url: 'https://picsum.photos/1000/800?grayscale&random=3',\n    id: 'image-03-123456789',\n  },\n  {\n    name: 'image-04.jpg',\n    size: 1528737,\n    type: 'image/jpeg',\n    url: 'https://picsum.photos/1000/800?grayscale&random=4',\n    id: 'image-04-123456789',\n  },\n];\n\nconst maxSizeMB = 5;\nconst maxSize = maxSizeMB * 1024 * 1024;\nconst maxFiles = 6;\n\nconst [\n  { files, isDragging, errors },\n  {\n    handleDragEnter,\n    handleDragLeave,\n    handleDragOver,\n    handleDrop,\n    openFileDialog,\n    removeFile,\n  },\n] = useFileUpload({\n  accept: 'image/svg+xml,image/png,image/jpeg,image/jpg,image/gif',\n  maxSize,\n  multiple: true,\n  maxFiles,\n  initialFiles,\n});\n</script>\n\n<template>\n  <div class=\"flex flex-col gap-2\"><div @dragenter=\"handleDragEnter\" @dragleave=\"handleDragLeave\" @dragover=\"handleDragOver\" @drop=\"handleDrop\" :data-dragging=\"isDragging || undefined\" :data-files=\"files.length > 0 || undefined\" class=\"border-input data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 relative flex min-h-52 flex-col items-center overflow-hidden rounded-xl border border-dashed p-4 transition-colors not-data-[files]:justify-center has-[input:focus]:ring-[3px]\"><input class=\"sr-only\" aria-label=\"Upload image file\" /><template v-if=\"files.length > 0\">\n<div class=\"flex w-full flex-col gap-3\"><div class=\"flex items-center justify-between gap-2\"><h3 class=\"truncate text-sm font-medium\">Uploaded Files ({{ files.length }})</h3><Button variant=\"outline\" size=\"sm\" @click=\"openFileDialog\" :disabled=\"files.length >= maxFiles\"><UploadIcon class=\"-ms-0.5 size-3.5 opacity-60\" aria-hidden=\"true\" />Add more\n              </Button></div><div class=\"grid grid-cols-2 gap-4 md:grid-cols-3\"><div v-for=\"(file, index) in files\" :key=\"file.id\" class=\"bg-accent relative aspect-square rounded-md\"><img :src=\"file.preview\" :alt=\"file.file.name\" class=\"size-full rounded-[inherit] object-cover\" /><Button @click=\"removeFile(file.id)\" size=\"icon\" class=\"border-background focus-visible:border-background absolute -top-2 -right-2 size-6 rounded-full border-2 shadow-none\" aria-label=\"Remove image\"><XIcon class=\"size-3.5\" /></Button></div></div></div>\n</template>\n<template v-else>\n<div class=\"flex flex-col items-center justify-center px-4 py-3 text-center\"><div class=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><ImageIcon class=\"size-4 opacity-60\" /></div><p class=\"mb-1.5 text-sm font-medium\">Drop your images here</p><p class=\"text-muted-foreground text-xs\">SVG, PNG, JPG or GIF (max. {{ maxSizeMB }}MB)\n            </p><Button variant=\"outline\" class=\"mt-4\" @click=\"openFileDialog\"><UploadIcon class=\"-ms-1 opacity-60\" aria-hidden=\"true\" />Select images\n            </Button></div>\n</template></div><div v-if=\"errors.length > 0\" class=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\"><AlertCircleIcon class=\"size-3 shrink-0\" /><span>{{ errors[0] }}</span></div><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-center text-xs\">Multiple image uploader w/ image grid ∙{{ ' ' }}<a href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\" class=\"hover:text-foreground underline\">API\n        </a></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/file-upload/file-upload-06.html",
          "target": "components/ui/file-upload-06.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex flex-col gap-2\"><div ondragenter=\"${handleDragEnter}\" ondragleave=\"${handleDragLeave}\" ondragover=\"${handleDragOver}\" ondrop=\"${handleDrop}\" data-dragging=\"${isDragging || undefined}\" data-files=\"${files.length > 0 || undefined}\" class=\"border-input data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 relative flex min-h-52 flex-col items-center overflow-hidden rounded-xl border border-dashed p-4 transition-colors not-data-[files]:justify-center has-[input:focus]:ring-[3px]\"><input class=\"sr-only\" aria-label=\"Upload image file\" /><!-- if files.length > 0 -->\n<div class=\"flex w-full flex-col gap-3\"><div class=\"flex items-center justify-between gap-2\"><h3 class=\"truncate text-sm font-medium\">Uploaded Files (${files.length})</h3><Button variant=\"outline\" size=\"sm\" on-click=\"${openFileDialog}\" disabled=\"${files.length >= maxFiles}\"><UploadIcon class=\"-ms-0.5 size-3.5 opacity-60\" aria-hidden=\"true\" />Add more\n              </Button></div><div class=\"grid grid-cols-2 gap-4 md:grid-cols-3\"><!-- Loop files -->\n<div key=\"${file.id}\" class=\"bg-accent relative aspect-square rounded-md\"><img src=\"${file.preview}\" alt=\"${file.file.name}\" class=\"size-full rounded-[inherit] object-cover\" /><Button on-click=\"${() => removeFile(file.id)}\" size=\"icon\" class=\"border-background focus-visible:border-background absolute -top-2 -right-2 size-6 rounded-full border-2 shadow-none\" aria-label=\"Remove image\"><XIcon class=\"size-3.5\" /></Button></div>\n<!-- End Loop --></div></div>\n<!-- else -->\n<div class=\"flex flex-col items-center justify-center px-4 py-3 text-center\"><div class=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><ImageIcon class=\"size-4 opacity-60\" /></div><p class=\"mb-1.5 text-sm font-medium\">Drop your images here</p><p class=\"text-muted-foreground text-xs\">SVG, PNG, JPG or GIF (max. ${maxSizeMB}MB)\n            </p><Button variant=\"outline\" class=\"mt-4\" on-click=\"${openFileDialog}\"><UploadIcon class=\"-ms-1 opacity-60\" aria-hidden=\"true\" />Select images\n            </Button></div>\n<!-- endif --></div><!-- if errors.length > 0 -->\n<div class=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\"><AlertCircleIcon class=\"size-3 shrink-0\" /><span>${errors[0]}</span></div>\n<!-- endif --><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-center text-xs\">Multiple image uploader w/ image grid ∙${' '}<a href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\" class=\"hover:text-foreground underline\">API\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/file-upload/file-upload-06.wxml",
          "target": "components/ui/file-upload-06/file-upload-06.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex flex-col gap-2\"><view ondragenter=\"{{handleDragEnter}}\" ondragleave=\"{{handleDragLeave}}\" ondragover=\"{{handleDragOver}}\" ondrop=\"{{handleDrop}}\" data-dragging=\"{{isDragging || undefined}}\" data-files=\"{{files.length > 0 || undefined}}\" class=\"border-input data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 relative flex min-h-52 flex-col items-center overflow-hidden rounded-xl border border-dashed p-4 transition-colors not-data-[files]:justify-center has-[input:focus]:ring-[3px]\"><input class=\"sr-only\" aria-label=\"Upload image file\" /><block wx:if=\"{{files.length > 0}}\">\n<view class=\"flex w-full flex-col gap-3\"><view class=\"flex items-center justify-between gap-2\"><h3 class=\"truncate text-sm font-medium\">Uploaded Files ({{ files.length }})</h3><button variant=\"outline\" size=\"sm\" bindtap=\"openFileDialog\" disabled=\"{{files.length >= maxFiles}}\"><uploadicon class=\"-ms-0.5 size-3.5 opacity-60\" aria-hidden=\"true\" />Add more\n              </button></view><view class=\"grid grid-cols-2 gap-4 md:grid-cols-3\"><view wx:for=\"{{files}}\" wx:for-item=\"file\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{file.id}}\" class=\"bg-accent relative aspect-square rounded-md\"><image src=\"{{file.preview}}\" alt=\"{{file.file.name}}\" class=\"size-full rounded-[inherit] object-cover\" /><button bindtap=\"removeFile(file.id)\" size=\"icon\" class=\"border-background focus-visible:border-background absolute -top-2 -right-2 size-6 rounded-full border-2 shadow-none\" aria-label=\"Remove image\"><xicon class=\"size-3.5\" /></button></view></view></view>\n</block>\n<block wx:else>\n<view class=\"flex flex-col items-center justify-center px-4 py-3 text-center\"><view class=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><imageicon class=\"size-4 opacity-60\" /></view><text class=\"mb-1.5 text-sm font-medium\">Drop your images here</text><text class=\"text-muted-foreground text-xs\">SVG, PNG, JPG or GIF (max. {{ maxSizeMB }}MB)\n            </text><button variant=\"outline\" class=\"mt-4\" bindtap=\"openFileDialog\"><uploadicon class=\"-ms-1 opacity-60\" aria-hidden=\"true\" />Select images\n            </button></view>\n</block></view><view wx:if=\"{{errors.length > 0}}\" class=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\"><alertcircleicon class=\"size-3 shrink-0\" /><text>{{ errors[0] }}</text></view><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-center text-xs\">Multiple image uploader w/ image grid ∙{{ ' ' }}<a href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\" class=\"hover:text-foreground underline\">API\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "upload",
          "file",
          "image",
          "drag and drop"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "file-upload-06",
          "group": "file-upload",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "file-upload-06",
              "path": "registry/default/components/file-upload/file-upload-06.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "file-upload-06",
              "path": "registry/default/components/file-upload/file-upload-06.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "file-upload-06",
              "path": "registry/default/components/file-upload/file-upload-06.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "file-upload-06",
              "path": "registry/default/components/file-upload/file-upload-06.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "file-upload",
        "title": "File Upload · Uploaded Files ({files.length})"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "file-upload"
      ]
    },
    {
      "name": "file-upload-07",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/file-upload/file-upload-07.tsx",
          "type": "registry:component",
          "target": "components/ui/file-upload-07.tsx",
          "content": "'use client'\n\nimport { Button } from '@timui/react'\nimport { AlertCircleIcon, ImageIcon, UploadIcon, XIcon } from 'lucide-react'\n\nimport { formatBytes, useFileUpload } from '@/registry/default/hooks/use-file-upload'\n\n// Create some dummy initial files\nconst initialFiles = [\n  {\n    name: 'image-01.jpg',\n    size: 1528737,\n    type: 'image/jpeg',\n    url: 'https://picsum.photos/1000/800?grayscale&random=1',\n    id: 'image-01-123456789',\n  },\n  {\n    name: 'image-02.jpg',\n    size: 2345678,\n    type: 'image/jpeg',\n    url: 'https://picsum.photos/1000/800?grayscale&random=2',\n    id: 'image-02-123456789',\n  },\n  {\n    name: 'image-03.jpg',\n    size: 3456789,\n    type: 'image/jpeg',\n    url: 'https://picsum.photos/1000/800?grayscale&random=3',\n    id: 'image-03-123456789',\n  },\n]\n\nexport default function Component() {\n  const maxSizeMB = 5\n  const maxSize = maxSizeMB * 1024 * 1024 // 5MB default\n  const maxFiles = 6\n\n  const [\n    { files, isDragging, errors },\n    {\n      handleDragEnter,\n      handleDragLeave,\n      handleDragOver,\n      handleDrop,\n      openFileDialog,\n      removeFile,\n      clearFiles,\n      getInputProps,\n    },\n  ] = useFileUpload({\n    accept: 'image/svg+xml,image/png,image/jpeg,image/jpg,image/gif',\n    maxSize,\n    multiple: true,\n    maxFiles,\n    initialFiles,\n  })\n\n  return (\n    <div className=\"flex flex-col gap-2\">\n      {/* Drop area */}\n      <div\n        onDragEnter={handleDragEnter}\n        onDragLeave={handleDragLeave}\n        onDragOver={handleDragOver}\n        onDrop={handleDrop}\n        data-dragging={isDragging || undefined}\n        data-files={files.length > 0 || undefined}\n        className=\"border-input data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 relative flex min-h-52 flex-col items-center overflow-hidden rounded-xl border border-dashed p-4 transition-colors not-data-[files]:justify-center has-[input:focus]:ring-[3px]\"\n      >\n        <input {...getInputProps()} className=\"sr-only\" aria-label=\"Upload image file\" />\n        <div className=\"flex flex-col items-center justify-center px-4 py-3 text-center\">\n          <div\n            className=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\"\n            aria-hidden=\"true\"\n          >\n            <ImageIcon className=\"size-4 opacity-60\" />\n          </div>\n          <p className=\"mb-1.5 text-sm font-medium\">Drop your images here</p>\n          <p className=\"text-muted-foreground text-xs\">SVG, PNG, JPG or GIF (max. {maxSizeMB}MB)</p>\n          <Button variant=\"outline\" className=\"mt-4\" onClick={openFileDialog}>\n            <UploadIcon className=\"-ms-1 opacity-60\" aria-hidden=\"true\" />\n            Select images\n          </Button>\n        </div>\n      </div>\n\n      {errors.length > 0 && (\n        <div className=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\">\n          <AlertCircleIcon className=\"size-3 shrink-0\" />\n          <span>{errors[0]}</span>\n        </div>\n      )}\n\n      {/* File list */}\n      {files.length > 0 && (\n        <div className=\"space-y-2\">\n          {files.map((file) => (\n            <div\n              key={file.id}\n              className=\"bg-background flex items-center justify-between gap-2 rounded-lg border p-2 pe-3\"\n            >\n              <div className=\"flex items-center gap-3 overflow-hidden\">\n                <div className=\"bg-accent aspect-square shrink-0 rounded\">\n                  <img\n                    src={file.preview}\n                    alt={file.file.name}\n                    className=\"size-10 rounded-[inherit] object-cover\"\n                  />\n                </div>\n                <div className=\"flex min-w-0 flex-col gap-0.5\">\n                  <p className=\"truncate text-[13px] font-medium\">{file.file.name}</p>\n                  <p className=\"text-muted-foreground text-xs\">{formatBytes(file.file.size)}</p>\n                </div>\n              </div>\n\n              <Button\n                size=\"icon\"\n                variant=\"ghost\"\n                className=\"text-muted-foreground/80 hover:text-foreground -me-2 size-8 hover:bg-transparent\"\n                onClick={() => removeFile(file.id)}\n                aria-label=\"Remove file\"\n              >\n                <XIcon aria-hidden=\"true\" />\n              </Button>\n            </div>\n          ))}\n\n          {/* Remove all files button */}\n          {files.length > 1 && (\n            <div>\n              <Button size=\"sm\" variant=\"outline\" onClick={clearFiles}>\n                Remove all files\n              </Button>\n            </div>\n          )}\n        </div>\n      )}\n\n      <p\n        aria-live=\"polite\"\n        role=\"region\"\n        className=\"text-muted-foreground mt-2 text-center text-xs\"\n      >\n        Multiple image uploader w/ image list ∙{' '}\n        <a\n          href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\"\n          className=\"hover:text-foreground underline\"\n        >\n          API\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/hooks/use-file-upload.ts",
          "type": "registry:hook",
          "target": "components/ui/file-upload-07/use-file-upload.ts",
          "content": "'use client'\n\nimport type React from 'react'\nimport {\n  useCallback,\n  useRef,\n  useState,\n  type ChangeEvent,\n  type DragEvent,\n  type InputHTMLAttributes,\n} from 'react'\n\nexport type FileMetadata = {\n  name: string\n  size: number\n  type: string\n  url: string\n  id: string\n}\n\nexport type FileWithPreview = {\n  file: File | FileMetadata\n  id: string\n  preview?: string\n}\n\nexport type FileUploadOptions = {\n  maxFiles?: number // Only used when multiple is true, defaults to Infinity\n  maxSize?: number // in bytes\n  accept?: string\n  multiple?: boolean // Defaults to false\n  initialFiles?: FileMetadata[]\n  onFilesChange?: (files: FileWithPreview[]) => void // Callback when files change\n  onFilesAdded?: (addedFiles: FileWithPreview[]) => void // Callback when new files are added\n}\n\nexport type FileUploadState = {\n  files: FileWithPreview[]\n  isDragging: boolean\n  errors: string[]\n}\n\nexport type FileUploadActions = {\n  addFiles: (files: FileList | File[]) => void\n  removeFile: (id: string) => void\n  clearFiles: () => void\n  clearErrors: () => void\n  handleDragEnter: (e: DragEvent<HTMLElement>) => void\n  handleDragLeave: (e: DragEvent<HTMLElement>) => void\n  handleDragOver: (e: DragEvent<HTMLElement>) => void\n  handleDrop: (e: DragEvent<HTMLElement>) => void\n  handleFileChange: (e: ChangeEvent<HTMLInputElement>) => void\n  openFileDialog: () => void\n  getInputProps: (\n    props?: InputHTMLAttributes<HTMLInputElement>\n  ) => InputHTMLAttributes<HTMLInputElement> & {\n    ref: React.Ref<HTMLInputElement>\n  }\n}\n\nexport const useFileUpload = (\n  options: FileUploadOptions = {}\n): [FileUploadState, FileUploadActions] => {\n  const {\n    maxFiles = Infinity,\n    maxSize = Infinity,\n    accept = '*',\n    multiple = false,\n    initialFiles = [],\n    onFilesChange,\n    onFilesAdded,\n  } = options\n\n  const [state, setState] = useState<FileUploadState>({\n    files: initialFiles.map((file) => ({\n      file,\n      id: file.id,\n      preview: file.url,\n    })),\n    isDragging: false,\n    errors: [],\n  })\n\n  const inputRef = useRef<HTMLInputElement>(null)\n\n  const validateFile = useCallback(\n    (file: File | FileMetadata): string | null => {\n      if (file instanceof File) {\n        if (file.size > maxSize) {\n          return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n        }\n      } else {\n        if (file.size > maxSize) {\n          return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n        }\n      }\n\n      if (accept !== '*') {\n        const acceptedTypes = accept.split(',').map((type) => type.trim())\n        const fileType = file instanceof File ? file.type || '' : file.type\n        const fileExtension = `.${file instanceof File ? file.name.split('.').pop() : file.name.split('.').pop()}`\n\n        const isAccepted = acceptedTypes.some((type) => {\n          if (type.startsWith('.')) {\n            return fileExtension.toLowerCase() === type.toLowerCase()\n          }\n          if (type.endsWith('/*')) {\n            const baseType = type.split('/')[0]\n            return fileType.startsWith(`${baseType}/`)\n          }\n          return fileType === type\n        })\n\n        if (!isAccepted) {\n          return `File \"${file instanceof File ? file.name : file.name}\" is not an accepted file type.`\n        }\n      }\n\n      return null\n    },\n    [accept, maxSize]\n  )\n\n  const createPreview = useCallback((file: File | FileMetadata): string | undefined => {\n    if (file instanceof File) {\n      return URL.createObjectURL(file)\n    }\n    return file.url\n  }, [])\n\n  const generateUniqueId = useCallback((file: File | FileMetadata): string => {\n    if (file instanceof File) {\n      return `${file.name}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`\n    }\n    return file.id\n  }, [])\n\n  const clearFiles = useCallback(() => {\n    setState((prev) => {\n      // Clean up object URLs\n      prev.files.forEach((file) => {\n        if (file.preview && file.file instanceof File && file.file.type.startsWith('image/')) {\n          URL.revokeObjectURL(file.preview)\n        }\n      })\n\n      if (inputRef.current) {\n        inputRef.current.value = ''\n      }\n\n      const newState = {\n        ...prev,\n        files: [],\n        errors: [],\n      }\n\n      onFilesChange?.(newState.files)\n      return newState\n    })\n  }, [onFilesChange])\n\n  const addFiles = useCallback(\n    (newFiles: FileList | File[]) => {\n      if (!newFiles || newFiles.length === 0) return\n\n      const newFilesArray = Array.from(newFiles)\n      const errors: string[] = []\n\n      // Clear existing errors when new files are uploaded\n      setState((prev) => ({ ...prev, errors: [] }))\n\n      // In single file mode, clear existing files first\n      if (!multiple) {\n        clearFiles()\n      }\n\n      // Check if adding these files would exceed maxFiles (only in multiple mode)\n      if (\n        multiple &&\n        maxFiles !== Infinity &&\n        state.files.length + newFilesArray.length > maxFiles\n      ) {\n        errors.push(`You can only upload a maximum of ${maxFiles} files.`)\n        setState((prev) => ({ ...prev, errors }))\n        return\n      }\n\n      const validFiles: FileWithPreview[] = []\n\n      newFilesArray.forEach((file) => {\n        // Only check for duplicates if multiple files are allowed\n        if (multiple) {\n          const isDuplicate = state.files.some(\n            (existingFile) =>\n              existingFile.file.name === file.name && existingFile.file.size === file.size\n          )\n\n          // Skip duplicate files silently\n          if (isDuplicate) {\n            return\n          }\n        }\n\n        // Check file size\n        if (file.size > maxSize) {\n          errors.push(\n            multiple\n              ? `Some files exceed the maximum size of ${formatBytes(maxSize)}.`\n              : `File exceeds the maximum size of ${formatBytes(maxSize)}.`\n          )\n          return\n        }\n\n        const error = validateFile(file)\n        if (error) {\n          errors.push(error)\n        } else {\n          validFiles.push({\n            file,\n            id: generateUniqueId(file),\n            preview: createPreview(file),\n          })\n        }\n      })\n\n      // Only update state if we have valid files to add\n      if (validFiles.length > 0) {\n        // Call the onFilesAdded callback with the newly added valid files\n        onFilesAdded?.(validFiles)\n\n        setState((prev) => {\n          const newFiles = !multiple ? validFiles : [...prev.files, ...validFiles]\n          onFilesChange?.(newFiles)\n          return {\n            ...prev,\n            files: newFiles,\n            errors,\n          }\n        })\n      } else if (errors.length > 0) {\n        setState((prev) => ({\n          ...prev,\n          errors,\n        }))\n      }\n\n      // Reset input value after handling files\n      if (inputRef.current) {\n        inputRef.current.value = ''\n      }\n    },\n    [\n      state.files,\n      maxFiles,\n      multiple,\n      maxSize,\n      validateFile,\n      createPreview,\n      generateUniqueId,\n      clearFiles,\n      onFilesChange,\n      onFilesAdded,\n    ]\n  )\n\n  const removeFile = useCallback(\n    (id: string) => {\n      setState((prev) => {\n        const fileToRemove = prev.files.find((file) => file.id === id)\n        if (\n          fileToRemove &&\n          fileToRemove.preview &&\n          fileToRemove.file instanceof File &&\n          fileToRemove.file.type.startsWith('image/')\n        ) {\n          URL.revokeObjectURL(fileToRemove.preview)\n        }\n\n        const newFiles = prev.files.filter((file) => file.id !== id)\n        onFilesChange?.(newFiles)\n\n        return {\n          ...prev,\n          files: newFiles,\n          errors: [],\n        }\n      })\n    },\n    [onFilesChange]\n  )\n\n  const clearErrors = useCallback(() => {\n    setState((prev) => ({\n      ...prev,\n      errors: [],\n    }))\n  }, [])\n\n  const handleDragEnter = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n    setState((prev) => ({ ...prev, isDragging: true }))\n  }, [])\n\n  const handleDragLeave = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n\n    if (e.currentTarget.contains(e.relatedTarget as Node)) {\n      return\n    }\n\n    setState((prev) => ({ ...prev, isDragging: false }))\n  }, [])\n\n  const handleDragOver = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n  }, [])\n\n  const handleDrop = useCallback(\n    (e: DragEvent<HTMLElement>) => {\n      e.preventDefault()\n      e.stopPropagation()\n      setState((prev) => ({ ...prev, isDragging: false }))\n\n      // Don't process files if the input is disabled\n      if (inputRef.current?.disabled) {\n        return\n      }\n\n      if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n        // In single file mode, only use the first file\n        if (!multiple) {\n          const file = e.dataTransfer.files[0]\n          addFiles([file])\n        } else {\n          addFiles(e.dataTransfer.files)\n        }\n      }\n    },\n    [addFiles, multiple]\n  )\n\n  const handleFileChange = useCallback(\n    (e: ChangeEvent<HTMLInputElement>) => {\n      if (e.target.files && e.target.files.length > 0) {\n        addFiles(e.target.files)\n      }\n    },\n    [addFiles]\n  )\n\n  const openFileDialog = useCallback(() => {\n    if (inputRef.current) {\n      inputRef.current.click()\n    }\n  }, [])\n\n  const getInputProps = useCallback(\n    (props: InputHTMLAttributes<HTMLInputElement> = {}) => {\n      return {\n        ...props,\n        type: 'file' as const,\n        onChange: handleFileChange,\n        accept: props.accept || accept,\n        multiple: props.multiple !== undefined ? props.multiple : multiple,\n        ref: inputRef,\n      }\n    },\n    [accept, multiple, handleFileChange]\n  )\n\n  return [\n    state,\n    {\n      addFiles,\n      removeFile,\n      clearFiles,\n      clearErrors,\n      handleDragEnter,\n      handleDragLeave,\n      handleDragOver,\n      handleDrop,\n      handleFileChange,\n      openFileDialog,\n      getInputProps,\n    },\n  ]\n}\n\n// Helper function to format bytes to human-readable format\nexport const formatBytes = (bytes: number, decimals = 2): string => {\n  if (bytes === 0) return '0 Bytes'\n\n  const k = 1024\n  const dm = decimals < 0 ? 0 : decimals\n  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']\n\n  const i = Math.floor(Math.log(bytes) / Math.log(k))\n\n  return Number.parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + sizes[i]\n}\n"
        },
        {
          "path": "registry/default/components/file-upload/file-upload-07.vue",
          "target": "components/ui/file-upload-07.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { AlertCircleIcon, ImageIcon, UploadIcon, XIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { formatBytes, useFileUpload } from '@/registry/default/hooks/use-file-upload-vue';\n\nconst initialFiles = [\n  {\n    name: 'image-01.jpg',\n    size: 1528737,\n    type: 'image/jpeg',\n    url: 'https://picsum.photos/1000/800?grayscale&random=1',\n    id: 'image-01-123456789',\n  },\n  {\n    name: 'image-02.jpg',\n    size: 2345678,\n    type: 'image/jpeg',\n    url: 'https://picsum.photos/1000/800?grayscale&random=2',\n    id: 'image-02-123456789',\n  },\n  {\n    name: 'image-03.jpg',\n    size: 3456789,\n    type: 'image/jpeg',\n    url: 'https://picsum.photos/1000/800?grayscale&random=3',\n    id: 'image-03-123456789',\n  },\n];\n\nconst maxSizeMB = 5;\nconst maxSize = maxSizeMB * 1024 * 1024;\nconst maxFiles = 6;\n\nconst [\n  { files, isDragging, errors },\n  {\n    handleDragEnter,\n    handleDragLeave,\n    handleDragOver,\n    handleDrop,\n    openFileDialog,\n    removeFile,\n    clearFiles,\n  },\n] = useFileUpload({\n  accept: 'image/svg+xml,image/png,image/jpeg,image/jpg,image/gif',\n  maxSize,\n  multiple: true,\n  maxFiles,\n  initialFiles,\n});\n</script>\n\n<template>\n  <div class=\"flex flex-col gap-2\"><div @dragenter=\"handleDragEnter\" @dragleave=\"handleDragLeave\" @dragover=\"handleDragOver\" @drop=\"handleDrop\" :data-dragging=\"isDragging || undefined\" :data-files=\"files.length > 0 || undefined\" class=\"border-input data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 relative flex min-h-52 flex-col items-center overflow-hidden rounded-xl border border-dashed p-4 transition-colors not-data-[files]:justify-center has-[input:focus]:ring-[3px]\"><input class=\"sr-only\" aria-label=\"Upload image file\" /><div class=\"flex flex-col items-center justify-center px-4 py-3 text-center\"><div class=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><ImageIcon class=\"size-4 opacity-60\" /></div><p class=\"mb-1.5 text-sm font-medium\">Drop your images here</p><p class=\"text-muted-foreground text-xs\">SVG, PNG, JPG or GIF (max. {{ maxSizeMB }}MB)</p><Button variant=\"outline\" class=\"mt-4\" @click=\"openFileDialog\"><UploadIcon class=\"-ms-1 opacity-60\" aria-hidden=\"true\" />Select images\n          </Button></div></div><div v-if=\"errors.length > 0\" class=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\"><AlertCircleIcon class=\"size-3 shrink-0\" /><span>{{ errors[0] }}</span></div><div v-if=\"files.length > 0\" class=\"space-y-2\"><div v-for=\"(file, index) in files\" :key=\"file.id\" class=\"bg-background flex items-center justify-between gap-2 rounded-lg border p-2 pe-3\"><div class=\"flex items-center gap-3 overflow-hidden\"><div class=\"bg-accent aspect-square shrink-0 rounded\"><img :src=\"file.preview\" :alt=\"file.file.name\" class=\"size-10 rounded-[inherit] object-cover\" /></div><div class=\"flex min-w-0 flex-col gap-0.5\"><p class=\"truncate text-[13px] font-medium\">{{ file.file.name }}</p><p class=\"text-muted-foreground text-xs\">{{ formatBytes(file.file.size) }}</p></div></div><Button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground/80 hover:text-foreground -me-2 size-8 hover:bg-transparent\" @click=\"removeFile(file.id)\" aria-label=\"Remove file\"><XIcon aria-hidden=\"true\" /></Button></div><div v-if=\"files.length > 1\"><Button size=\"sm\" variant=\"outline\" @click=\"clearFiles\">Remove all files\n              </Button></div></div><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-center text-xs\">Multiple image uploader w/ image list ∙{{ ' ' }}<a href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\" class=\"hover:text-foreground underline\">API\n        </a></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/file-upload/file-upload-07.html",
          "target": "components/ui/file-upload-07.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex flex-col gap-2\"><div ondragenter=\"${handleDragEnter}\" ondragleave=\"${handleDragLeave}\" ondragover=\"${handleDragOver}\" ondrop=\"${handleDrop}\" data-dragging=\"${isDragging || undefined}\" data-files=\"${files.length > 0 || undefined}\" class=\"border-input data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 relative flex min-h-52 flex-col items-center overflow-hidden rounded-xl border border-dashed p-4 transition-colors not-data-[files]:justify-center has-[input:focus]:ring-[3px]\"><input class=\"sr-only\" aria-label=\"Upload image file\" /><div class=\"flex flex-col items-center justify-center px-4 py-3 text-center\"><div class=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><ImageIcon class=\"size-4 opacity-60\" /></div><p class=\"mb-1.5 text-sm font-medium\">Drop your images here</p><p class=\"text-muted-foreground text-xs\">SVG, PNG, JPG or GIF (max. ${maxSizeMB}MB)</p><Button variant=\"outline\" class=\"mt-4\" on-click=\"${openFileDialog}\"><UploadIcon class=\"-ms-1 opacity-60\" aria-hidden=\"true\" />Select images\n          </Button></div></div><!-- if errors.length > 0 -->\n<div class=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\"><AlertCircleIcon class=\"size-3 shrink-0\" /><span>${errors[0]}</span></div>\n<!-- endif --><!-- if files.length > 0 -->\n<div class=\"space-y-2\"><!-- Loop files -->\n<div key=\"${file.id}\" class=\"bg-background flex items-center justify-between gap-2 rounded-lg border p-2 pe-3\"><div class=\"flex items-center gap-3 overflow-hidden\"><div class=\"bg-accent aspect-square shrink-0 rounded\"><img src=\"${file.preview}\" alt=\"${file.file.name}\" class=\"size-10 rounded-[inherit] object-cover\" /></div><div class=\"flex min-w-0 flex-col gap-0.5\"><p class=\"truncate text-[13px] font-medium\">${file.file.name}</p><p class=\"text-muted-foreground text-xs\">${formatBytes(file.file.size)}</p></div></div><Button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground/80 hover:text-foreground -me-2 size-8 hover:bg-transparent\" on-click=\"${() => removeFile(file.id)}\" aria-label=\"Remove file\"><XIcon aria-hidden=\"true\" /></Button></div>\n<!-- End Loop --><!-- if files.length > 1 -->\n<div><Button size=\"sm\" variant=\"outline\" on-click=\"${clearFiles}\">Remove all files\n              </Button></div>\n<!-- endif --></div>\n<!-- endif --><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-center text-xs\">Multiple image uploader w/ image list ∙${' '}<a href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\" class=\"hover:text-foreground underline\">API\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/file-upload/file-upload-07.wxml",
          "target": "components/ui/file-upload-07/file-upload-07.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex flex-col gap-2\"><view ondragenter=\"{{handleDragEnter}}\" ondragleave=\"{{handleDragLeave}}\" ondragover=\"{{handleDragOver}}\" ondrop=\"{{handleDrop}}\" data-dragging=\"{{isDragging || undefined}}\" data-files=\"{{files.length > 0 || undefined}}\" class=\"border-input data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 relative flex min-h-52 flex-col items-center overflow-hidden rounded-xl border border-dashed p-4 transition-colors not-data-[files]:justify-center has-[input:focus]:ring-[3px]\"><input class=\"sr-only\" aria-label=\"Upload image file\" /><view class=\"flex flex-col items-center justify-center px-4 py-3 text-center\"><view class=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><imageicon class=\"size-4 opacity-60\" /></view><text class=\"mb-1.5 text-sm font-medium\">Drop your images here</text><text class=\"text-muted-foreground text-xs\">SVG, PNG, JPG or GIF (max. {{ maxSizeMB }}MB)</text><button variant=\"outline\" class=\"mt-4\" bindtap=\"openFileDialog\"><uploadicon class=\"-ms-1 opacity-60\" aria-hidden=\"true\" />Select images\n          </button></view></view><view wx:if=\"{{errors.length > 0}}\" class=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\"><alertcircleicon class=\"size-3 shrink-0\" /><text>{{ errors[0] }}</text></view><view wx:if=\"{{files.length > 0}}\" class=\"space-y-2\"><view wx:for=\"{{files}}\" wx:for-item=\"file\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{file.id}}\" class=\"bg-background flex items-center justify-between gap-2 rounded-lg border p-2 pe-3\"><view class=\"flex items-center gap-3 overflow-hidden\"><view class=\"bg-accent aspect-square shrink-0 rounded\"><image src=\"{{file.preview}}\" alt=\"{{file.file.name}}\" class=\"size-10 rounded-[inherit] object-cover\" /></view><view class=\"flex min-w-0 flex-col gap-0.5\"><text class=\"truncate text-[13px] font-medium\">{{ file.file.name }}</text><text class=\"text-muted-foreground text-xs\">{{ formatBytes(file.file.size) }}</text></view></view><button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground/80 hover:text-foreground -me-2 size-8 hover:bg-transparent\" bindtap=\"removeFile(file.id)\" aria-label=\"Remove file\"><xicon aria-hidden=\"true\" /></button></view><view wx:if=\"{{files.length > 1}}\"><button size=\"sm\" variant=\"outline\" bindtap=\"clearFiles\">Remove all files\n              </button></view></view><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-center text-xs\">Multiple image uploader w/ image list ∙{{ ' ' }}<a href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\" class=\"hover:text-foreground underline\">API\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "upload",
          "file",
          "image",
          "drag and drop"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "file-upload-07",
          "group": "file-upload",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "file-upload-07",
              "path": "registry/default/components/file-upload/file-upload-07.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "file-upload-07",
              "path": "registry/default/components/file-upload/file-upload-07.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "file-upload-07",
              "path": "registry/default/components/file-upload/file-upload-07.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "file-upload-07",
              "path": "registry/default/components/file-upload/file-upload-07.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "file-upload",
        "title": "File Upload · Upload image file"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "file-upload"
      ]
    },
    {
      "name": "file-upload-08",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/file-upload/file-upload-08.tsx",
          "type": "registry:component",
          "target": "components/ui/file-upload-08.tsx",
          "content": "'use client'\n\nimport { Button } from '@timui/react'\nimport { AlertCircleIcon, PaperclipIcon, UploadIcon, XIcon } from 'lucide-react'\n\nimport { formatBytes, useFileUpload } from '@/registry/default/hooks/use-file-upload'\n\n// Create some dummy initial files\nconst initialFiles = [\n  {\n    name: 'document.pdf',\n    size: 1528737,\n    type: 'application/pdf',\n    url: 'https://picsum.photos/1000/800?grayscale&random=1',\n    id: 'document.pdf-1744638436563-8u5xuls',\n  },\n]\n\nexport default function Component() {\n  const maxSize = 10 * 1024 * 1024 // 10MB default\n\n  const [\n    { files, isDragging, errors },\n    {\n      handleDragEnter,\n      handleDragLeave,\n      handleDragOver,\n      handleDrop,\n      openFileDialog,\n      removeFile,\n      getInputProps,\n    },\n  ] = useFileUpload({\n    maxSize,\n    initialFiles,\n  })\n\n  const file = files[0]\n\n  return (\n    <div className=\"flex flex-col gap-2\">\n      {/* Drop area */}\n      <div\n        role=\"button\"\n        onClick={openFileDialog}\n        onDragEnter={handleDragEnter}\n        onDragLeave={handleDragLeave}\n        onDragOver={handleDragOver}\n        onDrop={handleDrop}\n        data-dragging={isDragging || undefined}\n        className=\"border-input hover:bg-accent/50 data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 flex min-h-40 flex-col items-center justify-center rounded-xl border border-dashed p-4 transition-colors has-disabled:pointer-events-none has-disabled:opacity-50 has-[input:focus]:ring-[3px]\"\n      >\n        <input\n          {...getInputProps()}\n          className=\"sr-only\"\n          aria-label=\"Upload file\"\n          disabled={Boolean(file)}\n        />\n\n        <div className=\"flex flex-col items-center justify-center text-center\">\n          <div\n            className=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\"\n            aria-hidden=\"true\"\n          >\n            <UploadIcon className=\"size-4 opacity-60\" />\n          </div>\n          <p className=\"mb-1.5 text-sm font-medium\">Upload file</p>\n          <p className=\"text-muted-foreground text-xs\">\n            Drag & drop or click to browse (max. {formatBytes(maxSize)})\n          </p>\n        </div>\n      </div>\n\n      {errors.length > 0 && (\n        <div className=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\">\n          <AlertCircleIcon className=\"size-3 shrink-0\" />\n          <span>{errors[0]}</span>\n        </div>\n      )}\n\n      {/* File list */}\n      {file && (\n        <div className=\"space-y-2\">\n          <div\n            key={file.id}\n            className=\"flex items-center justify-between gap-2 rounded-xl border px-4 py-2\"\n          >\n            <div className=\"flex items-center gap-3 overflow-hidden\">\n              <PaperclipIcon className=\"size-4 shrink-0 opacity-60\" aria-hidden=\"true\" />\n              <div className=\"min-w-0\">\n                <p className=\"truncate text-[13px] font-medium\">{file.file.name}</p>\n              </div>\n            </div>\n\n            <Button\n              size=\"icon\"\n              variant=\"ghost\"\n              className=\"text-muted-foreground/80 hover:text-foreground -me-2 size-8 hover:bg-transparent\"\n              onClick={() => removeFile(files[0]?.id)}\n              aria-label=\"Remove file\"\n            >\n              <XIcon className=\"size-4\" aria-hidden=\"true\" />\n            </Button>\n          </div>\n        </div>\n      )}\n\n      <p\n        aria-live=\"polite\"\n        role=\"region\"\n        className=\"text-muted-foreground mt-2 text-center text-xs\"\n      >\n        Single file uploader w/ max size ∙{' '}\n        <a\n          href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\"\n          className=\"hover:text-foreground underline\"\n        >\n          API\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/hooks/use-file-upload.ts",
          "type": "registry:hook",
          "target": "components/ui/file-upload-08/use-file-upload.ts",
          "content": "'use client'\n\nimport type React from 'react'\nimport {\n  useCallback,\n  useRef,\n  useState,\n  type ChangeEvent,\n  type DragEvent,\n  type InputHTMLAttributes,\n} from 'react'\n\nexport type FileMetadata = {\n  name: string\n  size: number\n  type: string\n  url: string\n  id: string\n}\n\nexport type FileWithPreview = {\n  file: File | FileMetadata\n  id: string\n  preview?: string\n}\n\nexport type FileUploadOptions = {\n  maxFiles?: number // Only used when multiple is true, defaults to Infinity\n  maxSize?: number // in bytes\n  accept?: string\n  multiple?: boolean // Defaults to false\n  initialFiles?: FileMetadata[]\n  onFilesChange?: (files: FileWithPreview[]) => void // Callback when files change\n  onFilesAdded?: (addedFiles: FileWithPreview[]) => void // Callback when new files are added\n}\n\nexport type FileUploadState = {\n  files: FileWithPreview[]\n  isDragging: boolean\n  errors: string[]\n}\n\nexport type FileUploadActions = {\n  addFiles: (files: FileList | File[]) => void\n  removeFile: (id: string) => void\n  clearFiles: () => void\n  clearErrors: () => void\n  handleDragEnter: (e: DragEvent<HTMLElement>) => void\n  handleDragLeave: (e: DragEvent<HTMLElement>) => void\n  handleDragOver: (e: DragEvent<HTMLElement>) => void\n  handleDrop: (e: DragEvent<HTMLElement>) => void\n  handleFileChange: (e: ChangeEvent<HTMLInputElement>) => void\n  openFileDialog: () => void\n  getInputProps: (\n    props?: InputHTMLAttributes<HTMLInputElement>\n  ) => InputHTMLAttributes<HTMLInputElement> & {\n    ref: React.Ref<HTMLInputElement>\n  }\n}\n\nexport const useFileUpload = (\n  options: FileUploadOptions = {}\n): [FileUploadState, FileUploadActions] => {\n  const {\n    maxFiles = Infinity,\n    maxSize = Infinity,\n    accept = '*',\n    multiple = false,\n    initialFiles = [],\n    onFilesChange,\n    onFilesAdded,\n  } = options\n\n  const [state, setState] = useState<FileUploadState>({\n    files: initialFiles.map((file) => ({\n      file,\n      id: file.id,\n      preview: file.url,\n    })),\n    isDragging: false,\n    errors: [],\n  })\n\n  const inputRef = useRef<HTMLInputElement>(null)\n\n  const validateFile = useCallback(\n    (file: File | FileMetadata): string | null => {\n      if (file instanceof File) {\n        if (file.size > maxSize) {\n          return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n        }\n      } else {\n        if (file.size > maxSize) {\n          return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n        }\n      }\n\n      if (accept !== '*') {\n        const acceptedTypes = accept.split(',').map((type) => type.trim())\n        const fileType = file instanceof File ? file.type || '' : file.type\n        const fileExtension = `.${file instanceof File ? file.name.split('.').pop() : file.name.split('.').pop()}`\n\n        const isAccepted = acceptedTypes.some((type) => {\n          if (type.startsWith('.')) {\n            return fileExtension.toLowerCase() === type.toLowerCase()\n          }\n          if (type.endsWith('/*')) {\n            const baseType = type.split('/')[0]\n            return fileType.startsWith(`${baseType}/`)\n          }\n          return fileType === type\n        })\n\n        if (!isAccepted) {\n          return `File \"${file instanceof File ? file.name : file.name}\" is not an accepted file type.`\n        }\n      }\n\n      return null\n    },\n    [accept, maxSize]\n  )\n\n  const createPreview = useCallback((file: File | FileMetadata): string | undefined => {\n    if (file instanceof File) {\n      return URL.createObjectURL(file)\n    }\n    return file.url\n  }, [])\n\n  const generateUniqueId = useCallback((file: File | FileMetadata): string => {\n    if (file instanceof File) {\n      return `${file.name}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`\n    }\n    return file.id\n  }, [])\n\n  const clearFiles = useCallback(() => {\n    setState((prev) => {\n      // Clean up object URLs\n      prev.files.forEach((file) => {\n        if (file.preview && file.file instanceof File && file.file.type.startsWith('image/')) {\n          URL.revokeObjectURL(file.preview)\n        }\n      })\n\n      if (inputRef.current) {\n        inputRef.current.value = ''\n      }\n\n      const newState = {\n        ...prev,\n        files: [],\n        errors: [],\n      }\n\n      onFilesChange?.(newState.files)\n      return newState\n    })\n  }, [onFilesChange])\n\n  const addFiles = useCallback(\n    (newFiles: FileList | File[]) => {\n      if (!newFiles || newFiles.length === 0) return\n\n      const newFilesArray = Array.from(newFiles)\n      const errors: string[] = []\n\n      // Clear existing errors when new files are uploaded\n      setState((prev) => ({ ...prev, errors: [] }))\n\n      // In single file mode, clear existing files first\n      if (!multiple) {\n        clearFiles()\n      }\n\n      // Check if adding these files would exceed maxFiles (only in multiple mode)\n      if (\n        multiple &&\n        maxFiles !== Infinity &&\n        state.files.length + newFilesArray.length > maxFiles\n      ) {\n        errors.push(`You can only upload a maximum of ${maxFiles} files.`)\n        setState((prev) => ({ ...prev, errors }))\n        return\n      }\n\n      const validFiles: FileWithPreview[] = []\n\n      newFilesArray.forEach((file) => {\n        // Only check for duplicates if multiple files are allowed\n        if (multiple) {\n          const isDuplicate = state.files.some(\n            (existingFile) =>\n              existingFile.file.name === file.name && existingFile.file.size === file.size\n          )\n\n          // Skip duplicate files silently\n          if (isDuplicate) {\n            return\n          }\n        }\n\n        // Check file size\n        if (file.size > maxSize) {\n          errors.push(\n            multiple\n              ? `Some files exceed the maximum size of ${formatBytes(maxSize)}.`\n              : `File exceeds the maximum size of ${formatBytes(maxSize)}.`\n          )\n          return\n        }\n\n        const error = validateFile(file)\n        if (error) {\n          errors.push(error)\n        } else {\n          validFiles.push({\n            file,\n            id: generateUniqueId(file),\n            preview: createPreview(file),\n          })\n        }\n      })\n\n      // Only update state if we have valid files to add\n      if (validFiles.length > 0) {\n        // Call the onFilesAdded callback with the newly added valid files\n        onFilesAdded?.(validFiles)\n\n        setState((prev) => {\n          const newFiles = !multiple ? validFiles : [...prev.files, ...validFiles]\n          onFilesChange?.(newFiles)\n          return {\n            ...prev,\n            files: newFiles,\n            errors,\n          }\n        })\n      } else if (errors.length > 0) {\n        setState((prev) => ({\n          ...prev,\n          errors,\n        }))\n      }\n\n      // Reset input value after handling files\n      if (inputRef.current) {\n        inputRef.current.value = ''\n      }\n    },\n    [\n      state.files,\n      maxFiles,\n      multiple,\n      maxSize,\n      validateFile,\n      createPreview,\n      generateUniqueId,\n      clearFiles,\n      onFilesChange,\n      onFilesAdded,\n    ]\n  )\n\n  const removeFile = useCallback(\n    (id: string) => {\n      setState((prev) => {\n        const fileToRemove = prev.files.find((file) => file.id === id)\n        if (\n          fileToRemove &&\n          fileToRemove.preview &&\n          fileToRemove.file instanceof File &&\n          fileToRemove.file.type.startsWith('image/')\n        ) {\n          URL.revokeObjectURL(fileToRemove.preview)\n        }\n\n        const newFiles = prev.files.filter((file) => file.id !== id)\n        onFilesChange?.(newFiles)\n\n        return {\n          ...prev,\n          files: newFiles,\n          errors: [],\n        }\n      })\n    },\n    [onFilesChange]\n  )\n\n  const clearErrors = useCallback(() => {\n    setState((prev) => ({\n      ...prev,\n      errors: [],\n    }))\n  }, [])\n\n  const handleDragEnter = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n    setState((prev) => ({ ...prev, isDragging: true }))\n  }, [])\n\n  const handleDragLeave = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n\n    if (e.currentTarget.contains(e.relatedTarget as Node)) {\n      return\n    }\n\n    setState((prev) => ({ ...prev, isDragging: false }))\n  }, [])\n\n  const handleDragOver = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n  }, [])\n\n  const handleDrop = useCallback(\n    (e: DragEvent<HTMLElement>) => {\n      e.preventDefault()\n      e.stopPropagation()\n      setState((prev) => ({ ...prev, isDragging: false }))\n\n      // Don't process files if the input is disabled\n      if (inputRef.current?.disabled) {\n        return\n      }\n\n      if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n        // In single file mode, only use the first file\n        if (!multiple) {\n          const file = e.dataTransfer.files[0]\n          addFiles([file])\n        } else {\n          addFiles(e.dataTransfer.files)\n        }\n      }\n    },\n    [addFiles, multiple]\n  )\n\n  const handleFileChange = useCallback(\n    (e: ChangeEvent<HTMLInputElement>) => {\n      if (e.target.files && e.target.files.length > 0) {\n        addFiles(e.target.files)\n      }\n    },\n    [addFiles]\n  )\n\n  const openFileDialog = useCallback(() => {\n    if (inputRef.current) {\n      inputRef.current.click()\n    }\n  }, [])\n\n  const getInputProps = useCallback(\n    (props: InputHTMLAttributes<HTMLInputElement> = {}) => {\n      return {\n        ...props,\n        type: 'file' as const,\n        onChange: handleFileChange,\n        accept: props.accept || accept,\n        multiple: props.multiple !== undefined ? props.multiple : multiple,\n        ref: inputRef,\n      }\n    },\n    [accept, multiple, handleFileChange]\n  )\n\n  return [\n    state,\n    {\n      addFiles,\n      removeFile,\n      clearFiles,\n      clearErrors,\n      handleDragEnter,\n      handleDragLeave,\n      handleDragOver,\n      handleDrop,\n      handleFileChange,\n      openFileDialog,\n      getInputProps,\n    },\n  ]\n}\n\n// Helper function to format bytes to human-readable format\nexport const formatBytes = (bytes: number, decimals = 2): string => {\n  if (bytes === 0) return '0 Bytes'\n\n  const k = 1024\n  const dm = decimals < 0 ? 0 : decimals\n  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']\n\n  const i = Math.floor(Math.log(bytes) / Math.log(k))\n\n  return Number.parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + sizes[i]\n}\n"
        },
        {
          "path": "registry/default/components/file-upload/file-upload-08.vue",
          "target": "components/ui/file-upload-08.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { AlertCircleIcon, PaperclipIcon, UploadIcon, XIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { formatBytes, useFileUpload } from '@/registry/default/hooks/use-file-upload-vue';\n\nconst initialFiles = [\n  {\n    name: 'document.pdf',\n    size: 1528737,\n    type: 'application/pdf',\n    url: 'https://picsum.photos/1000/800?grayscale&random=1',\n    id: 'document.pdf-1744638436563-8u5xuls',\n  },\n];\n\nconst maxSize = 10 * 1024 * 1024;\n\nconst [\n  { files, isDragging, errors },\n  {\n    handleDragEnter,\n    handleDragLeave,\n    handleDragOver,\n    handleDrop,\n    openFileDialog,\n    removeFile,\n    getInputProps,\n  },\n] = useFileUpload({\n  maxSize,\n  initialFiles,\n});\n\nconst file = computed(() => files.value[0] ?? null);\n\nfunction removeCurrentFile() {\n  const fileId = files.value[0]?.id;\n  if (fileId) {\n    removeFile(fileId);\n  }\n}\n</script>\n\n<template>\n  <div class=\"flex flex-col gap-2\">\n    <div\n      role=\"button\"\n      @click=\"openFileDialog\"\n      @dragenter=\"handleDragEnter\"\n      @dragleave=\"handleDragLeave\"\n      @dragover=\"handleDragOver\"\n      @drop=\"handleDrop\"\n      :data-dragging=\"isDragging || undefined\"\n      class=\"border-input hover:bg-accent/50 data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 flex min-h-40 flex-col items-center justify-center rounded-xl border border-dashed p-4 transition-colors has-disabled:pointer-events-none has-disabled:opacity-50 has-[input:focus]:ring-[3px]\"\n    >\n      <input\n        v-bind=\"getInputProps()\"\n        class=\"sr-only\"\n        aria-label=\"Upload file\"\n        :disabled=\"Boolean(file)\"\n      />\n\n      <div class=\"flex flex-col items-center justify-center text-center\">\n        <div class=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\">\n          <UploadIcon class=\"size-4 opacity-60\" />\n        </div>\n        <p class=\"mb-1.5 text-sm font-medium\">Upload file</p>\n        <p class=\"text-muted-foreground text-xs\">Drag & drop or click to browse (max. {{ formatBytes(maxSize) }})</p>\n      </div>\n    </div>\n\n    <div v-if=\"errors.length > 0\" class=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\">\n      <AlertCircleIcon class=\"size-3 shrink-0\" />\n      <span>{{ errors[0] }}</span>\n    </div>\n\n    <div v-if=\"file\" class=\"space-y-2\">\n      <div :key=\"file.id\" class=\"flex items-center justify-between gap-2 rounded-xl border px-4 py-2\">\n        <div class=\"flex items-center gap-3 overflow-hidden\">\n          <PaperclipIcon class=\"size-4 shrink-0 opacity-60\" aria-hidden=\"true\" />\n          <div class=\"min-w-0\">\n            <p class=\"truncate text-[13px] font-medium\">{{ file.file.name }}</p>\n          </div>\n        </div>\n\n        <Button\n          size=\"icon\"\n          variant=\"ghost\"\n          class=\"text-muted-foreground/80 hover:text-foreground -me-2 size-8 hover:bg-transparent\"\n          @click=\"removeCurrentFile\"\n          aria-label=\"Remove file\"\n        >\n          <XIcon class=\"size-4\" aria-hidden=\"true\" />\n        </Button>\n      </div>\n    </div>\n\n    <p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-center text-xs\">\n      Single file uploader w/ max size ∙\n      <a\n        href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\"\n        class=\"hover:text-foreground underline\"\n      >\n        API\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/file-upload/file-upload-08.html",
          "target": "components/ui/file-upload-08.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex flex-col gap-2\"><div role=\"button\" on-click=\"${openFileDialog}\" ondragenter=\"${handleDragEnter}\" ondragleave=\"${handleDragLeave}\" ondragover=\"${handleDragOver}\" ondrop=\"${handleDrop}\" data-dragging=\"${isDragging || undefined}\" class=\"border-input hover:bg-accent/50 data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 flex min-h-40 flex-col items-center justify-center rounded-xl border border-dashed p-4 transition-colors has-disabled:pointer-events-none has-disabled:opacity-50 has-[input:focus]:ring-[3px]\"><input class=\"sr-only\" aria-label=\"Upload file\" disabled=\"${Boolean(file)}\" /><div class=\"flex flex-col items-center justify-center text-center\"><div class=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><UploadIcon class=\"size-4 opacity-60\" /></div><p class=\"mb-1.5 text-sm font-medium\">Upload file</p><p class=\"text-muted-foreground text-xs\">Drag & drop or click to browse (max. ${formatBytes(maxSize)})\n          </p></div></div><!-- if errors.length > 0 -->\n<div class=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\"><AlertCircleIcon class=\"size-3 shrink-0\" /><span>${errors[0]}</span></div>\n<!-- endif --><!-- if file -->\n<div class=\"space-y-2\"><div key=\"${file.id}\" class=\"flex items-center justify-between gap-2 rounded-xl border px-4 py-2\"><div class=\"flex items-center gap-3 overflow-hidden\"><PaperclipIcon class=\"size-4 shrink-0 opacity-60\" aria-hidden=\"true\" /><div class=\"min-w-0\"><p class=\"truncate text-[13px] font-medium\">${file.file.name}</p></div></div><Button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground/80 hover:text-foreground -me-2 size-8 hover:bg-transparent\" on-click=\"${() => removeFile(files[0]?.id)}\" aria-label=\"Remove file\"><XIcon class=\"size-4\" aria-hidden=\"true\" /></Button></div></div>\n<!-- endif --><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-center text-xs\">Single file uploader w/ max size ∙${' '}<a href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\" class=\"hover:text-foreground underline\">API\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/file-upload/file-upload-08.wxml",
          "target": "components/ui/file-upload-08/file-upload-08.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex flex-col gap-2\"><view role=\"button\" bindtap=\"openFileDialog\" ondragenter=\"{{handleDragEnter}}\" ondragleave=\"{{handleDragLeave}}\" ondragover=\"{{handleDragOver}}\" ondrop=\"{{handleDrop}}\" data-dragging=\"{{isDragging || undefined}}\" class=\"border-input hover:bg-accent/50 data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 flex min-h-40 flex-col items-center justify-center rounded-xl border border-dashed p-4 transition-colors has-disabled:pointer-events-none has-disabled:opacity-50 has-[input:focus]:ring-[3px]\"><input class=\"sr-only\" aria-label=\"Upload file\" disabled=\"{{Boolean(file)}}\" /><view class=\"flex flex-col items-center justify-center text-center\"><view class=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><uploadicon class=\"size-4 opacity-60\" /></view><text class=\"mb-1.5 text-sm font-medium\">Upload file</text><text class=\"text-muted-foreground text-xs\">Drag & drop or click to browse (max. {{ formatBytes(maxSize) }})\n          </text></view></view><view wx:if=\"{{errors.length > 0}}\" class=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\"><alertcircleicon class=\"size-3 shrink-0\" /><text>{{ errors[0] }}</text></view><view wx:if=\"{{file}}\" class=\"space-y-2\"><view key=\"{{file.id}}\" class=\"flex items-center justify-between gap-2 rounded-xl border px-4 py-2\"><view class=\"flex items-center gap-3 overflow-hidden\"><paperclipicon class=\"size-4 shrink-0 opacity-60\" aria-hidden=\"true\" /><view class=\"min-w-0\"><text class=\"truncate text-[13px] font-medium\">{{ file.file.name }}</text></view></view><button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground/80 hover:text-foreground -me-2 size-8 hover:bg-transparent\" bindtap=\"removeFile(files[0]?.id)\" aria-label=\"Remove file\"><xicon class=\"size-4\" aria-hidden=\"true\" /></button></view></view><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-center text-xs\">Single file uploader w/ max size ∙{{ ' ' }}<a href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\" class=\"hover:text-foreground underline\">API\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "upload",
          "file",
          "image",
          "drag and drop"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "file-upload-08",
          "group": "file-upload",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "file-upload-08",
              "path": "registry/default/components/file-upload/file-upload-08.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "file-upload-08",
              "path": "registry/default/components/file-upload/file-upload-08.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "file-upload-08",
              "path": "registry/default/components/file-upload/file-upload-08.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "file-upload-08",
              "path": "registry/default/components/file-upload/file-upload-08.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "file-upload",
        "title": "File Upload · Upload file"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "file-upload"
      ]
    },
    {
      "name": "file-upload-09",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/file-upload/file-upload-09.tsx",
          "type": "registry:component",
          "target": "components/ui/file-upload-09.tsx",
          "content": "'use client'\n\nimport { Button } from '@timui/react'\nimport {\n  AlertCircleIcon,\n  FileArchiveIcon,\n  FileIcon,\n  FileSpreadsheetIcon,\n  FileTextIcon,\n  FileUpIcon,\n  HeadphonesIcon,\n  ImageIcon,\n  VideoIcon,\n  XIcon,\n} from 'lucide-react'\n\nimport { formatBytes, useFileUpload } from '@/registry/default/hooks/use-file-upload'\n\n// Create some dummy initial files\nconst initialFiles = [\n  {\n    name: 'document.pdf',\n    size: 528737,\n    type: 'application/pdf',\n    url: 'https://example.com/document.pdf',\n    id: 'document.pdf-1744638436563-8u5xuls',\n  },\n  {\n    name: 'intro.zip',\n    size: 252873,\n    type: 'application/zip',\n    url: 'https://example.com/intro.zip',\n    id: 'intro.zip-1744638436563-8u5xuls',\n  },\n  {\n    name: 'conclusion.xlsx',\n    size: 352873,\n    type: 'application/xlsx',\n    url: 'https://example.com/conclusion.xlsx',\n    id: 'conclusion.xlsx-1744638436563-8u5xuls',\n  },\n]\n\nconst getFileIcon = (file: { file: File | { type: string; name: string } }) => {\n  const fileType = file.file instanceof File ? file.file.type : file.file.type\n  const fileName = file.file instanceof File ? file.file.name : file.file.name\n\n  if (\n    fileType.includes('pdf') ||\n    fileName.endsWith('.pdf') ||\n    fileType.includes('word') ||\n    fileName.endsWith('.doc') ||\n    fileName.endsWith('.docx')\n  ) {\n    return <FileTextIcon className=\"size-4 opacity-60\" />\n  } else if (\n    fileType.includes('zip') ||\n    fileType.includes('archive') ||\n    fileName.endsWith('.zip') ||\n    fileName.endsWith('.rar')\n  ) {\n    return <FileArchiveIcon className=\"size-4 opacity-60\" />\n  } else if (\n    fileType.includes('excel') ||\n    fileName.endsWith('.xls') ||\n    fileName.endsWith('.xlsx')\n  ) {\n    return <FileSpreadsheetIcon className=\"size-4 opacity-60\" />\n  } else if (fileType.includes('video/')) {\n    return <VideoIcon className=\"size-4 opacity-60\" />\n  } else if (fileType.includes('audio/')) {\n    return <HeadphonesIcon className=\"size-4 opacity-60\" />\n  } else if (fileType.startsWith('image/')) {\n    return <ImageIcon className=\"size-4 opacity-60\" />\n  }\n  return <FileIcon className=\"size-4 opacity-60\" />\n}\n\nexport default function Component() {\n  const maxSize = 100 * 1024 * 1024 // 10MB default\n  const maxFiles = 10\n\n  const [\n    { files, isDragging, errors },\n    {\n      handleDragEnter,\n      handleDragLeave,\n      handleDragOver,\n      handleDrop,\n      openFileDialog,\n      removeFile,\n      clearFiles,\n      getInputProps,\n    },\n  ] = useFileUpload({\n    multiple: true,\n    maxFiles,\n    maxSize,\n    initialFiles,\n  })\n\n  return (\n    <div className=\"flex flex-col gap-2\">\n      {/* Drop area */}\n      <div\n        role=\"button\"\n        onClick={openFileDialog}\n        onDragEnter={handleDragEnter}\n        onDragLeave={handleDragLeave}\n        onDragOver={handleDragOver}\n        onDrop={handleDrop}\n        data-dragging={isDragging || undefined}\n        className=\"border-input hover:bg-accent/50 data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 flex min-h-40 flex-col items-center justify-center rounded-xl border border-dashed p-4 transition-colors has-disabled:pointer-events-none has-disabled:opacity-50 has-[input:focus]:ring-[3px]\"\n      >\n        <input {...getInputProps()} className=\"sr-only\" aria-label=\"Upload files\" />\n\n        <div className=\"flex flex-col items-center justify-center text-center\">\n          <div\n            className=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\"\n            aria-hidden=\"true\"\n          >\n            <FileUpIcon className=\"size-4 opacity-60\" />\n          </div>\n          <p className=\"mb-1.5 text-sm font-medium\">Upload files</p>\n          <p className=\"text-muted-foreground mb-2 text-xs\">Drag & drop or click to browse</p>\n          <div className=\"text-muted-foreground/70 flex flex-wrap justify-center gap-1 text-xs\">\n            <span>All files</span>\n            <span>∙</span>\n            <span>Max {maxFiles} files</span>\n            <span>∙</span>\n            <span>Up to {formatBytes(maxSize)}</span>\n          </div>\n        </div>\n      </div>\n\n      {errors.length > 0 && (\n        <div className=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\">\n          <AlertCircleIcon className=\"size-3 shrink-0\" />\n          <span>{errors[0]}</span>\n        </div>\n      )}\n\n      {/* File list */}\n      {files.length > 0 && (\n        <div className=\"space-y-2\">\n          {files.map((file) => (\n            <div\n              key={file.id}\n              className=\"bg-background flex items-center justify-between gap-2 rounded-lg border p-2 pe-3\"\n            >\n              <div className=\"flex items-center gap-3 overflow-hidden\">\n                <div className=\"flex aspect-square size-10 shrink-0 items-center justify-center rounded border\">\n                  {getFileIcon(file)}\n                </div>\n                <div className=\"flex min-w-0 flex-col gap-0.5\">\n                  <p className=\"truncate text-[13px] font-medium\">\n                    {file.file instanceof File ? file.file.name : file.file.name}\n                  </p>\n                  <p className=\"text-muted-foreground text-xs\">\n                    {formatBytes(file.file instanceof File ? file.file.size : file.file.size)}\n                  </p>\n                </div>\n              </div>\n\n              <Button\n                size=\"icon\"\n                variant=\"ghost\"\n                className=\"text-muted-foreground/80 hover:text-foreground -me-2 size-8 hover:bg-transparent\"\n                onClick={() => removeFile(file.id)}\n                aria-label=\"Remove file\"\n              >\n                <XIcon className=\"size-4\" aria-hidden=\"true\" />\n              </Button>\n            </div>\n          ))}\n\n          {/* Remove all files button */}\n          {files.length > 1 && (\n            <div>\n              <Button size=\"sm\" variant=\"outline\" onClick={clearFiles}>\n                Remove all files\n              </Button>\n            </div>\n          )}\n        </div>\n      )}\n\n      <p\n        aria-live=\"polite\"\n        role=\"region\"\n        className=\"text-muted-foreground mt-2 text-center text-xs\"\n      >\n        Multiple files uploader w/ list ∙{' '}\n        <a\n          href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\"\n          className=\"hover:text-foreground underline\"\n        >\n          API\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/hooks/use-file-upload.ts",
          "type": "registry:hook",
          "target": "components/ui/file-upload-09/use-file-upload.ts",
          "content": "'use client'\n\nimport type React from 'react'\nimport {\n  useCallback,\n  useRef,\n  useState,\n  type ChangeEvent,\n  type DragEvent,\n  type InputHTMLAttributes,\n} from 'react'\n\nexport type FileMetadata = {\n  name: string\n  size: number\n  type: string\n  url: string\n  id: string\n}\n\nexport type FileWithPreview = {\n  file: File | FileMetadata\n  id: string\n  preview?: string\n}\n\nexport type FileUploadOptions = {\n  maxFiles?: number // Only used when multiple is true, defaults to Infinity\n  maxSize?: number // in bytes\n  accept?: string\n  multiple?: boolean // Defaults to false\n  initialFiles?: FileMetadata[]\n  onFilesChange?: (files: FileWithPreview[]) => void // Callback when files change\n  onFilesAdded?: (addedFiles: FileWithPreview[]) => void // Callback when new files are added\n}\n\nexport type FileUploadState = {\n  files: FileWithPreview[]\n  isDragging: boolean\n  errors: string[]\n}\n\nexport type FileUploadActions = {\n  addFiles: (files: FileList | File[]) => void\n  removeFile: (id: string) => void\n  clearFiles: () => void\n  clearErrors: () => void\n  handleDragEnter: (e: DragEvent<HTMLElement>) => void\n  handleDragLeave: (e: DragEvent<HTMLElement>) => void\n  handleDragOver: (e: DragEvent<HTMLElement>) => void\n  handleDrop: (e: DragEvent<HTMLElement>) => void\n  handleFileChange: (e: ChangeEvent<HTMLInputElement>) => void\n  openFileDialog: () => void\n  getInputProps: (\n    props?: InputHTMLAttributes<HTMLInputElement>\n  ) => InputHTMLAttributes<HTMLInputElement> & {\n    ref: React.Ref<HTMLInputElement>\n  }\n}\n\nexport const useFileUpload = (\n  options: FileUploadOptions = {}\n): [FileUploadState, FileUploadActions] => {\n  const {\n    maxFiles = Infinity,\n    maxSize = Infinity,\n    accept = '*',\n    multiple = false,\n    initialFiles = [],\n    onFilesChange,\n    onFilesAdded,\n  } = options\n\n  const [state, setState] = useState<FileUploadState>({\n    files: initialFiles.map((file) => ({\n      file,\n      id: file.id,\n      preview: file.url,\n    })),\n    isDragging: false,\n    errors: [],\n  })\n\n  const inputRef = useRef<HTMLInputElement>(null)\n\n  const validateFile = useCallback(\n    (file: File | FileMetadata): string | null => {\n      if (file instanceof File) {\n        if (file.size > maxSize) {\n          return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n        }\n      } else {\n        if (file.size > maxSize) {\n          return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n        }\n      }\n\n      if (accept !== '*') {\n        const acceptedTypes = accept.split(',').map((type) => type.trim())\n        const fileType = file instanceof File ? file.type || '' : file.type\n        const fileExtension = `.${file instanceof File ? file.name.split('.').pop() : file.name.split('.').pop()}`\n\n        const isAccepted = acceptedTypes.some((type) => {\n          if (type.startsWith('.')) {\n            return fileExtension.toLowerCase() === type.toLowerCase()\n          }\n          if (type.endsWith('/*')) {\n            const baseType = type.split('/')[0]\n            return fileType.startsWith(`${baseType}/`)\n          }\n          return fileType === type\n        })\n\n        if (!isAccepted) {\n          return `File \"${file instanceof File ? file.name : file.name}\" is not an accepted file type.`\n        }\n      }\n\n      return null\n    },\n    [accept, maxSize]\n  )\n\n  const createPreview = useCallback((file: File | FileMetadata): string | undefined => {\n    if (file instanceof File) {\n      return URL.createObjectURL(file)\n    }\n    return file.url\n  }, [])\n\n  const generateUniqueId = useCallback((file: File | FileMetadata): string => {\n    if (file instanceof File) {\n      return `${file.name}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`\n    }\n    return file.id\n  }, [])\n\n  const clearFiles = useCallback(() => {\n    setState((prev) => {\n      // Clean up object URLs\n      prev.files.forEach((file) => {\n        if (file.preview && file.file instanceof File && file.file.type.startsWith('image/')) {\n          URL.revokeObjectURL(file.preview)\n        }\n      })\n\n      if (inputRef.current) {\n        inputRef.current.value = ''\n      }\n\n      const newState = {\n        ...prev,\n        files: [],\n        errors: [],\n      }\n\n      onFilesChange?.(newState.files)\n      return newState\n    })\n  }, [onFilesChange])\n\n  const addFiles = useCallback(\n    (newFiles: FileList | File[]) => {\n      if (!newFiles || newFiles.length === 0) return\n\n      const newFilesArray = Array.from(newFiles)\n      const errors: string[] = []\n\n      // Clear existing errors when new files are uploaded\n      setState((prev) => ({ ...prev, errors: [] }))\n\n      // In single file mode, clear existing files first\n      if (!multiple) {\n        clearFiles()\n      }\n\n      // Check if adding these files would exceed maxFiles (only in multiple mode)\n      if (\n        multiple &&\n        maxFiles !== Infinity &&\n        state.files.length + newFilesArray.length > maxFiles\n      ) {\n        errors.push(`You can only upload a maximum of ${maxFiles} files.`)\n        setState((prev) => ({ ...prev, errors }))\n        return\n      }\n\n      const validFiles: FileWithPreview[] = []\n\n      newFilesArray.forEach((file) => {\n        // Only check for duplicates if multiple files are allowed\n        if (multiple) {\n          const isDuplicate = state.files.some(\n            (existingFile) =>\n              existingFile.file.name === file.name && existingFile.file.size === file.size\n          )\n\n          // Skip duplicate files silently\n          if (isDuplicate) {\n            return\n          }\n        }\n\n        // Check file size\n        if (file.size > maxSize) {\n          errors.push(\n            multiple\n              ? `Some files exceed the maximum size of ${formatBytes(maxSize)}.`\n              : `File exceeds the maximum size of ${formatBytes(maxSize)}.`\n          )\n          return\n        }\n\n        const error = validateFile(file)\n        if (error) {\n          errors.push(error)\n        } else {\n          validFiles.push({\n            file,\n            id: generateUniqueId(file),\n            preview: createPreview(file),\n          })\n        }\n      })\n\n      // Only update state if we have valid files to add\n      if (validFiles.length > 0) {\n        // Call the onFilesAdded callback with the newly added valid files\n        onFilesAdded?.(validFiles)\n\n        setState((prev) => {\n          const newFiles = !multiple ? validFiles : [...prev.files, ...validFiles]\n          onFilesChange?.(newFiles)\n          return {\n            ...prev,\n            files: newFiles,\n            errors,\n          }\n        })\n      } else if (errors.length > 0) {\n        setState((prev) => ({\n          ...prev,\n          errors,\n        }))\n      }\n\n      // Reset input value after handling files\n      if (inputRef.current) {\n        inputRef.current.value = ''\n      }\n    },\n    [\n      state.files,\n      maxFiles,\n      multiple,\n      maxSize,\n      validateFile,\n      createPreview,\n      generateUniqueId,\n      clearFiles,\n      onFilesChange,\n      onFilesAdded,\n    ]\n  )\n\n  const removeFile = useCallback(\n    (id: string) => {\n      setState((prev) => {\n        const fileToRemove = prev.files.find((file) => file.id === id)\n        if (\n          fileToRemove &&\n          fileToRemove.preview &&\n          fileToRemove.file instanceof File &&\n          fileToRemove.file.type.startsWith('image/')\n        ) {\n          URL.revokeObjectURL(fileToRemove.preview)\n        }\n\n        const newFiles = prev.files.filter((file) => file.id !== id)\n        onFilesChange?.(newFiles)\n\n        return {\n          ...prev,\n          files: newFiles,\n          errors: [],\n        }\n      })\n    },\n    [onFilesChange]\n  )\n\n  const clearErrors = useCallback(() => {\n    setState((prev) => ({\n      ...prev,\n      errors: [],\n    }))\n  }, [])\n\n  const handleDragEnter = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n    setState((prev) => ({ ...prev, isDragging: true }))\n  }, [])\n\n  const handleDragLeave = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n\n    if (e.currentTarget.contains(e.relatedTarget as Node)) {\n      return\n    }\n\n    setState((prev) => ({ ...prev, isDragging: false }))\n  }, [])\n\n  const handleDragOver = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n  }, [])\n\n  const handleDrop = useCallback(\n    (e: DragEvent<HTMLElement>) => {\n      e.preventDefault()\n      e.stopPropagation()\n      setState((prev) => ({ ...prev, isDragging: false }))\n\n      // Don't process files if the input is disabled\n      if (inputRef.current?.disabled) {\n        return\n      }\n\n      if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n        // In single file mode, only use the first file\n        if (!multiple) {\n          const file = e.dataTransfer.files[0]\n          addFiles([file])\n        } else {\n          addFiles(e.dataTransfer.files)\n        }\n      }\n    },\n    [addFiles, multiple]\n  )\n\n  const handleFileChange = useCallback(\n    (e: ChangeEvent<HTMLInputElement>) => {\n      if (e.target.files && e.target.files.length > 0) {\n        addFiles(e.target.files)\n      }\n    },\n    [addFiles]\n  )\n\n  const openFileDialog = useCallback(() => {\n    if (inputRef.current) {\n      inputRef.current.click()\n    }\n  }, [])\n\n  const getInputProps = useCallback(\n    (props: InputHTMLAttributes<HTMLInputElement> = {}) => {\n      return {\n        ...props,\n        type: 'file' as const,\n        onChange: handleFileChange,\n        accept: props.accept || accept,\n        multiple: props.multiple !== undefined ? props.multiple : multiple,\n        ref: inputRef,\n      }\n    },\n    [accept, multiple, handleFileChange]\n  )\n\n  return [\n    state,\n    {\n      addFiles,\n      removeFile,\n      clearFiles,\n      clearErrors,\n      handleDragEnter,\n      handleDragLeave,\n      handleDragOver,\n      handleDrop,\n      handleFileChange,\n      openFileDialog,\n      getInputProps,\n    },\n  ]\n}\n\n// Helper function to format bytes to human-readable format\nexport const formatBytes = (bytes: number, decimals = 2): string => {\n  if (bytes === 0) return '0 Bytes'\n\n  const k = 1024\n  const dm = decimals < 0 ? 0 : decimals\n  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']\n\n  const i = Math.floor(Math.log(bytes) / Math.log(k))\n\n  return Number.parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + sizes[i]\n}\n"
        },
        {
          "path": "registry/default/components/file-upload/file-upload-09.vue",
          "target": "components/ui/file-upload-09.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { AlertCircleIcon, FileArchiveIcon, FileIcon, FileSpreadsheetIcon, FileTextIcon, FileUpIcon, HeadphonesIcon, ImageIcon, VideoIcon, XIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { formatBytes, useFileUpload } from '@/registry/default/hooks/use-file-upload-vue';\n\nconst initialFiles = [\n  {\n    name: 'document.pdf',\n    size: 528737,\n    type: 'application/pdf',\n    url: 'https://example.com/document.pdf',\n    id: 'document.pdf-1744638436563-8u5xuls',\n  },\n  {\n    name: 'intro.zip',\n    size: 252873,\n    type: 'application/zip',\n    url: 'https://example.com/intro.zip',\n    id: 'intro.zip-1744638436563-8u5xuls',\n  },\n  {\n    name: 'conclusion.xlsx',\n    size: 352873,\n    type: 'application/xlsx',\n    url: 'https://example.com/conclusion.xlsx',\n    id: 'conclusion.xlsx-1744638436563-8u5xuls',\n  },\n];\n\nconst maxSize = 100 * 1024 * 1024;\nconst maxFiles = 10;\n\nconst [\n  { files, isDragging, errors },\n  {\n    handleDragEnter,\n    handleDragLeave,\n    handleDragOver,\n    handleDrop,\n    openFileDialog,\n    removeFile,\n    clearFiles,\n  },\n] = useFileUpload({\n  multiple: true,\n  maxFiles,\n  maxSize,\n  initialFiles,\n});\n\nfunction getFileIcon(file: { file: File | { type: string; name: string } }) {\n  const fileType = file.file.type;\n  const fileName = file.file.name;\n\n  if (\n    fileType.includes('pdf') ||\n    fileType.includes('word') ||\n    fileName.endsWith('.pdf') ||\n    fileName.endsWith('.doc') ||\n    fileName.endsWith('.docx')\n  ) {\n    return FileTextIcon;\n  }\n\n  if (\n    fileType.includes('zip') ||\n    fileType.includes('archive') ||\n    fileName.endsWith('.zip') ||\n    fileName.endsWith('.rar')\n  ) {\n    return FileArchiveIcon;\n  }\n\n  if (\n    fileType.includes('excel') ||\n    fileName.endsWith('.xls') ||\n    fileName.endsWith('.xlsx')\n  ) {\n    return FileSpreadsheetIcon;\n  }\n\n  if (fileType.includes('video/')) return VideoIcon;\n  if (fileType.includes('audio/')) return HeadphonesIcon;\n  if (fileType.startsWith('image/')) return ImageIcon;\n  return FileIcon;\n}\n</script>\n\n<template>\n  <div class=\"flex flex-col gap-2\"><div role=\"button\" @click=\"openFileDialog\" @dragenter=\"handleDragEnter\" @dragleave=\"handleDragLeave\" @dragover=\"handleDragOver\" @drop=\"handleDrop\" :data-dragging=\"isDragging || undefined\" class=\"border-input hover:bg-accent/50 data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 flex min-h-40 flex-col items-center justify-center rounded-xl border border-dashed p-4 transition-colors has-disabled:pointer-events-none has-disabled:opacity-50 has-[input:focus]:ring-[3px]\"><input class=\"sr-only\" aria-label=\"Upload files\" /><div class=\"flex flex-col items-center justify-center text-center\"><div class=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><FileUpIcon class=\"size-4 opacity-60\" /></div><p class=\"mb-1.5 text-sm font-medium\">Upload files</p><p class=\"text-muted-foreground mb-2 text-xs\">Drag & drop or click to browse</p><div class=\"text-muted-foreground/70 flex flex-wrap justify-center gap-1 text-xs\"><span>All files</span><span>∙</span><span>Max {{ maxFiles }}files</span><span>∙</span><span>Up to {{ formatBytes(maxSize) }}</span></div></div></div><div v-if=\"errors.length > 0\" class=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\"><AlertCircleIcon class=\"size-3 shrink-0\" /><span>{{ errors[0] }}</span></div><div v-if=\"files.length > 0\" class=\"space-y-2\"><div v-for=\"(file, index) in files\" :key=\"file.id\" class=\"bg-background flex items-center justify-between gap-2 rounded-lg border p-2 pe-3\"><div class=\"flex items-center gap-3 overflow-hidden\"><div class=\"flex aspect-square size-10 shrink-0 items-center justify-center rounded border\"><component :is=\"getFileIcon(file)\" class=\"size-4 opacity-60\" /></div><div class=\"flex min-w-0 flex-col gap-0.5\"><p class=\"truncate text-[13px] font-medium\">{{ file.file.name }}</p><p class=\"text-muted-foreground text-xs\">{{ formatBytes(file.file.size) }}</p></div></div><Button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground/80 hover:text-foreground -me-2 size-8 hover:bg-transparent\" @click=\"removeFile(file.id)\" aria-label=\"Remove file\"><XIcon class=\"size-4\" aria-hidden=\"true\" /></Button></div><div v-if=\"files.length > 1\"><Button size=\"sm\" variant=\"outline\" @click=\"clearFiles\">Remove all files\n              </Button></div></div><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-center text-xs\">Multiple files uploader w/ list ∙{{ ' ' }}<a href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\" class=\"hover:text-foreground underline\">API\n        </a></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/file-upload/file-upload-09.html",
          "target": "components/ui/file-upload-09.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex flex-col gap-2\"><div role=\"button\" on-click=\"${openFileDialog}\" ondragenter=\"${handleDragEnter}\" ondragleave=\"${handleDragLeave}\" ondragover=\"${handleDragOver}\" ondrop=\"${handleDrop}\" data-dragging=\"${isDragging || undefined}\" class=\"border-input hover:bg-accent/50 data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 flex min-h-40 flex-col items-center justify-center rounded-xl border border-dashed p-4 transition-colors has-disabled:pointer-events-none has-disabled:opacity-50 has-[input:focus]:ring-[3px]\"><input class=\"sr-only\" aria-label=\"Upload files\" /><div class=\"flex flex-col items-center justify-center text-center\"><div class=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><FileUpIcon class=\"size-4 opacity-60\" /></div><p class=\"mb-1.5 text-sm font-medium\">Upload files</p><p class=\"text-muted-foreground mb-2 text-xs\">Drag & drop or click to browse</p><div class=\"text-muted-foreground/70 flex flex-wrap justify-center gap-1 text-xs\"><span>All files</span><span>∙</span><span>Max ${maxFiles}files</span><span>∙</span><span>Up to ${formatBytes(maxSize)}</span></div></div></div><!-- if errors.length > 0 -->\n<div class=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\"><AlertCircleIcon class=\"size-3 shrink-0\" /><span>${errors[0]}</span></div>\n<!-- endif --><!-- if files.length > 0 -->\n<div class=\"space-y-2\"><!-- Loop files -->\n<div key=\"${file.id}\" class=\"bg-background flex items-center justify-between gap-2 rounded-lg border p-2 pe-3\"><div class=\"flex items-center gap-3 overflow-hidden\"><div class=\"flex aspect-square size-10 shrink-0 items-center justify-center rounded border\">${getFileIcon(file)}</div><div class=\"flex min-w-0 flex-col gap-0.5\"><p class=\"truncate text-[13px] font-medium\"><!-- if file.file instanceof File -->\n${file.file.name}\n<!-- else -->\n${file.file.name}\n<!-- endif --></p><p class=\"text-muted-foreground text-xs\">${formatBytes(file.file instanceof File ? file.file.size : file.file.size)}</p></div></div><Button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground/80 hover:text-foreground -me-2 size-8 hover:bg-transparent\" on-click=\"${() => removeFile(file.id)}\" aria-label=\"Remove file\"><XIcon class=\"size-4\" aria-hidden=\"true\" /></Button></div>\n<!-- End Loop --><!-- if files.length > 1 -->\n<div><Button size=\"sm\" variant=\"outline\" on-click=\"${clearFiles}\">Remove all files\n              </Button></div>\n<!-- endif --></div>\n<!-- endif --><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-center text-xs\">Multiple files uploader w/ list ∙${' '}<a href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\" class=\"hover:text-foreground underline\">API\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/file-upload/file-upload-09.wxml",
          "target": "components/ui/file-upload-09/file-upload-09.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex flex-col gap-2\"><view role=\"button\" bindtap=\"openFileDialog\" ondragenter=\"{{handleDragEnter}}\" ondragleave=\"{{handleDragLeave}}\" ondragover=\"{{handleDragOver}}\" ondrop=\"{{handleDrop}}\" data-dragging=\"{{isDragging || undefined}}\" class=\"border-input hover:bg-accent/50 data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 flex min-h-40 flex-col items-center justify-center rounded-xl border border-dashed p-4 transition-colors has-disabled:pointer-events-none has-disabled:opacity-50 has-[input:focus]:ring-[3px]\"><input class=\"sr-only\" aria-label=\"Upload files\" /><view class=\"flex flex-col items-center justify-center text-center\"><view class=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><fileupicon class=\"size-4 opacity-60\" /></view><text class=\"mb-1.5 text-sm font-medium\">Upload files</text><text class=\"text-muted-foreground mb-2 text-xs\">Drag & drop or click to browse</text><view class=\"text-muted-foreground/70 flex flex-wrap justify-center gap-1 text-xs\"><text>All files</text><text>∙</text><text>Max {{ maxFiles }}files</text><text>∙</text><text>Up to {{ formatBytes(maxSize) }}</text></view></view></view><view wx:if=\"{{errors.length > 0}}\" class=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\"><alertcircleicon class=\"size-3 shrink-0\" /><text>{{ errors[0] }}</text></view><view wx:if=\"{{files.length > 0}}\" class=\"space-y-2\"><view wx:for=\"{{files}}\" wx:for-item=\"file\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{file.id}}\" class=\"bg-background flex items-center justify-between gap-2 rounded-lg border p-2 pe-3\"><view class=\"flex items-center gap-3 overflow-hidden\"><view class=\"flex aspect-square size-10 shrink-0 items-center justify-center rounded border\">{{ getFileIcon(file) }}</view><view class=\"flex min-w-0 flex-col gap-0.5\"><text class=\"truncate text-[13px] font-medium\"><block wx:if=\"{{file.file instanceof File}}\">\n{{ file.file.name }}\n</block>\n<block wx:else>\n{{ file.file.name }}\n</block></text><text class=\"text-muted-foreground text-xs\">{{ formatBytes(file.file instanceof File ? file.file.size : file.file.size) }}</text></view></view><button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground/80 hover:text-foreground -me-2 size-8 hover:bg-transparent\" bindtap=\"removeFile(file.id)\" aria-label=\"Remove file\"><xicon class=\"size-4\" aria-hidden=\"true\" /></button></view><view wx:if=\"{{files.length > 1}}\"><button size=\"sm\" variant=\"outline\" bindtap=\"clearFiles\">Remove all files\n              </button></view></view><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-center text-xs\">Multiple files uploader w/ list ∙{{ ' ' }}<a href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\" class=\"hover:text-foreground underline\">API\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "upload",
          "file",
          "image",
          "drag and drop"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "file-upload-09",
          "group": "file-upload",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "file-upload-09",
              "path": "registry/default/components/file-upload/file-upload-09.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "file-upload-09",
              "path": "registry/default/components/file-upload/file-upload-09.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "file-upload-09",
              "path": "registry/default/components/file-upload/file-upload-09.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "file-upload-09",
              "path": "registry/default/components/file-upload/file-upload-09.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "file-upload",
        "title": "File Upload · Upload files"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "file-upload"
      ]
    },
    {
      "name": "file-upload-10",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/file-upload/file-upload-10.tsx",
          "type": "registry:component",
          "target": "components/ui/file-upload-10.tsx",
          "content": "'use client'\n\nimport type React from 'react'\nimport { Button } from '@timui/react'\nimport {\n  AlertCircleIcon,\n  FileArchiveIcon,\n  FileIcon,\n  FileSpreadsheetIcon,\n  FileTextIcon,\n  HeadphonesIcon,\n  ImageIcon,\n  Trash2Icon,\n  UploadIcon,\n  VideoIcon,\n  XIcon,\n} from 'lucide-react'\n\nimport { formatBytes, useFileUpload } from '@/registry/default/hooks/use-file-upload'\n\nconst getFileIcon = (file: { file: File | { type: string; name: string } }) => {\n  const fileType = file.file instanceof File ? file.file.type : file.file.type\n  const fileName = file.file instanceof File ? file.file.name : file.file.name\n\n  if (\n    fileType.includes('pdf') ||\n    fileName.endsWith('.pdf') ||\n    fileType.includes('word') ||\n    fileName.endsWith('.doc') ||\n    fileName.endsWith('.docx')\n  ) {\n    return <FileTextIcon className=\"size-4 opacity-60\" />\n  } else if (\n    fileType.includes('zip') ||\n    fileType.includes('archive') ||\n    fileName.endsWith('.zip') ||\n    fileName.endsWith('.rar')\n  ) {\n    return <FileArchiveIcon className=\"size-4 opacity-60\" />\n  } else if (\n    fileType.includes('excel') ||\n    fileName.endsWith('.xls') ||\n    fileName.endsWith('.xlsx')\n  ) {\n    return <FileSpreadsheetIcon className=\"size-4 opacity-60\" />\n  } else if (fileType.includes('video/')) {\n    return <VideoIcon className=\"size-4 opacity-60\" />\n  } else if (fileType.includes('audio/')) {\n    return <HeadphonesIcon className=\"size-4 opacity-60\" />\n  } else if (fileType.startsWith('image/')) {\n    return <ImageIcon className=\"size-4 opacity-60\" />\n  }\n  return <FileIcon className=\"size-4 opacity-60\" />\n}\n\n// Create some dummy initial files\nconst initialFiles = [\n  {\n    name: 'document.pdf',\n    size: 528737,\n    type: 'application/pdf',\n    url: 'https://example.com/document.pdf',\n    id: 'document.pdf-1744638436563-8u5xuls',\n  },\n  {\n    name: 'intro.zip',\n    size: 252873,\n    type: 'application/zip',\n    url: 'https://example.com/intro.zip',\n    id: 'intro.zip-1744638436563-8u5xuls',\n  },\n  {\n    name: 'conclusion.xlsx',\n    size: 352873,\n    type: 'application/xlsx',\n    url: 'https://example.com/conclusion.xlsx',\n    id: 'conclusion.xlsx-1744638436563-8u5xuls',\n  },\n]\n\nexport default function Component() {\n  const maxSize = 10 * 1024 * 1024 // 10MB default\n  const maxFiles = 10\n\n  const [\n    { files, isDragging, errors },\n    {\n      handleDragEnter,\n      handleDragLeave,\n      handleDragOver,\n      handleDrop,\n      openFileDialog,\n      removeFile,\n      clearFiles,\n      getInputProps,\n    },\n  ] = useFileUpload({\n    multiple: true,\n    maxFiles,\n    maxSize,\n    initialFiles,\n  })\n\n  return (\n    <div className=\"flex flex-col gap-2\">\n      {/* Drop area */}\n      <div\n        onDragEnter={handleDragEnter}\n        onDragLeave={handleDragLeave}\n        onDragOver={handleDragOver}\n        onDrop={handleDrop}\n        data-dragging={isDragging || undefined}\n        data-files={files.length > 0 || undefined}\n        className=\"border-input data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 flex min-h-56 flex-col items-center rounded-xl border border-dashed p-4 transition-colors not-data-[files]:justify-center has-[input:focus]:ring-[3px]\"\n      >\n        <input {...getInputProps()} className=\"sr-only\" aria-label=\"Upload files\" />\n\n        {files.length > 0 ? (\n          <div className=\"flex w-full flex-col gap-3\">\n            <div className=\"flex items-center justify-between gap-2\">\n              <h3 className=\"truncate text-sm font-medium\">Uploaded Files ({files.length})</h3>\n              <Button variant=\"outline\" size=\"sm\" onClick={clearFiles}>\n                <Trash2Icon className=\"-ms-0.5 size-3.5 opacity-60\" aria-hidden=\"true\" />\n                Remove all\n              </Button>\n            </div>\n            <div className=\"w-full space-y-2\">\n              {files.map((file) => (\n                <div\n                  key={file.id}\n                  className=\"bg-background flex items-center justify-between gap-2 rounded-lg border p-2 pe-3\"\n                >\n                  <div className=\"flex items-center gap-3 overflow-hidden\">\n                    <div className=\"flex aspect-square size-10 shrink-0 items-center justify-center rounded border\">\n                      {getFileIcon(file)}\n                    </div>\n                    <div className=\"flex min-w-0 flex-col gap-0.5\">\n                      <p className=\"truncate text-[13px] font-medium\">\n                        {file.file instanceof File ? file.file.name : file.file.name}\n                      </p>\n                      <p className=\"text-muted-foreground text-xs\">\n                        {formatBytes(file.file instanceof File ? file.file.size : file.file.size)}\n                      </p>\n                    </div>\n                  </div>\n\n                  <Button\n                    size=\"icon\"\n                    variant=\"ghost\"\n                    className=\"text-muted-foreground/80 hover:text-foreground -me-2 size-8 hover:bg-transparent\"\n                    onClick={() => removeFile(file.id)}\n                    aria-label=\"Remove file\"\n                  >\n                    <XIcon className=\"size-4\" aria-hidden=\"true\" />\n                  </Button>\n                </div>\n              ))}\n\n              {files.length < maxFiles && (\n                <Button variant=\"outline\" className=\"mt-2 w-full\" onClick={openFileDialog}>\n                  <UploadIcon className=\"-ms-1 opacity-60\" aria-hidden=\"true\" />\n                  Add more\n                </Button>\n              )}\n            </div>\n          </div>\n        ) : (\n          <div className=\"flex flex-col items-center justify-center text-center\">\n            <div\n              className=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\"\n              aria-hidden=\"true\"\n            >\n              <FileIcon className=\"size-4 opacity-60\" />\n            </div>\n            <p className=\"mb-1.5 text-sm font-medium\">Upload files</p>\n            <p className=\"text-muted-foreground text-xs\">\n              Max {maxFiles} files ∙ Up to {maxSize}MB\n            </p>\n            <Button variant=\"outline\" className=\"mt-4\" onClick={openFileDialog}>\n              <UploadIcon className=\"-ms-1 opacity-60\" aria-hidden=\"true\" />\n              Select files\n            </Button>\n          </div>\n        )}\n      </div>\n\n      {errors.length > 0 && (\n        <div className=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\">\n          <AlertCircleIcon className=\"size-3 shrink-0\" />\n          <span>{errors[0]}</span>\n        </div>\n      )}\n\n      <p\n        aria-live=\"polite\"\n        role=\"region\"\n        className=\"text-muted-foreground mt-2 text-center text-xs\"\n      >\n        Multiple files uploader w/ list inside ∙{' '}\n        <a\n          href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\"\n          className=\"hover:text-foreground underline\"\n        >\n          API\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/hooks/use-file-upload.ts",
          "type": "registry:hook",
          "target": "components/ui/file-upload-10/use-file-upload.ts",
          "content": "'use client'\n\nimport type React from 'react'\nimport {\n  useCallback,\n  useRef,\n  useState,\n  type ChangeEvent,\n  type DragEvent,\n  type InputHTMLAttributes,\n} from 'react'\n\nexport type FileMetadata = {\n  name: string\n  size: number\n  type: string\n  url: string\n  id: string\n}\n\nexport type FileWithPreview = {\n  file: File | FileMetadata\n  id: string\n  preview?: string\n}\n\nexport type FileUploadOptions = {\n  maxFiles?: number // Only used when multiple is true, defaults to Infinity\n  maxSize?: number // in bytes\n  accept?: string\n  multiple?: boolean // Defaults to false\n  initialFiles?: FileMetadata[]\n  onFilesChange?: (files: FileWithPreview[]) => void // Callback when files change\n  onFilesAdded?: (addedFiles: FileWithPreview[]) => void // Callback when new files are added\n}\n\nexport type FileUploadState = {\n  files: FileWithPreview[]\n  isDragging: boolean\n  errors: string[]\n}\n\nexport type FileUploadActions = {\n  addFiles: (files: FileList | File[]) => void\n  removeFile: (id: string) => void\n  clearFiles: () => void\n  clearErrors: () => void\n  handleDragEnter: (e: DragEvent<HTMLElement>) => void\n  handleDragLeave: (e: DragEvent<HTMLElement>) => void\n  handleDragOver: (e: DragEvent<HTMLElement>) => void\n  handleDrop: (e: DragEvent<HTMLElement>) => void\n  handleFileChange: (e: ChangeEvent<HTMLInputElement>) => void\n  openFileDialog: () => void\n  getInputProps: (\n    props?: InputHTMLAttributes<HTMLInputElement>\n  ) => InputHTMLAttributes<HTMLInputElement> & {\n    ref: React.Ref<HTMLInputElement>\n  }\n}\n\nexport const useFileUpload = (\n  options: FileUploadOptions = {}\n): [FileUploadState, FileUploadActions] => {\n  const {\n    maxFiles = Infinity,\n    maxSize = Infinity,\n    accept = '*',\n    multiple = false,\n    initialFiles = [],\n    onFilesChange,\n    onFilesAdded,\n  } = options\n\n  const [state, setState] = useState<FileUploadState>({\n    files: initialFiles.map((file) => ({\n      file,\n      id: file.id,\n      preview: file.url,\n    })),\n    isDragging: false,\n    errors: [],\n  })\n\n  const inputRef = useRef<HTMLInputElement>(null)\n\n  const validateFile = useCallback(\n    (file: File | FileMetadata): string | null => {\n      if (file instanceof File) {\n        if (file.size > maxSize) {\n          return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n        }\n      } else {\n        if (file.size > maxSize) {\n          return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n        }\n      }\n\n      if (accept !== '*') {\n        const acceptedTypes = accept.split(',').map((type) => type.trim())\n        const fileType = file instanceof File ? file.type || '' : file.type\n        const fileExtension = `.${file instanceof File ? file.name.split('.').pop() : file.name.split('.').pop()}`\n\n        const isAccepted = acceptedTypes.some((type) => {\n          if (type.startsWith('.')) {\n            return fileExtension.toLowerCase() === type.toLowerCase()\n          }\n          if (type.endsWith('/*')) {\n            const baseType = type.split('/')[0]\n            return fileType.startsWith(`${baseType}/`)\n          }\n          return fileType === type\n        })\n\n        if (!isAccepted) {\n          return `File \"${file instanceof File ? file.name : file.name}\" is not an accepted file type.`\n        }\n      }\n\n      return null\n    },\n    [accept, maxSize]\n  )\n\n  const createPreview = useCallback((file: File | FileMetadata): string | undefined => {\n    if (file instanceof File) {\n      return URL.createObjectURL(file)\n    }\n    return file.url\n  }, [])\n\n  const generateUniqueId = useCallback((file: File | FileMetadata): string => {\n    if (file instanceof File) {\n      return `${file.name}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`\n    }\n    return file.id\n  }, [])\n\n  const clearFiles = useCallback(() => {\n    setState((prev) => {\n      // Clean up object URLs\n      prev.files.forEach((file) => {\n        if (file.preview && file.file instanceof File && file.file.type.startsWith('image/')) {\n          URL.revokeObjectURL(file.preview)\n        }\n      })\n\n      if (inputRef.current) {\n        inputRef.current.value = ''\n      }\n\n      const newState = {\n        ...prev,\n        files: [],\n        errors: [],\n      }\n\n      onFilesChange?.(newState.files)\n      return newState\n    })\n  }, [onFilesChange])\n\n  const addFiles = useCallback(\n    (newFiles: FileList | File[]) => {\n      if (!newFiles || newFiles.length === 0) return\n\n      const newFilesArray = Array.from(newFiles)\n      const errors: string[] = []\n\n      // Clear existing errors when new files are uploaded\n      setState((prev) => ({ ...prev, errors: [] }))\n\n      // In single file mode, clear existing files first\n      if (!multiple) {\n        clearFiles()\n      }\n\n      // Check if adding these files would exceed maxFiles (only in multiple mode)\n      if (\n        multiple &&\n        maxFiles !== Infinity &&\n        state.files.length + newFilesArray.length > maxFiles\n      ) {\n        errors.push(`You can only upload a maximum of ${maxFiles} files.`)\n        setState((prev) => ({ ...prev, errors }))\n        return\n      }\n\n      const validFiles: FileWithPreview[] = []\n\n      newFilesArray.forEach((file) => {\n        // Only check for duplicates if multiple files are allowed\n        if (multiple) {\n          const isDuplicate = state.files.some(\n            (existingFile) =>\n              existingFile.file.name === file.name && existingFile.file.size === file.size\n          )\n\n          // Skip duplicate files silently\n          if (isDuplicate) {\n            return\n          }\n        }\n\n        // Check file size\n        if (file.size > maxSize) {\n          errors.push(\n            multiple\n              ? `Some files exceed the maximum size of ${formatBytes(maxSize)}.`\n              : `File exceeds the maximum size of ${formatBytes(maxSize)}.`\n          )\n          return\n        }\n\n        const error = validateFile(file)\n        if (error) {\n          errors.push(error)\n        } else {\n          validFiles.push({\n            file,\n            id: generateUniqueId(file),\n            preview: createPreview(file),\n          })\n        }\n      })\n\n      // Only update state if we have valid files to add\n      if (validFiles.length > 0) {\n        // Call the onFilesAdded callback with the newly added valid files\n        onFilesAdded?.(validFiles)\n\n        setState((prev) => {\n          const newFiles = !multiple ? validFiles : [...prev.files, ...validFiles]\n          onFilesChange?.(newFiles)\n          return {\n            ...prev,\n            files: newFiles,\n            errors,\n          }\n        })\n      } else if (errors.length > 0) {\n        setState((prev) => ({\n          ...prev,\n          errors,\n        }))\n      }\n\n      // Reset input value after handling files\n      if (inputRef.current) {\n        inputRef.current.value = ''\n      }\n    },\n    [\n      state.files,\n      maxFiles,\n      multiple,\n      maxSize,\n      validateFile,\n      createPreview,\n      generateUniqueId,\n      clearFiles,\n      onFilesChange,\n      onFilesAdded,\n    ]\n  )\n\n  const removeFile = useCallback(\n    (id: string) => {\n      setState((prev) => {\n        const fileToRemove = prev.files.find((file) => file.id === id)\n        if (\n          fileToRemove &&\n          fileToRemove.preview &&\n          fileToRemove.file instanceof File &&\n          fileToRemove.file.type.startsWith('image/')\n        ) {\n          URL.revokeObjectURL(fileToRemove.preview)\n        }\n\n        const newFiles = prev.files.filter((file) => file.id !== id)\n        onFilesChange?.(newFiles)\n\n        return {\n          ...prev,\n          files: newFiles,\n          errors: [],\n        }\n      })\n    },\n    [onFilesChange]\n  )\n\n  const clearErrors = useCallback(() => {\n    setState((prev) => ({\n      ...prev,\n      errors: [],\n    }))\n  }, [])\n\n  const handleDragEnter = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n    setState((prev) => ({ ...prev, isDragging: true }))\n  }, [])\n\n  const handleDragLeave = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n\n    if (e.currentTarget.contains(e.relatedTarget as Node)) {\n      return\n    }\n\n    setState((prev) => ({ ...prev, isDragging: false }))\n  }, [])\n\n  const handleDragOver = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n  }, [])\n\n  const handleDrop = useCallback(\n    (e: DragEvent<HTMLElement>) => {\n      e.preventDefault()\n      e.stopPropagation()\n      setState((prev) => ({ ...prev, isDragging: false }))\n\n      // Don't process files if the input is disabled\n      if (inputRef.current?.disabled) {\n        return\n      }\n\n      if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n        // In single file mode, only use the first file\n        if (!multiple) {\n          const file = e.dataTransfer.files[0]\n          addFiles([file])\n        } else {\n          addFiles(e.dataTransfer.files)\n        }\n      }\n    },\n    [addFiles, multiple]\n  )\n\n  const handleFileChange = useCallback(\n    (e: ChangeEvent<HTMLInputElement>) => {\n      if (e.target.files && e.target.files.length > 0) {\n        addFiles(e.target.files)\n      }\n    },\n    [addFiles]\n  )\n\n  const openFileDialog = useCallback(() => {\n    if (inputRef.current) {\n      inputRef.current.click()\n    }\n  }, [])\n\n  const getInputProps = useCallback(\n    (props: InputHTMLAttributes<HTMLInputElement> = {}) => {\n      return {\n        ...props,\n        type: 'file' as const,\n        onChange: handleFileChange,\n        accept: props.accept || accept,\n        multiple: props.multiple !== undefined ? props.multiple : multiple,\n        ref: inputRef,\n      }\n    },\n    [accept, multiple, handleFileChange]\n  )\n\n  return [\n    state,\n    {\n      addFiles,\n      removeFile,\n      clearFiles,\n      clearErrors,\n      handleDragEnter,\n      handleDragLeave,\n      handleDragOver,\n      handleDrop,\n      handleFileChange,\n      openFileDialog,\n      getInputProps,\n    },\n  ]\n}\n\n// Helper function to format bytes to human-readable format\nexport const formatBytes = (bytes: number, decimals = 2): string => {\n  if (bytes === 0) return '0 Bytes'\n\n  const k = 1024\n  const dm = decimals < 0 ? 0 : decimals\n  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']\n\n  const i = Math.floor(Math.log(bytes) / Math.log(k))\n\n  return Number.parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + sizes[i]\n}\n"
        },
        {
          "path": "registry/default/components/file-upload/file-upload-10.vue",
          "target": "components/ui/file-upload-10.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { AlertCircleIcon, FileArchiveIcon, FileIcon, FileSpreadsheetIcon, FileTextIcon, HeadphonesIcon, ImageIcon, Trash2Icon, UploadIcon, VideoIcon, XIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { formatBytes, useFileUpload } from '@/registry/default/hooks/use-file-upload-vue';\n\nconst initialFiles = [\n  {\n    name: 'document.pdf',\n    size: 528737,\n    type: 'application/pdf',\n    url: 'https://example.com/document.pdf',\n    id: 'document.pdf-1744638436563-8u5xuls',\n  },\n  {\n    name: 'intro.zip',\n    size: 252873,\n    type: 'application/zip',\n    url: 'https://example.com/intro.zip',\n    id: 'intro.zip-1744638436563-8u5xuls',\n  },\n  {\n    name: 'conclusion.xlsx',\n    size: 352873,\n    type: 'application/xlsx',\n    url: 'https://example.com/conclusion.xlsx',\n    id: 'conclusion.xlsx-1744638436563-8u5xuls',\n  },\n];\n\nconst maxSize = 10;\nconst maxSizeBytes = maxSize * 1024 * 1024;\nconst maxFiles = 10;\n\nconst [\n  { files, isDragging, errors },\n  {\n    handleDragEnter,\n    handleDragLeave,\n    handleDragOver,\n    handleDrop,\n    openFileDialog,\n    removeFile,\n    clearFiles,\n  },\n] = useFileUpload({\n  multiple: true,\n  maxFiles,\n  maxSize: maxSizeBytes,\n  initialFiles,\n});\n\nfunction getFileIcon(file: { file: File | { type: string; name: string } }) {\n  const fileType = file.file.type;\n  const fileName = file.file.name;\n\n  if (\n    fileType.includes('pdf') ||\n    fileType.includes('word') ||\n    fileName.endsWith('.pdf') ||\n    fileName.endsWith('.doc') ||\n    fileName.endsWith('.docx')\n  ) {\n    return FileTextIcon;\n  }\n\n  if (\n    fileType.includes('zip') ||\n    fileType.includes('archive') ||\n    fileName.endsWith('.zip') ||\n    fileName.endsWith('.rar')\n  ) {\n    return FileArchiveIcon;\n  }\n\n  if (\n    fileType.includes('excel') ||\n    fileName.endsWith('.xls') ||\n    fileName.endsWith('.xlsx')\n  ) {\n    return FileSpreadsheetIcon;\n  }\n\n  if (fileType.includes('video/')) return VideoIcon;\n  if (fileType.includes('audio/')) return HeadphonesIcon;\n  if (fileType.startsWith('image/')) return ImageIcon;\n  return FileIcon;\n}\n</script>\n\n<template>\n  <div class=\"flex flex-col gap-2\"><div @dragenter=\"handleDragEnter\" @dragleave=\"handleDragLeave\" @dragover=\"handleDragOver\" @drop=\"handleDrop\" :data-dragging=\"isDragging || undefined\" :data-files=\"files.length > 0 || undefined\" class=\"border-input data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 flex min-h-56 flex-col items-center rounded-xl border border-dashed p-4 transition-colors not-data-[files]:justify-center has-[input:focus]:ring-[3px]\"><input class=\"sr-only\" aria-label=\"Upload files\" /><template v-if=\"files.length > 0\">\n<div class=\"flex w-full flex-col gap-3\"><div class=\"flex items-center justify-between gap-2\"><h3 class=\"truncate text-sm font-medium\">Uploaded Files ({{ files.length }})</h3><Button variant=\"outline\" size=\"sm\" @click=\"clearFiles\"><Trash2Icon class=\"-ms-0.5 size-3.5 opacity-60\" aria-hidden=\"true\" />Remove all\n              </Button></div><div class=\"w-full space-y-2\"><div v-for=\"(file, index) in files\" :key=\"file.id\" class=\"bg-background flex items-center justify-between gap-2 rounded-lg border p-2 pe-3\"><div class=\"flex items-center gap-3 overflow-hidden\"><div class=\"flex aspect-square size-10 shrink-0 items-center justify-center rounded border\"><component :is=\"getFileIcon(file)\" class=\"size-4 opacity-60\" /></div><div class=\"flex min-w-0 flex-col gap-0.5\"><p class=\"truncate text-[13px] font-medium\">{{ file.file.name }}</p><p class=\"text-muted-foreground text-xs\">{{ formatBytes(file.file.size) }}</p></div></div><Button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground/80 hover:text-foreground -me-2 size-8 hover:bg-transparent\" @click=\"removeFile(file.id)\" aria-label=\"Remove file\"><XIcon class=\"size-4\" aria-hidden=\"true\" /></Button></div><Button v-if=\"files.length < maxFiles\" variant=\"outline\" class=\"mt-2 w-full\" @click=\"openFileDialog\"><UploadIcon class=\"-ms-1 opacity-60\" aria-hidden=\"true\" />Add more\n                </Button></div></div>\n</template>\n<template v-else>\n<div class=\"flex flex-col items-center justify-center text-center\"><div class=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><FileIcon class=\"size-4 opacity-60\" /></div><p class=\"mb-1.5 text-sm font-medium\">Upload files</p><p class=\"text-muted-foreground text-xs\">Max {{ maxFiles }}files ∙ Up to {{ maxSize }}MB\n            </p><Button variant=\"outline\" class=\"mt-4\" @click=\"openFileDialog\"><UploadIcon class=\"-ms-1 opacity-60\" aria-hidden=\"true\" />Select files\n            </Button></div>\n</template></div><div v-if=\"errors.length > 0\" class=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\"><AlertCircleIcon class=\"size-3 shrink-0\" /><span>{{ errors[0] }}</span></div><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-center text-xs\">Multiple files uploader w/ list inside ∙{{ ' ' }}<a href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\" class=\"hover:text-foreground underline\">API\n        </a></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/file-upload/file-upload-10.html",
          "target": "components/ui/file-upload-10.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex flex-col gap-2\"><div ondragenter=\"${handleDragEnter}\" ondragleave=\"${handleDragLeave}\" ondragover=\"${handleDragOver}\" ondrop=\"${handleDrop}\" data-dragging=\"${isDragging || undefined}\" data-files=\"${files.length > 0 || undefined}\" class=\"border-input data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 flex min-h-56 flex-col items-center rounded-xl border border-dashed p-4 transition-colors not-data-[files]:justify-center has-[input:focus]:ring-[3px]\"><input class=\"sr-only\" aria-label=\"Upload files\" /><!-- if files.length > 0 -->\n<div class=\"flex w-full flex-col gap-3\"><div class=\"flex items-center justify-between gap-2\"><h3 class=\"truncate text-sm font-medium\">Uploaded Files (${files.length})</h3><Button variant=\"outline\" size=\"sm\" on-click=\"${clearFiles}\"><Trash2Icon class=\"-ms-0.5 size-3.5 opacity-60\" aria-hidden=\"true\" />Remove all\n              </Button></div><div class=\"w-full space-y-2\"><!-- Loop files -->\n<div key=\"${file.id}\" class=\"bg-background flex items-center justify-between gap-2 rounded-lg border p-2 pe-3\"><div class=\"flex items-center gap-3 overflow-hidden\"><div class=\"flex aspect-square size-10 shrink-0 items-center justify-center rounded border\">${getFileIcon(file)}</div><div class=\"flex min-w-0 flex-col gap-0.5\"><p class=\"truncate text-[13px] font-medium\"><!-- if file.file instanceof File -->\n${file.file.name}\n<!-- else -->\n${file.file.name}\n<!-- endif --></p><p class=\"text-muted-foreground text-xs\">${formatBytes(file.file instanceof File ? file.file.size : file.file.size)}</p></div></div><Button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground/80 hover:text-foreground -me-2 size-8 hover:bg-transparent\" on-click=\"${() => removeFile(file.id)}\" aria-label=\"Remove file\"><XIcon class=\"size-4\" aria-hidden=\"true\" /></Button></div>\n<!-- End Loop --><!-- if files.length < maxFiles -->\n<Button variant=\"outline\" class=\"mt-2 w-full\" on-click=\"${openFileDialog}\"><UploadIcon class=\"-ms-1 opacity-60\" aria-hidden=\"true\" />Add more\n                </Button>\n<!-- endif --></div></div>\n<!-- else -->\n<div class=\"flex flex-col items-center justify-center text-center\"><div class=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><FileIcon class=\"size-4 opacity-60\" /></div><p class=\"mb-1.5 text-sm font-medium\">Upload files</p><p class=\"text-muted-foreground text-xs\">Max ${maxFiles}files ∙ Up to ${maxSize}MB\n            </p><Button variant=\"outline\" class=\"mt-4\" on-click=\"${openFileDialog}\"><UploadIcon class=\"-ms-1 opacity-60\" aria-hidden=\"true\" />Select files\n            </Button></div>\n<!-- endif --></div><!-- if errors.length > 0 -->\n<div class=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\"><AlertCircleIcon class=\"size-3 shrink-0\" /><span>${errors[0]}</span></div>\n<!-- endif --><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-center text-xs\">Multiple files uploader w/ list inside ∙${' '}<a href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\" class=\"hover:text-foreground underline\">API\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/file-upload/file-upload-10.wxml",
          "target": "components/ui/file-upload-10/file-upload-10.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex flex-col gap-2\"><view ondragenter=\"{{handleDragEnter}}\" ondragleave=\"{{handleDragLeave}}\" ondragover=\"{{handleDragOver}}\" ondrop=\"{{handleDrop}}\" data-dragging=\"{{isDragging || undefined}}\" data-files=\"{{files.length > 0 || undefined}}\" class=\"border-input data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 flex min-h-56 flex-col items-center rounded-xl border border-dashed p-4 transition-colors not-data-[files]:justify-center has-[input:focus]:ring-[3px]\"><input class=\"sr-only\" aria-label=\"Upload files\" /><block wx:if=\"{{files.length > 0}}\">\n<view class=\"flex w-full flex-col gap-3\"><view class=\"flex items-center justify-between gap-2\"><h3 class=\"truncate text-sm font-medium\">Uploaded Files ({{ files.length }})</h3><button variant=\"outline\" size=\"sm\" bindtap=\"clearFiles\"><trash2icon class=\"-ms-0.5 size-3.5 opacity-60\" aria-hidden=\"true\" />Remove all\n              </button></view><view class=\"w-full space-y-2\"><view wx:for=\"{{files}}\" wx:for-item=\"file\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{file.id}}\" class=\"bg-background flex items-center justify-between gap-2 rounded-lg border p-2 pe-3\"><view class=\"flex items-center gap-3 overflow-hidden\"><view class=\"flex aspect-square size-10 shrink-0 items-center justify-center rounded border\">{{ getFileIcon(file) }}</view><view class=\"flex min-w-0 flex-col gap-0.5\"><text class=\"truncate text-[13px] font-medium\"><block wx:if=\"{{file.file instanceof File}}\">\n{{ file.file.name }}\n</block>\n<block wx:else>\n{{ file.file.name }}\n</block></text><text class=\"text-muted-foreground text-xs\">{{ formatBytes(file.file instanceof File ? file.file.size : file.file.size) }}</text></view></view><button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground/80 hover:text-foreground -me-2 size-8 hover:bg-transparent\" bindtap=\"removeFile(file.id)\" aria-label=\"Remove file\"><xicon class=\"size-4\" aria-hidden=\"true\" /></button></view><button wx:if=\"{{files.length < maxFiles}}\" variant=\"outline\" class=\"mt-2 w-full\" bindtap=\"openFileDialog\"><uploadicon class=\"-ms-1 opacity-60\" aria-hidden=\"true\" />Add more\n                </button></view></view>\n</block>\n<block wx:else>\n<view class=\"flex flex-col items-center justify-center text-center\"><view class=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><fileicon class=\"size-4 opacity-60\" /></view><text class=\"mb-1.5 text-sm font-medium\">Upload files</text><text class=\"text-muted-foreground text-xs\">Max {{ maxFiles }}files ∙ Up to {{ maxSize }}MB\n            </text><button variant=\"outline\" class=\"mt-4\" bindtap=\"openFileDialog\"><uploadicon class=\"-ms-1 opacity-60\" aria-hidden=\"true\" />Select files\n            </button></view>\n</block></view><view wx:if=\"{{errors.length > 0}}\" class=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\"><alertcircleicon class=\"size-3 shrink-0\" /><text>{{ errors[0] }}</text></view><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-center text-xs\">Multiple files uploader w/ list inside ∙{{ ' ' }}<a href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\" class=\"hover:text-foreground underline\">API\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "upload",
          "file",
          "image",
          "drag and drop"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "file-upload-10",
          "group": "file-upload",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "file-upload-10",
              "path": "registry/default/components/file-upload/file-upload-10.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "file-upload-10",
              "path": "registry/default/components/file-upload/file-upload-10.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "file-upload-10",
              "path": "registry/default/components/file-upload/file-upload-10.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "file-upload-10",
              "path": "registry/default/components/file-upload/file-upload-10.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "file-upload",
        "title": "File Upload · Uploaded Files ({files.length})"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "file-upload"
      ]
    },
    {
      "name": "file-upload-11",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/table.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/file-upload/file-upload-11.tsx",
          "type": "registry:component",
          "target": "components/ui/file-upload-11.tsx",
          "content": "'use client'\n\nimport { Button, Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@timui/react'\nimport {\n  AlertCircleIcon,\n  DownloadIcon,\n  FileArchiveIcon,\n  FileIcon,\n  FileSpreadsheetIcon,\n  FileTextIcon,\n  HeadphonesIcon,\n  ImageIcon,\n  Trash2Icon,\n  UploadCloudIcon,\n  UploadIcon,\n  VideoIcon,\n} from 'lucide-react'\n\nimport { formatBytes, useFileUpload } from '@/registry/default/hooks/use-file-upload'\n\n// Create some dummy initial files\nconst initialFiles = [\n  {\n    name: 'document.pdf',\n    size: 528737,\n    type: 'application/pdf',\n    url: 'https://ui.timkit.cn',\n    id: 'document.pdf-1744638436563-8u5xuls',\n  },\n  {\n    name: 'intro.zip',\n    size: 252873,\n    type: 'application/zip',\n    url: 'https://ui.timkit.cn',\n    id: 'intro.zip-1744638436563-8u5xuls',\n  },\n  {\n    name: 'conclusion.xlsx',\n    size: 352873,\n    type: 'application/xlsx',\n    url: 'https://ui.timkit.cn',\n    id: 'conclusion.xlsx-1744638436563-8u5xuls',\n  },\n]\n\nconst getFileIcon = (file: { file: File | { type: string; name: string } }) => {\n  const fileType = file.file instanceof File ? file.file.type : file.file.type\n  const fileName = file.file instanceof File ? file.file.name : file.file.name\n\n  if (\n    fileType.includes('pdf') ||\n    fileName.endsWith('.pdf') ||\n    fileType.includes('word') ||\n    fileName.endsWith('.doc') ||\n    fileName.endsWith('.docx')\n  ) {\n    return <FileTextIcon className=\"size-4 opacity-60\" />\n  } else if (\n    fileType.includes('zip') ||\n    fileType.includes('archive') ||\n    fileName.endsWith('.zip') ||\n    fileName.endsWith('.rar')\n  ) {\n    return <FileArchiveIcon className=\"size-4 opacity-60\" />\n  } else if (\n    fileType.includes('excel') ||\n    fileName.endsWith('.xls') ||\n    fileName.endsWith('.xlsx')\n  ) {\n    return <FileSpreadsheetIcon className=\"size-4 opacity-60\" />\n  } else if (fileType.includes('video/')) {\n    return <VideoIcon className=\"size-4 opacity-60\" />\n  } else if (fileType.includes('audio/')) {\n    return <HeadphonesIcon className=\"size-4 opacity-60\" />\n  } else if (fileType.startsWith('image/')) {\n    return <ImageIcon className=\"size-4 opacity-60\" />\n  }\n  return <FileIcon className=\"size-4 opacity-60\" />\n}\n\nexport default function Component() {\n  const maxSize = 10 * 1024 * 1024 // 10MB default\n  const maxFiles = 10\n\n  const [\n    { files, isDragging, errors },\n    {\n      handleDragEnter,\n      handleDragLeave,\n      handleDragOver,\n      handleDrop,\n      openFileDialog,\n      removeFile,\n      clearFiles,\n      getInputProps,\n    },\n  ] = useFileUpload({\n    multiple: true,\n    maxFiles,\n    maxSize,\n    initialFiles,\n  })\n\n  return (\n    <div className=\"flex flex-col gap-2\">\n      {/* Drop area */}\n      <div\n        onDragEnter={handleDragEnter}\n        onDragLeave={handleDragLeave}\n        onDragOver={handleDragOver}\n        onDrop={handleDrop}\n        data-dragging={isDragging || undefined}\n        data-files={files.length > 0 || undefined}\n        className=\"border-input data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 flex min-h-56 flex-col items-center rounded-xl border border-dashed p-4 transition-colors not-data-[files]:justify-center has-[input:focus]:ring-[3px] data-[files]:hidden\"\n      >\n        <input {...getInputProps()} className=\"sr-only\" aria-label=\"Upload files\" />\n        <div className=\"flex flex-col items-center justify-center text-center\">\n          <div\n            className=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\"\n            aria-hidden=\"true\"\n          >\n            <FileIcon className=\"size-4 opacity-60\" />\n          </div>\n          <p className=\"mb-1.5 text-sm font-medium\">Upload files</p>\n          <p className=\"text-muted-foreground text-xs\">\n            Max {maxFiles} files ∙ Up to {formatBytes(maxSize)}\n          </p>\n          <Button variant=\"outline\" className=\"mt-4\" onClick={openFileDialog}>\n            <UploadIcon className=\"-ms-1 opacity-60\" aria-hidden=\"true\" />\n            Select files\n          </Button>\n        </div>\n      </div>\n      {files.length > 0 && (\n        <>\n          {/* Table with files */}\n          <div className=\"flex items-center justify-between gap-2\">\n            <h3 className=\"text-sm font-medium\">Files ({files.length})</h3>\n            <div className=\"flex gap-2\">\n              <Button variant=\"outline\" size=\"sm\" onClick={openFileDialog}>\n                <UploadCloudIcon className=\"-ms-0.5 size-3.5 opacity-60\" aria-hidden=\"true\" />\n                Add files\n              </Button>\n              <Button variant=\"outline\" size=\"sm\" onClick={clearFiles}>\n                <Trash2Icon className=\"-ms-0.5 size-3.5 opacity-60\" aria-hidden=\"true\" />\n                Remove all\n              </Button>\n            </div>\n          </div>\n          <div className=\"bg-background overflow-hidden rounded-md border\">\n            <Table>\n              <TableHeader className=\"text-xs\">\n                <TableRow className=\"bg-muted/50\">\n                  <TableHead className=\"h-9 py-2\">Name</TableHead>\n                  <TableHead className=\"h-9 py-2\">Type</TableHead>\n                  <TableHead className=\"h-9 py-2\">Size</TableHead>\n                  <TableHead className=\"h-9 w-0 py-2 text-right\">Actions</TableHead>\n                </TableRow>\n              </TableHeader>\n              <TableBody className=\"text-[13px]\">\n                {files.map((file) => (\n                  <TableRow key={file.id}>\n                    <TableCell className=\"max-w-48 py-2 font-medium\">\n                      <span className=\"flex items-center gap-2\">\n                        <span className=\"shrink-0\">{getFileIcon(file)}</span>{' '}\n                        <span className=\"truncate\">{file.file.name}</span>\n                      </span>\n                    </TableCell>\n                    <TableCell className=\"text-muted-foreground py-2\">\n                      {file.file.type.split('/')[1]?.toUpperCase() || 'UNKNOWN'}\n                    </TableCell>\n                    <TableCell className=\"text-muted-foreground py-2\">\n                      {formatBytes(file.file.size)}\n                    </TableCell>\n                    <TableCell className=\"py-2 text-right whitespace-nowrap\">\n                      <Button\n                        size=\"icon\"\n                        variant=\"ghost\"\n                        className=\"text-muted-foreground/80 hover:text-foreground size-8 hover:bg-transparent\"\n                        aria-label={`Download ${file.file.name}`}\n                        onClick={() => window.open(file.preview, '_blank')}\n                      >\n                        <DownloadIcon className=\"size-4\" />\n                      </Button>\n                      <Button\n                        size=\"icon\"\n                        variant=\"ghost\"\n                        className=\"text-muted-foreground/80 hover:text-foreground size-8 hover:bg-transparent\"\n                        aria-label={`Remove ${file.file.name}`}\n                        onClick={() => removeFile(file.id)}\n                      >\n                        <Trash2Icon className=\"size-4\" />\n                      </Button>\n                    </TableCell>\n                  </TableRow>\n                ))}\n              </TableBody>\n            </Table>\n          </div>\n        </>\n      )}\n\n      {errors.length > 0 && (\n        <div className=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\">\n          <AlertCircleIcon className=\"size-3 shrink-0\" />\n          <span>{errors[0]}</span>\n        </div>\n      )}\n\n      <p\n        aria-live=\"polite\"\n        role=\"region\"\n        className=\"text-muted-foreground mt-2 text-center text-xs\"\n      >\n        Multiple files uploader w/ table ∙{' '}\n        <a\n          href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\"\n          className=\"hover:text-foreground underline\"\n        >\n          API\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/hooks/use-file-upload.ts",
          "type": "registry:hook",
          "target": "components/ui/file-upload-11/use-file-upload.ts",
          "content": "'use client'\n\nimport type React from 'react'\nimport {\n  useCallback,\n  useRef,\n  useState,\n  type ChangeEvent,\n  type DragEvent,\n  type InputHTMLAttributes,\n} from 'react'\n\nexport type FileMetadata = {\n  name: string\n  size: number\n  type: string\n  url: string\n  id: string\n}\n\nexport type FileWithPreview = {\n  file: File | FileMetadata\n  id: string\n  preview?: string\n}\n\nexport type FileUploadOptions = {\n  maxFiles?: number // Only used when multiple is true, defaults to Infinity\n  maxSize?: number // in bytes\n  accept?: string\n  multiple?: boolean // Defaults to false\n  initialFiles?: FileMetadata[]\n  onFilesChange?: (files: FileWithPreview[]) => void // Callback when files change\n  onFilesAdded?: (addedFiles: FileWithPreview[]) => void // Callback when new files are added\n}\n\nexport type FileUploadState = {\n  files: FileWithPreview[]\n  isDragging: boolean\n  errors: string[]\n}\n\nexport type FileUploadActions = {\n  addFiles: (files: FileList | File[]) => void\n  removeFile: (id: string) => void\n  clearFiles: () => void\n  clearErrors: () => void\n  handleDragEnter: (e: DragEvent<HTMLElement>) => void\n  handleDragLeave: (e: DragEvent<HTMLElement>) => void\n  handleDragOver: (e: DragEvent<HTMLElement>) => void\n  handleDrop: (e: DragEvent<HTMLElement>) => void\n  handleFileChange: (e: ChangeEvent<HTMLInputElement>) => void\n  openFileDialog: () => void\n  getInputProps: (\n    props?: InputHTMLAttributes<HTMLInputElement>\n  ) => InputHTMLAttributes<HTMLInputElement> & {\n    ref: React.Ref<HTMLInputElement>\n  }\n}\n\nexport const useFileUpload = (\n  options: FileUploadOptions = {}\n): [FileUploadState, FileUploadActions] => {\n  const {\n    maxFiles = Infinity,\n    maxSize = Infinity,\n    accept = '*',\n    multiple = false,\n    initialFiles = [],\n    onFilesChange,\n    onFilesAdded,\n  } = options\n\n  const [state, setState] = useState<FileUploadState>({\n    files: initialFiles.map((file) => ({\n      file,\n      id: file.id,\n      preview: file.url,\n    })),\n    isDragging: false,\n    errors: [],\n  })\n\n  const inputRef = useRef<HTMLInputElement>(null)\n\n  const validateFile = useCallback(\n    (file: File | FileMetadata): string | null => {\n      if (file instanceof File) {\n        if (file.size > maxSize) {\n          return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n        }\n      } else {\n        if (file.size > maxSize) {\n          return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n        }\n      }\n\n      if (accept !== '*') {\n        const acceptedTypes = accept.split(',').map((type) => type.trim())\n        const fileType = file instanceof File ? file.type || '' : file.type\n        const fileExtension = `.${file instanceof File ? file.name.split('.').pop() : file.name.split('.').pop()}`\n\n        const isAccepted = acceptedTypes.some((type) => {\n          if (type.startsWith('.')) {\n            return fileExtension.toLowerCase() === type.toLowerCase()\n          }\n          if (type.endsWith('/*')) {\n            const baseType = type.split('/')[0]\n            return fileType.startsWith(`${baseType}/`)\n          }\n          return fileType === type\n        })\n\n        if (!isAccepted) {\n          return `File \"${file instanceof File ? file.name : file.name}\" is not an accepted file type.`\n        }\n      }\n\n      return null\n    },\n    [accept, maxSize]\n  )\n\n  const createPreview = useCallback((file: File | FileMetadata): string | undefined => {\n    if (file instanceof File) {\n      return URL.createObjectURL(file)\n    }\n    return file.url\n  }, [])\n\n  const generateUniqueId = useCallback((file: File | FileMetadata): string => {\n    if (file instanceof File) {\n      return `${file.name}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`\n    }\n    return file.id\n  }, [])\n\n  const clearFiles = useCallback(() => {\n    setState((prev) => {\n      // Clean up object URLs\n      prev.files.forEach((file) => {\n        if (file.preview && file.file instanceof File && file.file.type.startsWith('image/')) {\n          URL.revokeObjectURL(file.preview)\n        }\n      })\n\n      if (inputRef.current) {\n        inputRef.current.value = ''\n      }\n\n      const newState = {\n        ...prev,\n        files: [],\n        errors: [],\n      }\n\n      onFilesChange?.(newState.files)\n      return newState\n    })\n  }, [onFilesChange])\n\n  const addFiles = useCallback(\n    (newFiles: FileList | File[]) => {\n      if (!newFiles || newFiles.length === 0) return\n\n      const newFilesArray = Array.from(newFiles)\n      const errors: string[] = []\n\n      // Clear existing errors when new files are uploaded\n      setState((prev) => ({ ...prev, errors: [] }))\n\n      // In single file mode, clear existing files first\n      if (!multiple) {\n        clearFiles()\n      }\n\n      // Check if adding these files would exceed maxFiles (only in multiple mode)\n      if (\n        multiple &&\n        maxFiles !== Infinity &&\n        state.files.length + newFilesArray.length > maxFiles\n      ) {\n        errors.push(`You can only upload a maximum of ${maxFiles} files.`)\n        setState((prev) => ({ ...prev, errors }))\n        return\n      }\n\n      const validFiles: FileWithPreview[] = []\n\n      newFilesArray.forEach((file) => {\n        // Only check for duplicates if multiple files are allowed\n        if (multiple) {\n          const isDuplicate = state.files.some(\n            (existingFile) =>\n              existingFile.file.name === file.name && existingFile.file.size === file.size\n          )\n\n          // Skip duplicate files silently\n          if (isDuplicate) {\n            return\n          }\n        }\n\n        // Check file size\n        if (file.size > maxSize) {\n          errors.push(\n            multiple\n              ? `Some files exceed the maximum size of ${formatBytes(maxSize)}.`\n              : `File exceeds the maximum size of ${formatBytes(maxSize)}.`\n          )\n          return\n        }\n\n        const error = validateFile(file)\n        if (error) {\n          errors.push(error)\n        } else {\n          validFiles.push({\n            file,\n            id: generateUniqueId(file),\n            preview: createPreview(file),\n          })\n        }\n      })\n\n      // Only update state if we have valid files to add\n      if (validFiles.length > 0) {\n        // Call the onFilesAdded callback with the newly added valid files\n        onFilesAdded?.(validFiles)\n\n        setState((prev) => {\n          const newFiles = !multiple ? validFiles : [...prev.files, ...validFiles]\n          onFilesChange?.(newFiles)\n          return {\n            ...prev,\n            files: newFiles,\n            errors,\n          }\n        })\n      } else if (errors.length > 0) {\n        setState((prev) => ({\n          ...prev,\n          errors,\n        }))\n      }\n\n      // Reset input value after handling files\n      if (inputRef.current) {\n        inputRef.current.value = ''\n      }\n    },\n    [\n      state.files,\n      maxFiles,\n      multiple,\n      maxSize,\n      validateFile,\n      createPreview,\n      generateUniqueId,\n      clearFiles,\n      onFilesChange,\n      onFilesAdded,\n    ]\n  )\n\n  const removeFile = useCallback(\n    (id: string) => {\n      setState((prev) => {\n        const fileToRemove = prev.files.find((file) => file.id === id)\n        if (\n          fileToRemove &&\n          fileToRemove.preview &&\n          fileToRemove.file instanceof File &&\n          fileToRemove.file.type.startsWith('image/')\n        ) {\n          URL.revokeObjectURL(fileToRemove.preview)\n        }\n\n        const newFiles = prev.files.filter((file) => file.id !== id)\n        onFilesChange?.(newFiles)\n\n        return {\n          ...prev,\n          files: newFiles,\n          errors: [],\n        }\n      })\n    },\n    [onFilesChange]\n  )\n\n  const clearErrors = useCallback(() => {\n    setState((prev) => ({\n      ...prev,\n      errors: [],\n    }))\n  }, [])\n\n  const handleDragEnter = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n    setState((prev) => ({ ...prev, isDragging: true }))\n  }, [])\n\n  const handleDragLeave = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n\n    if (e.currentTarget.contains(e.relatedTarget as Node)) {\n      return\n    }\n\n    setState((prev) => ({ ...prev, isDragging: false }))\n  }, [])\n\n  const handleDragOver = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n  }, [])\n\n  const handleDrop = useCallback(\n    (e: DragEvent<HTMLElement>) => {\n      e.preventDefault()\n      e.stopPropagation()\n      setState((prev) => ({ ...prev, isDragging: false }))\n\n      // Don't process files if the input is disabled\n      if (inputRef.current?.disabled) {\n        return\n      }\n\n      if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n        // In single file mode, only use the first file\n        if (!multiple) {\n          const file = e.dataTransfer.files[0]\n          addFiles([file])\n        } else {\n          addFiles(e.dataTransfer.files)\n        }\n      }\n    },\n    [addFiles, multiple]\n  )\n\n  const handleFileChange = useCallback(\n    (e: ChangeEvent<HTMLInputElement>) => {\n      if (e.target.files && e.target.files.length > 0) {\n        addFiles(e.target.files)\n      }\n    },\n    [addFiles]\n  )\n\n  const openFileDialog = useCallback(() => {\n    if (inputRef.current) {\n      inputRef.current.click()\n    }\n  }, [])\n\n  const getInputProps = useCallback(\n    (props: InputHTMLAttributes<HTMLInputElement> = {}) => {\n      return {\n        ...props,\n        type: 'file' as const,\n        onChange: handleFileChange,\n        accept: props.accept || accept,\n        multiple: props.multiple !== undefined ? props.multiple : multiple,\n        ref: inputRef,\n      }\n    },\n    [accept, multiple, handleFileChange]\n  )\n\n  return [\n    state,\n    {\n      addFiles,\n      removeFile,\n      clearFiles,\n      clearErrors,\n      handleDragEnter,\n      handleDragLeave,\n      handleDragOver,\n      handleDrop,\n      handleFileChange,\n      openFileDialog,\n      getInputProps,\n    },\n  ]\n}\n\n// Helper function to format bytes to human-readable format\nexport const formatBytes = (bytes: number, decimals = 2): string => {\n  if (bytes === 0) return '0 Bytes'\n\n  const k = 1024\n  const dm = decimals < 0 ? 0 : decimals\n  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']\n\n  const i = Math.floor(Math.log(bytes) / Math.log(k))\n\n  return Number.parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + sizes[i]\n}\n"
        },
        {
          "path": "registry/default/components/file-upload/file-upload-11.vue",
          "target": "components/ui/file-upload-11.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { AlertCircleIcon, DownloadIcon, FileArchiveIcon, FileIcon, FileSpreadsheetIcon, FileTextIcon, HeadphonesIcon, ImageIcon, Trash2Icon, UploadCloudIcon, UploadIcon, VideoIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { Table } from '@timui/vue';\nimport { TableBody } from '@timui/vue';\nimport { TableCell } from '@timui/vue';\nimport { TableHead } from '@timui/vue';\nimport { TableHeader } from '@timui/vue';\nimport { TableRow } from '@timui/vue';\nimport { formatBytes, useFileUpload } from '@/registry/default/hooks/use-file-upload-vue';\n\nconst initialFiles = [\n  {\n    name: 'document.pdf',\n    size: 528737,\n    type: 'application/pdf',\n    url: 'https://example.com/document.pdf',\n    id: 'document.pdf-1744638436563-8u5xuls',\n  },\n  {\n    name: 'intro.zip',\n    size: 252873,\n    type: 'application/zip',\n    url: 'https://example.com/intro.zip',\n    id: 'intro.zip-1744638436563-8u5xuls',\n  },\n  {\n    name: 'conclusion.xlsx',\n    size: 352873,\n    type: 'application/xlsx',\n    url: 'https://example.com/conclusion.xlsx',\n    id: 'conclusion.xlsx-1744638436563-8u5xuls',\n  },\n];\n\nconst maxSize = 100 * 1024 * 1024;\nconst maxFiles = 10;\n\nconst [\n  { files, isDragging, errors },\n  {\n    handleDragEnter,\n    handleDragLeave,\n    handleDragOver,\n    handleDrop,\n    openFileDialog,\n    removeFile,\n    clearFiles,\n  },\n] = useFileUpload({\n  multiple: true,\n  maxFiles,\n  maxSize,\n  initialFiles,\n});\n\nfunction getFileIcon(file: { file: File | { type: string; name: string } }) {\n  const fileType = file.file.type;\n  const fileName = file.file.name;\n\n  if (\n    fileType.includes('pdf') ||\n    fileType.includes('word') ||\n    fileName.endsWith('.pdf') ||\n    fileName.endsWith('.doc') ||\n    fileName.endsWith('.docx')\n  ) {\n    return FileTextIcon;\n  }\n\n  if (\n    fileType.includes('zip') ||\n    fileType.includes('archive') ||\n    fileName.endsWith('.zip') ||\n    fileName.endsWith('.rar')\n  ) {\n    return FileArchiveIcon;\n  }\n\n  if (\n    fileType.includes('excel') ||\n    fileName.endsWith('.xls') ||\n    fileName.endsWith('.xlsx')\n  ) {\n    return FileSpreadsheetIcon;\n  }\n\n  if (fileType.includes('video/')) return VideoIcon;\n  if (fileType.includes('audio/')) return HeadphonesIcon;\n  if (fileType.startsWith('image/')) return ImageIcon;\n  return FileIcon;\n}\n</script>\n\n<template>\n  <div class=\"flex flex-col gap-2\"><div @dragenter=\"handleDragEnter\" @dragleave=\"handleDragLeave\" @dragover=\"handleDragOver\" @drop=\"handleDrop\" :data-dragging=\"isDragging || undefined\" :data-files=\"files.length > 0 || undefined\" class=\"border-input data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 flex min-h-56 flex-col items-center rounded-xl border border-dashed p-4 transition-colors not-data-[files]:justify-center has-[input:focus]:ring-[3px] data-[files]:hidden\"><input class=\"sr-only\" aria-label=\"Upload files\" /><div class=\"flex flex-col items-center justify-center text-center\"><div class=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><FileIcon class=\"size-4 opacity-60\" /></div><p class=\"mb-1.5 text-sm font-medium\">Upload files</p><p class=\"text-muted-foreground text-xs\">Max {{ maxFiles }}files ∙ Up to {{ formatBytes(maxSize) }}</p><Button variant=\"outline\" class=\"mt-4\" @click=\"openFileDialog\"><UploadIcon class=\"-ms-1 opacity-60\" aria-hidden=\"true\" />Select files\n          </Button></div></div><div v-if=\"files.length > 0\" class=\"flex items-center justify-between gap-2\"><h3 class=\"text-sm font-medium\">Files ({{ files.length }})</h3><div class=\"flex gap-2\"><Button variant=\"outline\" size=\"sm\" @click=\"openFileDialog\"><UploadCloudIcon class=\"-ms-0.5 size-3.5 opacity-60\" aria-hidden=\"true\" />Add files\n              </Button><Button variant=\"outline\" size=\"sm\" @click=\"clearFiles\"><Trash2Icon class=\"-ms-0.5 size-3.5 opacity-60\" aria-hidden=\"true\" />Remove all\n              </Button></div></div><div class=\"bg-background overflow-hidden rounded-md border\"><Table><TableHeader class=\"text-xs\"><TableRow class=\"bg-muted/50\"><TableHead class=\"h-9 py-2\">Name</TableHead><TableHead class=\"h-9 py-2\">Type</TableHead><TableHead class=\"h-9 py-2\">Size</TableHead><TableHead class=\"h-9 w-0 py-2 text-right\">Actions</TableHead></TableRow></TableHeader><TableBody class=\"text-[13px]\"><TableRow v-for=\"(file, index) in files\" :key=\"file.id\"><TableCell class=\"max-w-48 py-2 font-medium\"><span class=\"flex items-center gap-2\"><span class=\"shrink-0\"><component :is=\"getFileIcon(file)\" class=\"size-4 opacity-60\" /></span>{{ ' ' }}<span class=\"truncate\">{{ file.file.name }}</span></span></TableCell><TableCell class=\"text-muted-foreground py-2\">{{ file.file.type.split('/')[1]?.toUpperCase() || 'UNKNOWN' }}</TableCell><TableCell class=\"text-muted-foreground py-2\">{{ formatBytes(file.file.size) }}</TableCell><TableCell class=\"py-2 text-right whitespace-nowrap\"><Button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground/80 hover:text-foreground size-8 hover:bg-transparent\" :aria-label=\"`Download ${file.file.name}`\" @click=\"window.open(file.preview, '_blank')\"><DownloadIcon class=\"size-4\" /></Button><Button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground/80 hover:text-foreground size-8 hover:bg-transparent\" :aria-label=\"`Remove ${file.file.name}`\" @click=\"removeFile(file.id)\"><Trash2Icon class=\"size-4\" /></Button></TableCell></TableRow></TableBody></Table></div><div v-if=\"errors.length > 0\" class=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\"><AlertCircleIcon class=\"size-3 shrink-0\" /><span>{{ errors[0] }}</span></div><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-center text-xs\">Multiple files uploader w/ table ∙{{ ' ' }}<a href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\" class=\"hover:text-foreground underline\">API\n        </a></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/file-upload/file-upload-11.html",
          "target": "components/ui/file-upload-11.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex flex-col gap-2\"><div ondragenter=\"${handleDragEnter}\" ondragleave=\"${handleDragLeave}\" ondragover=\"${handleDragOver}\" ondrop=\"${handleDrop}\" data-dragging=\"${isDragging || undefined}\" data-files=\"${files.length > 0 || undefined}\" class=\"border-input data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 flex min-h-56 flex-col items-center rounded-xl border border-dashed p-4 transition-colors not-data-[files]:justify-center has-[input:focus]:ring-[3px] data-[files]:hidden\"><input class=\"sr-only\" aria-label=\"Upload files\" /><div class=\"flex flex-col items-center justify-center text-center\"><div class=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><FileIcon class=\"size-4 opacity-60\" /></div><p class=\"mb-1.5 text-sm font-medium\">Upload files</p><p class=\"text-muted-foreground text-xs\">Max ${maxFiles}files ∙ Up to ${formatBytes(maxSize)}</p><Button variant=\"outline\" class=\"mt-4\" on-click=\"${openFileDialog}\"><UploadIcon class=\"-ms-1 opacity-60\" aria-hidden=\"true\" />Select files\n          </Button></div></div><!-- if files.length > 0 -->\n<div class=\"flex items-center justify-between gap-2\"><h3 class=\"text-sm font-medium\">Files (${files.length})</h3><div class=\"flex gap-2\"><Button variant=\"outline\" size=\"sm\" on-click=\"${openFileDialog}\"><UploadCloudIcon class=\"-ms-0.5 size-3.5 opacity-60\" aria-hidden=\"true\" />Add files\n              </Button><Button variant=\"outline\" size=\"sm\" on-click=\"${clearFiles}\"><Trash2Icon class=\"-ms-0.5 size-3.5 opacity-60\" aria-hidden=\"true\" />Remove all\n              </Button></div></div><div class=\"bg-background overflow-hidden rounded-md border\"><Table><TableHeader class=\"text-xs\"><TableRow class=\"bg-muted/50\"><TableHead class=\"h-9 py-2\">Name</TableHead><TableHead class=\"h-9 py-2\">Type</TableHead><TableHead class=\"h-9 py-2\">Size</TableHead><TableHead class=\"h-9 w-0 py-2 text-right\">Actions</TableHead></TableRow></TableHeader><TableBody class=\"text-[13px]\"><!-- Loop files -->\n<TableRow key=\"${file.id}\"><TableCell class=\"max-w-48 py-2 font-medium\"><span class=\"flex items-center gap-2\"><span class=\"shrink-0\">${getFileIcon(file)}</span>${' '}<span class=\"truncate\">${file.file.name}</span></span></TableCell><TableCell class=\"text-muted-foreground py-2\">${file.file.type.split('/')[1]?.toUpperCase() || 'UNKNOWN'}</TableCell><TableCell class=\"text-muted-foreground py-2\">${formatBytes(file.file.size)}</TableCell><TableCell class=\"py-2 text-right whitespace-nowrap\"><Button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground/80 hover:text-foreground size-8 hover:bg-transparent\" aria-label=\"${`Download ${file.file.name}`}\" on-click=\"${() => window.open(file.preview, '_blank')}\"><DownloadIcon class=\"size-4\" /></Button><Button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground/80 hover:text-foreground size-8 hover:bg-transparent\" aria-label=\"${`Remove ${file.file.name}`}\" on-click=\"${() => removeFile(file.id)}\"><Trash2Icon class=\"size-4\" /></Button></TableCell></TableRow>\n<!-- End Loop --></TableBody></Table></div>\n<!-- endif --><!-- if errors.length > 0 -->\n<div class=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\"><AlertCircleIcon class=\"size-3 shrink-0\" /><span>${errors[0]}</span></div>\n<!-- endif --><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-center text-xs\">Multiple files uploader w/ table ∙${' '}<a href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\" class=\"hover:text-foreground underline\">API\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/file-upload/file-upload-11.wxml",
          "target": "components/ui/file-upload-11/file-upload-11.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex flex-col gap-2\"><view ondragenter=\"{{handleDragEnter}}\" ondragleave=\"{{handleDragLeave}}\" ondragover=\"{{handleDragOver}}\" ondrop=\"{{handleDrop}}\" data-dragging=\"{{isDragging || undefined}}\" data-files=\"{{files.length > 0 || undefined}}\" class=\"border-input data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 flex min-h-56 flex-col items-center rounded-xl border border-dashed p-4 transition-colors not-data-[files]:justify-center has-[input:focus]:ring-[3px] data-[files]:hidden\"><input class=\"sr-only\" aria-label=\"Upload files\" /><view class=\"flex flex-col items-center justify-center text-center\"><view class=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><fileicon class=\"size-4 opacity-60\" /></view><text class=\"mb-1.5 text-sm font-medium\">Upload files</text><text class=\"text-muted-foreground text-xs\">Max {{ maxFiles }}files ∙ Up to {{ formatBytes(maxSize) }}</text><button variant=\"outline\" class=\"mt-4\" bindtap=\"openFileDialog\"><uploadicon class=\"-ms-1 opacity-60\" aria-hidden=\"true\" />Select files\n          </button></view></view><view wx:if=\"{{files.length > 0}}\" class=\"flex items-center justify-between gap-2\"><h3 class=\"text-sm font-medium\">Files ({{ files.length }})</h3><view class=\"flex gap-2\"><button variant=\"outline\" size=\"sm\" bindtap=\"openFileDialog\"><uploadcloudicon class=\"-ms-0.5 size-3.5 opacity-60\" aria-hidden=\"true\" />Add files\n              </button><button variant=\"outline\" size=\"sm\" bindtap=\"clearFiles\"><trash2icon class=\"-ms-0.5 size-3.5 opacity-60\" aria-hidden=\"true\" />Remove all\n              </button></view></view><view class=\"bg-background overflow-hidden rounded-md border\"><table><tableheader class=\"text-xs\"><tablerow class=\"bg-muted/50\"><tablehead class=\"h-9 py-2\">Name</tablehead><tablehead class=\"h-9 py-2\">Type</tablehead><tablehead class=\"h-9 py-2\">Size</tablehead><tablehead class=\"h-9 w-0 py-2 text-right\">Actions</tablehead></tablerow></tableheader><tablebody class=\"text-[13px]\"><tablerow wx:for=\"{{files}}\" wx:for-item=\"file\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{file.id}}\"><tablecell class=\"max-w-48 py-2 font-medium\"><text class=\"flex items-center gap-2\"><text class=\"shrink-0\">{{ getFileIcon(file) }}</text>{{ ' ' }}<text class=\"truncate\">{{ file.file.name }}</text></text></tablecell><tablecell class=\"text-muted-foreground py-2\">{{ file.file.type.split('/')[1]?.toUpperCase() || 'UNKNOWN' }}</tablecell><tablecell class=\"text-muted-foreground py-2\">{{ formatBytes(file.file.size) }}</tablecell><tablecell class=\"py-2 text-right whitespace-nowrap\"><button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground/80 hover:text-foreground size-8 hover:bg-transparent\" aria-label=\"{{`Download ${file.file.name}`}}\" bindtap=\"window.open(file.preview, '_blank')\"><downloadicon class=\"size-4\" /></button><button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground/80 hover:text-foreground size-8 hover:bg-transparent\" aria-label=\"{{`Remove ${file.file.name}`}}\" bindtap=\"removeFile(file.id)\"><trash2icon class=\"size-4\" /></button></tablecell></tablerow></tablebody></table></view><view wx:if=\"{{errors.length > 0}}\" class=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\"><alertcircleicon class=\"size-3 shrink-0\" /><text>{{ errors[0] }}</text></view><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-center text-xs\">Multiple files uploader w/ table ∙{{ ' ' }}<a href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\" class=\"hover:text-foreground underline\">API\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "upload",
          "file",
          "image",
          "drag and drop"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "file-upload-11",
          "group": "file-upload",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "file-upload-11",
              "path": "registry/default/components/file-upload/file-upload-11.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "file-upload-11",
              "path": "registry/default/components/file-upload/file-upload-11.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "file-upload-11",
              "path": "registry/default/components/file-upload/file-upload-11.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "file-upload-11",
              "path": "registry/default/components/file-upload/file-upload-11.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "file-upload",
        "title": "File Upload · Files ({files.length})"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "file-upload"
      ]
    },
    {
      "name": "file-upload-12",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/file-upload/file-upload-12.tsx",
          "type": "registry:component",
          "target": "components/ui/file-upload-12.tsx",
          "content": "'use client'\n\nimport { Button } from '@timui/react'\nimport {\n  AlertCircleIcon,\n  FileArchiveIcon,\n  FileIcon,\n  FileSpreadsheetIcon,\n  FileTextIcon,\n  HeadphonesIcon,\n  ImageIcon,\n  Trash2Icon,\n  UploadIcon,\n  VideoIcon,\n  XIcon,\n} from 'lucide-react'\n\nimport { formatBytes, useFileUpload } from '@/registry/default/hooks/use-file-upload'\n\n// Create some dummy initial files\nconst initialFiles = [\n  {\n    name: 'intro.zip',\n    size: 252873,\n    type: 'application/zip',\n    url: 'https://example.com/intro.zip',\n    id: 'intro.zip-1744638436563-8u5xuls',\n  },\n  {\n    name: 'image-01.jpg',\n    size: 1528737,\n    type: 'image/jpeg',\n    url: 'https://picsum.photos/1000/800?grayscale&random=1',\n    id: 'image-01-123456789',\n  },\n  {\n    name: 'audio.mp3',\n    size: 1528737,\n    type: 'audio/mpeg',\n    url: 'https://example.com/audio.mp3',\n    id: 'audio-123456789',\n  },\n]\n\nconst getFileIcon = (file: { file: File | { type: string; name: string } }) => {\n  const fileType = file.file instanceof File ? file.file.type : file.file.type\n  const fileName = file.file instanceof File ? file.file.name : file.file.name\n\n  const iconMap = {\n    pdf: {\n      icon: FileTextIcon,\n      conditions: (type: string, name: string) =>\n        type.includes('pdf') ||\n        name.endsWith('.pdf') ||\n        type.includes('word') ||\n        name.endsWith('.doc') ||\n        name.endsWith('.docx'),\n    },\n    archive: {\n      icon: FileArchiveIcon,\n      conditions: (type: string, name: string) =>\n        type.includes('zip') ||\n        type.includes('archive') ||\n        name.endsWith('.zip') ||\n        name.endsWith('.rar'),\n    },\n    excel: {\n      icon: FileSpreadsheetIcon,\n      conditions: (type: string, name: string) =>\n        type.includes('excel') || name.endsWith('.xls') || name.endsWith('.xlsx'),\n    },\n    video: {\n      icon: VideoIcon,\n      conditions: (type: string) => type.includes('video/'),\n    },\n    audio: {\n      icon: HeadphonesIcon,\n      conditions: (type: string) => type.includes('audio/'),\n    },\n    image: {\n      icon: ImageIcon,\n      conditions: (type: string) => type.startsWith('image/'),\n    },\n  }\n\n  for (const { icon: Icon, conditions } of Object.values(iconMap)) {\n    if (conditions(fileType, fileName)) {\n      return <Icon className=\"size-5 opacity-60\" />\n    }\n  }\n\n  return <FileIcon className=\"size-5 opacity-60\" />\n}\n\nconst getFilePreview = (file: { file: File | { type: string; name: string; url?: string } }) => {\n  const fileType = file.file instanceof File ? file.file.type : file.file.type\n  const fileName = file.file instanceof File ? file.file.name : file.file.name\n\n  const renderImage = (src: string) => (\n    <img src={src} alt={fileName} className=\"size-full rounded-t-[inherit] object-cover\" />\n  )\n\n  return (\n    <div className=\"bg-accent flex aspect-square items-center justify-center overflow-hidden rounded-t-[inherit]\">\n      {fileType.startsWith('image/') ? (\n        file.file instanceof File ? (\n          (() => {\n            const previewUrl = URL.createObjectURL(file.file)\n            return renderImage(previewUrl)\n          })()\n        ) : file.file.url ? (\n          renderImage(file.file.url)\n        ) : (\n          <ImageIcon className=\"size-5 opacity-60\" />\n        )\n      ) : (\n        getFileIcon(file)\n      )}\n    </div>\n  )\n}\n\nexport default function Component() {\n  const maxSizeMB = 5\n  const maxSize = maxSizeMB * 1024 * 1024 // 5MB default\n  const maxFiles = 6\n\n  const [\n    { files, isDragging, errors },\n    {\n      handleDragEnter,\n      handleDragLeave,\n      handleDragOver,\n      handleDrop,\n      openFileDialog,\n      removeFile,\n      clearFiles,\n      getInputProps,\n    },\n  ] = useFileUpload({\n    multiple: true,\n    maxFiles,\n    maxSize,\n    initialFiles,\n  })\n\n  return (\n    <div className=\"flex flex-col gap-2\">\n      {/* Drop area */}\n      <div\n        onDragEnter={handleDragEnter}\n        onDragLeave={handleDragLeave}\n        onDragOver={handleDragOver}\n        onDrop={handleDrop}\n        data-dragging={isDragging || undefined}\n        data-files={files.length > 0 || undefined}\n        className=\"border-input data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 relative flex min-h-52 flex-col items-center overflow-hidden rounded-xl border border-dashed p-4 transition-colors not-data-[files]:justify-center has-[input:focus]:ring-[3px]\"\n      >\n        <input {...getInputProps()} className=\"sr-only\" aria-label=\"Upload image file\" />\n        {files.length > 0 ? (\n          <div className=\"flex w-full flex-col gap-3\">\n            <div className=\"flex items-center justify-between gap-2\">\n              <h3 className=\"truncate text-sm font-medium\">Files ({files.length})</h3>\n              <div className=\"flex gap-2\">\n                <Button variant=\"outline\" size=\"sm\" onClick={openFileDialog}>\n                  <UploadIcon className=\"-ms-0.5 size-3.5 opacity-60\" aria-hidden=\"true\" />\n                  Add files\n                </Button>\n                <Button variant=\"outline\" size=\"sm\" onClick={clearFiles}>\n                  <Trash2Icon className=\"-ms-0.5 size-3.5 opacity-60\" aria-hidden=\"true\" />\n                  Remove all\n                </Button>\n              </div>\n            </div>\n\n            <div className=\"grid grid-cols-2 gap-4 md:grid-cols-3\">\n              {files.map((file) => (\n                <div\n                  key={file.id}\n                  className=\"bg-background relative flex flex-col rounded-md border\"\n                >\n                  {getFilePreview(file)}\n                  <Button\n                    onClick={() => removeFile(file.id)}\n                    size=\"icon\"\n                    className=\"border-background focus-visible:border-background absolute -top-2 -right-2 size-6 rounded-full border-2 shadow-none\"\n                    aria-label=\"Remove image\"\n                  >\n                    <XIcon className=\"size-3.5\" />\n                  </Button>\n                  <div className=\"flex min-w-0 flex-col gap-0.5 border-t p-3\">\n                    <p className=\"truncate text-[13px] font-medium\">{file.file.name}</p>\n                    <p className=\"text-muted-foreground truncate text-xs\">\n                      {formatBytes(file.file.size)}\n                    </p>\n                  </div>\n                </div>\n              ))}\n            </div>\n          </div>\n        ) : (\n          <div className=\"flex flex-col items-center justify-center px-4 py-3 text-center\">\n            <div\n              className=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\"\n              aria-hidden=\"true\"\n            >\n              <ImageIcon className=\"size-4 opacity-60\" />\n            </div>\n            <p className=\"mb-1.5 text-sm font-medium\">Drop your files here</p>\n            <p className=\"text-muted-foreground text-xs\">\n              Max {maxFiles} files ∙ Up to {maxSizeMB}MB\n            </p>\n            <Button variant=\"outline\" className=\"mt-4\" onClick={openFileDialog}>\n              <UploadIcon className=\"-ms-1 opacity-60\" aria-hidden=\"true\" />\n              Select images\n            </Button>\n          </div>\n        )}\n      </div>\n\n      {errors.length > 0 && (\n        <div className=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\">\n          <AlertCircleIcon className=\"size-3 shrink-0\" />\n          <span>{errors[0]}</span>\n        </div>\n      )}\n\n      <p\n        aria-live=\"polite\"\n        role=\"region\"\n        className=\"text-muted-foreground mt-2 text-center text-xs\"\n      >\n        Mixed content w/ card ∙{' '}\n        <a\n          href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\"\n          className=\"hover:text-foreground underline\"\n        >\n          API\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/hooks/use-file-upload.ts",
          "type": "registry:hook",
          "target": "components/ui/file-upload-12/use-file-upload.ts",
          "content": "'use client'\n\nimport type React from 'react'\nimport {\n  useCallback,\n  useRef,\n  useState,\n  type ChangeEvent,\n  type DragEvent,\n  type InputHTMLAttributes,\n} from 'react'\n\nexport type FileMetadata = {\n  name: string\n  size: number\n  type: string\n  url: string\n  id: string\n}\n\nexport type FileWithPreview = {\n  file: File | FileMetadata\n  id: string\n  preview?: string\n}\n\nexport type FileUploadOptions = {\n  maxFiles?: number // Only used when multiple is true, defaults to Infinity\n  maxSize?: number // in bytes\n  accept?: string\n  multiple?: boolean // Defaults to false\n  initialFiles?: FileMetadata[]\n  onFilesChange?: (files: FileWithPreview[]) => void // Callback when files change\n  onFilesAdded?: (addedFiles: FileWithPreview[]) => void // Callback when new files are added\n}\n\nexport type FileUploadState = {\n  files: FileWithPreview[]\n  isDragging: boolean\n  errors: string[]\n}\n\nexport type FileUploadActions = {\n  addFiles: (files: FileList | File[]) => void\n  removeFile: (id: string) => void\n  clearFiles: () => void\n  clearErrors: () => void\n  handleDragEnter: (e: DragEvent<HTMLElement>) => void\n  handleDragLeave: (e: DragEvent<HTMLElement>) => void\n  handleDragOver: (e: DragEvent<HTMLElement>) => void\n  handleDrop: (e: DragEvent<HTMLElement>) => void\n  handleFileChange: (e: ChangeEvent<HTMLInputElement>) => void\n  openFileDialog: () => void\n  getInputProps: (\n    props?: InputHTMLAttributes<HTMLInputElement>\n  ) => InputHTMLAttributes<HTMLInputElement> & {\n    ref: React.Ref<HTMLInputElement>\n  }\n}\n\nexport const useFileUpload = (\n  options: FileUploadOptions = {}\n): [FileUploadState, FileUploadActions] => {\n  const {\n    maxFiles = Infinity,\n    maxSize = Infinity,\n    accept = '*',\n    multiple = false,\n    initialFiles = [],\n    onFilesChange,\n    onFilesAdded,\n  } = options\n\n  const [state, setState] = useState<FileUploadState>({\n    files: initialFiles.map((file) => ({\n      file,\n      id: file.id,\n      preview: file.url,\n    })),\n    isDragging: false,\n    errors: [],\n  })\n\n  const inputRef = useRef<HTMLInputElement>(null)\n\n  const validateFile = useCallback(\n    (file: File | FileMetadata): string | null => {\n      if (file instanceof File) {\n        if (file.size > maxSize) {\n          return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n        }\n      } else {\n        if (file.size > maxSize) {\n          return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n        }\n      }\n\n      if (accept !== '*') {\n        const acceptedTypes = accept.split(',').map((type) => type.trim())\n        const fileType = file instanceof File ? file.type || '' : file.type\n        const fileExtension = `.${file instanceof File ? file.name.split('.').pop() : file.name.split('.').pop()}`\n\n        const isAccepted = acceptedTypes.some((type) => {\n          if (type.startsWith('.')) {\n            return fileExtension.toLowerCase() === type.toLowerCase()\n          }\n          if (type.endsWith('/*')) {\n            const baseType = type.split('/')[0]\n            return fileType.startsWith(`${baseType}/`)\n          }\n          return fileType === type\n        })\n\n        if (!isAccepted) {\n          return `File \"${file instanceof File ? file.name : file.name}\" is not an accepted file type.`\n        }\n      }\n\n      return null\n    },\n    [accept, maxSize]\n  )\n\n  const createPreview = useCallback((file: File | FileMetadata): string | undefined => {\n    if (file instanceof File) {\n      return URL.createObjectURL(file)\n    }\n    return file.url\n  }, [])\n\n  const generateUniqueId = useCallback((file: File | FileMetadata): string => {\n    if (file instanceof File) {\n      return `${file.name}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`\n    }\n    return file.id\n  }, [])\n\n  const clearFiles = useCallback(() => {\n    setState((prev) => {\n      // Clean up object URLs\n      prev.files.forEach((file) => {\n        if (file.preview && file.file instanceof File && file.file.type.startsWith('image/')) {\n          URL.revokeObjectURL(file.preview)\n        }\n      })\n\n      if (inputRef.current) {\n        inputRef.current.value = ''\n      }\n\n      const newState = {\n        ...prev,\n        files: [],\n        errors: [],\n      }\n\n      onFilesChange?.(newState.files)\n      return newState\n    })\n  }, [onFilesChange])\n\n  const addFiles = useCallback(\n    (newFiles: FileList | File[]) => {\n      if (!newFiles || newFiles.length === 0) return\n\n      const newFilesArray = Array.from(newFiles)\n      const errors: string[] = []\n\n      // Clear existing errors when new files are uploaded\n      setState((prev) => ({ ...prev, errors: [] }))\n\n      // In single file mode, clear existing files first\n      if (!multiple) {\n        clearFiles()\n      }\n\n      // Check if adding these files would exceed maxFiles (only in multiple mode)\n      if (\n        multiple &&\n        maxFiles !== Infinity &&\n        state.files.length + newFilesArray.length > maxFiles\n      ) {\n        errors.push(`You can only upload a maximum of ${maxFiles} files.`)\n        setState((prev) => ({ ...prev, errors }))\n        return\n      }\n\n      const validFiles: FileWithPreview[] = []\n\n      newFilesArray.forEach((file) => {\n        // Only check for duplicates if multiple files are allowed\n        if (multiple) {\n          const isDuplicate = state.files.some(\n            (existingFile) =>\n              existingFile.file.name === file.name && existingFile.file.size === file.size\n          )\n\n          // Skip duplicate files silently\n          if (isDuplicate) {\n            return\n          }\n        }\n\n        // Check file size\n        if (file.size > maxSize) {\n          errors.push(\n            multiple\n              ? `Some files exceed the maximum size of ${formatBytes(maxSize)}.`\n              : `File exceeds the maximum size of ${formatBytes(maxSize)}.`\n          )\n          return\n        }\n\n        const error = validateFile(file)\n        if (error) {\n          errors.push(error)\n        } else {\n          validFiles.push({\n            file,\n            id: generateUniqueId(file),\n            preview: createPreview(file),\n          })\n        }\n      })\n\n      // Only update state if we have valid files to add\n      if (validFiles.length > 0) {\n        // Call the onFilesAdded callback with the newly added valid files\n        onFilesAdded?.(validFiles)\n\n        setState((prev) => {\n          const newFiles = !multiple ? validFiles : [...prev.files, ...validFiles]\n          onFilesChange?.(newFiles)\n          return {\n            ...prev,\n            files: newFiles,\n            errors,\n          }\n        })\n      } else if (errors.length > 0) {\n        setState((prev) => ({\n          ...prev,\n          errors,\n        }))\n      }\n\n      // Reset input value after handling files\n      if (inputRef.current) {\n        inputRef.current.value = ''\n      }\n    },\n    [\n      state.files,\n      maxFiles,\n      multiple,\n      maxSize,\n      validateFile,\n      createPreview,\n      generateUniqueId,\n      clearFiles,\n      onFilesChange,\n      onFilesAdded,\n    ]\n  )\n\n  const removeFile = useCallback(\n    (id: string) => {\n      setState((prev) => {\n        const fileToRemove = prev.files.find((file) => file.id === id)\n        if (\n          fileToRemove &&\n          fileToRemove.preview &&\n          fileToRemove.file instanceof File &&\n          fileToRemove.file.type.startsWith('image/')\n        ) {\n          URL.revokeObjectURL(fileToRemove.preview)\n        }\n\n        const newFiles = prev.files.filter((file) => file.id !== id)\n        onFilesChange?.(newFiles)\n\n        return {\n          ...prev,\n          files: newFiles,\n          errors: [],\n        }\n      })\n    },\n    [onFilesChange]\n  )\n\n  const clearErrors = useCallback(() => {\n    setState((prev) => ({\n      ...prev,\n      errors: [],\n    }))\n  }, [])\n\n  const handleDragEnter = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n    setState((prev) => ({ ...prev, isDragging: true }))\n  }, [])\n\n  const handleDragLeave = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n\n    if (e.currentTarget.contains(e.relatedTarget as Node)) {\n      return\n    }\n\n    setState((prev) => ({ ...prev, isDragging: false }))\n  }, [])\n\n  const handleDragOver = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n  }, [])\n\n  const handleDrop = useCallback(\n    (e: DragEvent<HTMLElement>) => {\n      e.preventDefault()\n      e.stopPropagation()\n      setState((prev) => ({ ...prev, isDragging: false }))\n\n      // Don't process files if the input is disabled\n      if (inputRef.current?.disabled) {\n        return\n      }\n\n      if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n        // In single file mode, only use the first file\n        if (!multiple) {\n          const file = e.dataTransfer.files[0]\n          addFiles([file])\n        } else {\n          addFiles(e.dataTransfer.files)\n        }\n      }\n    },\n    [addFiles, multiple]\n  )\n\n  const handleFileChange = useCallback(\n    (e: ChangeEvent<HTMLInputElement>) => {\n      if (e.target.files && e.target.files.length > 0) {\n        addFiles(e.target.files)\n      }\n    },\n    [addFiles]\n  )\n\n  const openFileDialog = useCallback(() => {\n    if (inputRef.current) {\n      inputRef.current.click()\n    }\n  }, [])\n\n  const getInputProps = useCallback(\n    (props: InputHTMLAttributes<HTMLInputElement> = {}) => {\n      return {\n        ...props,\n        type: 'file' as const,\n        onChange: handleFileChange,\n        accept: props.accept || accept,\n        multiple: props.multiple !== undefined ? props.multiple : multiple,\n        ref: inputRef,\n      }\n    },\n    [accept, multiple, handleFileChange]\n  )\n\n  return [\n    state,\n    {\n      addFiles,\n      removeFile,\n      clearFiles,\n      clearErrors,\n      handleDragEnter,\n      handleDragLeave,\n      handleDragOver,\n      handleDrop,\n      handleFileChange,\n      openFileDialog,\n      getInputProps,\n    },\n  ]\n}\n\n// Helper function to format bytes to human-readable format\nexport const formatBytes = (bytes: number, decimals = 2): string => {\n  if (bytes === 0) return '0 Bytes'\n\n  const k = 1024\n  const dm = decimals < 0 ? 0 : decimals\n  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']\n\n  const i = Math.floor(Math.log(bytes) / Math.log(k))\n\n  return Number.parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + sizes[i]\n}\n"
        },
        {
          "path": "registry/default/components/file-upload/file-upload-12.vue",
          "target": "components/ui/file-upload-12.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { AlertCircleIcon, FileArchiveIcon, FileIcon, FileSpreadsheetIcon, FileTextIcon, HeadphonesIcon, ImageIcon, Trash2Icon, UploadIcon, VideoIcon, XIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { formatBytes, useFileUpload, type FileWithPreview } from '@/registry/default/hooks/use-file-upload-vue';\n\nconst initialFiles = [\n  {\n    name: 'intro.zip',\n    size: 252873,\n    type: 'application/zip',\n    url: 'https://example.com/intro.zip',\n    id: 'intro.zip-1744638436563-8u5xuls',\n  },\n  {\n    name: 'image-01.jpg',\n    size: 1528737,\n    type: 'image/jpeg',\n    url: 'https://picsum.photos/1000/800?grayscale&random=1',\n    id: 'image-01-123456789',\n  },\n  {\n    name: 'audio.mp3',\n    size: 1528737,\n    type: 'audio/mpeg',\n    url: 'https://example.com/audio.mp3',\n    id: 'audio-123456789',\n  },\n];\n\nconst maxSizeMB = 5;\nconst maxSize = maxSizeMB * 1024 * 1024;\nconst maxFiles = 6;\n\nconst [\n  { files, isDragging, errors },\n  {\n    handleDragEnter,\n    handleDragLeave,\n    handleDragOver,\n    handleDrop,\n    openFileDialog,\n    removeFile,\n    clearFiles,\n  },\n] = useFileUpload({\n  multiple: true,\n  maxFiles,\n  maxSize,\n  initialFiles,\n});\n\nfunction getFileIcon(file: FileWithPreview) {\n  const fileType = file.file.type;\n  const fileName = file.file.name;\n\n  if (\n    fileType.includes('pdf') ||\n    fileType.includes('word') ||\n    fileName.endsWith('.pdf') ||\n    fileName.endsWith('.doc') ||\n    fileName.endsWith('.docx')\n  ) {\n    return FileTextIcon;\n  }\n\n  if (\n    fileType.includes('zip') ||\n    fileType.includes('archive') ||\n    fileName.endsWith('.zip') ||\n    fileName.endsWith('.rar')\n  ) {\n    return FileArchiveIcon;\n  }\n\n  if (\n    fileType.includes('excel') ||\n    fileName.endsWith('.xls') ||\n    fileName.endsWith('.xlsx')\n  ) {\n    return FileSpreadsheetIcon;\n  }\n\n  if (fileType.includes('video/')) return VideoIcon;\n  if (fileType.includes('audio/')) return HeadphonesIcon;\n  if (fileType.startsWith('image/')) return ImageIcon;\n  return FileIcon;\n}\n\nfunction getFilePreview(file: FileWithPreview) {\n  if (file.file.type.startsWith('image/')) {\n    return file.preview;\n  }\n  return null;\n}\n</script>\n\n<template>\n  <div class=\"flex flex-col gap-2\"><div @dragenter=\"handleDragEnter\" @dragleave=\"handleDragLeave\" @dragover=\"handleDragOver\" @drop=\"handleDrop\" :data-dragging=\"isDragging || undefined\" :data-files=\"files.length > 0 || undefined\" class=\"border-input data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 relative flex min-h-52 flex-col items-center overflow-hidden rounded-xl border border-dashed p-4 transition-colors not-data-[files]:justify-center has-[input:focus]:ring-[3px]\"><input class=\"sr-only\" aria-label=\"Upload image file\" /><template v-if=\"files.length > 0\">\n<div class=\"flex w-full flex-col gap-3\"><div class=\"flex items-center justify-between gap-2\"><h3 class=\"truncate text-sm font-medium\">Files ({{ files.length }})</h3><div class=\"flex gap-2\"><Button variant=\"outline\" size=\"sm\" @click=\"openFileDialog\"><UploadIcon class=\"-ms-0.5 size-3.5 opacity-60\" aria-hidden=\"true\" />Add files\n                </Button><Button variant=\"outline\" size=\"sm\" @click=\"clearFiles\"><Trash2Icon class=\"-ms-0.5 size-3.5 opacity-60\" aria-hidden=\"true\" />Remove all\n                </Button></div></div><div class=\"grid grid-cols-2 gap-4 md:grid-cols-3\"><div v-for=\"(file, index) in files\" :key=\"file.id\" class=\"bg-background relative flex flex-col rounded-md border\"><div class=\"bg-accent flex aspect-square items-center justify-center overflow-hidden rounded-t-[inherit]\"><img v-if=\"getFilePreview(file)\" :src=\"getFilePreview(file) || ''\" :alt=\"file.file.name\" class=\"size-full rounded-t-[inherit] object-cover\" /><component v-else :is=\"getFileIcon(file)\" class=\"size-5 opacity-60\" /></div><Button @click=\"removeFile(file.id)\" size=\"icon\" class=\"border-background focus-visible:border-background absolute -top-2 -right-2 size-6 rounded-full border-2 shadow-none\" aria-label=\"Remove image\"><XIcon class=\"size-3.5\" /></Button><div class=\"flex min-w-0 flex-col gap-0.5 border-t p-3\"><p class=\"truncate text-[13px] font-medium\">{{ file.file.name }}</p><p class=\"text-muted-foreground truncate text-xs\">{{ formatBytes(file.file.size) }}</p></div></div></div></div>\n</template>\n<template v-else>\n<div class=\"flex flex-col items-center justify-center px-4 py-3 text-center\"><div class=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><ImageIcon class=\"size-4 opacity-60\" /></div><p class=\"mb-1.5 text-sm font-medium\">Drop your files here</p><p class=\"text-muted-foreground text-xs\">Max {{ maxFiles }}files ∙ Up to {{ maxSizeMB }}MB\n            </p><Button variant=\"outline\" class=\"mt-4\" @click=\"openFileDialog\"><UploadIcon class=\"-ms-1 opacity-60\" aria-hidden=\"true\" />Select images\n            </Button></div>\n</template></div><div v-if=\"errors.length > 0\" class=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\"><AlertCircleIcon class=\"size-3 shrink-0\" /><span>{{ errors[0] }}</span></div><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-center text-xs\">Mixed content w/ card ∙{{ ' ' }}<a href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\" class=\"hover:text-foreground underline\">API\n        </a></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/file-upload/file-upload-12.html",
          "target": "components/ui/file-upload-12.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex flex-col gap-2\"><div ondragenter=\"${handleDragEnter}\" ondragleave=\"${handleDragLeave}\" ondragover=\"${handleDragOver}\" ondrop=\"${handleDrop}\" data-dragging=\"${isDragging || undefined}\" data-files=\"${files.length > 0 || undefined}\" class=\"border-input data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 relative flex min-h-52 flex-col items-center overflow-hidden rounded-xl border border-dashed p-4 transition-colors not-data-[files]:justify-center has-[input:focus]:ring-[3px]\"><input class=\"sr-only\" aria-label=\"Upload image file\" /><!-- if files.length > 0 -->\n<div class=\"flex w-full flex-col gap-3\"><div class=\"flex items-center justify-between gap-2\"><h3 class=\"truncate text-sm font-medium\">Files (${files.length})</h3><div class=\"flex gap-2\"><Button variant=\"outline\" size=\"sm\" on-click=\"${openFileDialog}\"><UploadIcon class=\"-ms-0.5 size-3.5 opacity-60\" aria-hidden=\"true\" />Add files\n                </Button><Button variant=\"outline\" size=\"sm\" on-click=\"${clearFiles}\"><Trash2Icon class=\"-ms-0.5 size-3.5 opacity-60\" aria-hidden=\"true\" />Remove all\n                </Button></div></div><div class=\"grid grid-cols-2 gap-4 md:grid-cols-3\"><!-- Loop files -->\n<div key=\"${file.id}\" class=\"bg-background relative flex flex-col rounded-md border\">${getFilePreview(file)}<Button on-click=\"${() => removeFile(file.id)}\" size=\"icon\" class=\"border-background focus-visible:border-background absolute -top-2 -right-2 size-6 rounded-full border-2 shadow-none\" aria-label=\"Remove image\"><XIcon class=\"size-3.5\" /></Button><div class=\"flex min-w-0 flex-col gap-0.5 border-t p-3\"><p class=\"truncate text-[13px] font-medium\">${file.file.name}</p><p class=\"text-muted-foreground truncate text-xs\">${formatBytes(file.file.size)}</p></div></div>\n<!-- End Loop --></div></div>\n<!-- else -->\n<div class=\"flex flex-col items-center justify-center px-4 py-3 text-center\"><div class=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><ImageIcon class=\"size-4 opacity-60\" /></div><p class=\"mb-1.5 text-sm font-medium\">Drop your files here</p><p class=\"text-muted-foreground text-xs\">Max ${maxFiles}files ∙ Up to ${maxSizeMB}MB\n            </p><Button variant=\"outline\" class=\"mt-4\" on-click=\"${openFileDialog}\"><UploadIcon class=\"-ms-1 opacity-60\" aria-hidden=\"true\" />Select images\n            </Button></div>\n<!-- endif --></div><!-- if errors.length > 0 -->\n<div class=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\"><AlertCircleIcon class=\"size-3 shrink-0\" /><span>${errors[0]}</span></div>\n<!-- endif --><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-center text-xs\">Mixed content w/ card ∙${' '}<a href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\" class=\"hover:text-foreground underline\">API\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/file-upload/file-upload-12.wxml",
          "target": "components/ui/file-upload-12/file-upload-12.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex flex-col gap-2\"><view ondragenter=\"{{handleDragEnter}}\" ondragleave=\"{{handleDragLeave}}\" ondragover=\"{{handleDragOver}}\" ondrop=\"{{handleDrop}}\" data-dragging=\"{{isDragging || undefined}}\" data-files=\"{{files.length > 0 || undefined}}\" class=\"border-input data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 relative flex min-h-52 flex-col items-center overflow-hidden rounded-xl border border-dashed p-4 transition-colors not-data-[files]:justify-center has-[input:focus]:ring-[3px]\"><input class=\"sr-only\" aria-label=\"Upload image file\" /><block wx:if=\"{{files.length > 0}}\">\n<view class=\"flex w-full flex-col gap-3\"><view class=\"flex items-center justify-between gap-2\"><h3 class=\"truncate text-sm font-medium\">Files ({{ files.length }})</h3><view class=\"flex gap-2\"><button variant=\"outline\" size=\"sm\" bindtap=\"openFileDialog\"><uploadicon class=\"-ms-0.5 size-3.5 opacity-60\" aria-hidden=\"true\" />Add files\n                </button><button variant=\"outline\" size=\"sm\" bindtap=\"clearFiles\"><trash2icon class=\"-ms-0.5 size-3.5 opacity-60\" aria-hidden=\"true\" />Remove all\n                </button></view></view><view class=\"grid grid-cols-2 gap-4 md:grid-cols-3\"><view wx:for=\"{{files}}\" wx:for-item=\"file\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{file.id}}\" class=\"bg-background relative flex flex-col rounded-md border\">{{ getFilePreview(file) }}<button bindtap=\"removeFile(file.id)\" size=\"icon\" class=\"border-background focus-visible:border-background absolute -top-2 -right-2 size-6 rounded-full border-2 shadow-none\" aria-label=\"Remove image\"><xicon class=\"size-3.5\" /></button><view class=\"flex min-w-0 flex-col gap-0.5 border-t p-3\"><text class=\"truncate text-[13px] font-medium\">{{ file.file.name }}</text><text class=\"text-muted-foreground truncate text-xs\">{{ formatBytes(file.file.size) }}</text></view></view></view></view>\n</block>\n<block wx:else>\n<view class=\"flex flex-col items-center justify-center px-4 py-3 text-center\"><view class=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><imageicon class=\"size-4 opacity-60\" /></view><text class=\"mb-1.5 text-sm font-medium\">Drop your files here</text><text class=\"text-muted-foreground text-xs\">Max {{ maxFiles }}files ∙ Up to {{ maxSizeMB }}MB\n            </text><button variant=\"outline\" class=\"mt-4\" bindtap=\"openFileDialog\"><uploadicon class=\"-ms-1 opacity-60\" aria-hidden=\"true\" />Select images\n            </button></view>\n</block></view><view wx:if=\"{{errors.length > 0}}\" class=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\"><alertcircleicon class=\"size-3 shrink-0\" /><text>{{ errors[0] }}</text></view><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-center text-xs\">Mixed content w/ card ∙{{ ' ' }}<a href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\" class=\"hover:text-foreground underline\">API\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "upload",
          "file",
          "image",
          "drag and drop"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "file-upload-12",
          "group": "file-upload",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "file-upload-12",
              "path": "registry/default/components/file-upload/file-upload-12.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "file-upload-12",
              "path": "registry/default/components/file-upload/file-upload-12.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "file-upload-12",
              "path": "registry/default/components/file-upload/file-upload-12.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "file-upload-12",
              "path": "registry/default/components/file-upload/file-upload-12.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "file-upload",
        "title": "File Upload · Files ({files.length})"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "file-upload"
      ]
    },
    {
      "name": "file-upload-13",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/file-upload/file-upload-13.tsx",
          "type": "registry:component",
          "target": "components/ui/file-upload-13.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Button } from '@timui/react'\nimport {\n  AlertCircleIcon,\n  FileArchiveIcon,\n  FileIcon,\n  FileSpreadsheetIcon,\n  FileTextIcon,\n  HeadphonesIcon,\n  ImageIcon,\n  Trash2Icon,\n  UploadIcon,\n  VideoIcon,\n  XIcon,\n} from 'lucide-react'\n\nimport {\n  formatBytes,\n  useFileUpload,\n  type FileWithPreview,\n} from '@/registry/default/hooks/use-file-upload'\n\n// Create some dummy initial files\nconst initialFiles = [\n  {\n    name: 'intro.zip',\n    size: 252873,\n    type: 'application/zip',\n    url: 'https://example.com/intro.zip',\n    id: 'intro.zip-1744638436563-8u5xuls',\n  },\n  {\n    name: 'image-01.jpg',\n    size: 1528737,\n    type: 'image/jpeg',\n    url: 'https://picsum.photos/1000/800?grayscale&random=1',\n    id: 'image-01-123456789',\n  },\n  {\n    name: 'audio.mp3',\n    size: 1528737,\n    type: 'audio/mpeg',\n    url: 'https://example.com/audio.mp3',\n    id: 'audio-123456789',\n  },\n]\n\nconst getFileIcon = (file: { file: File | { type: string; name: string } }) => {\n  const fileType = file.file instanceof File ? file.file.type : file.file.type\n  const fileName = file.file instanceof File ? file.file.name : file.file.name\n\n  const iconMap = {\n    pdf: {\n      icon: FileTextIcon,\n      conditions: (type: string, name: string) =>\n        type.includes('pdf') ||\n        name.endsWith('.pdf') ||\n        type.includes('word') ||\n        name.endsWith('.doc') ||\n        name.endsWith('.docx'),\n    },\n    archive: {\n      icon: FileArchiveIcon,\n      conditions: (type: string, name: string) =>\n        type.includes('zip') ||\n        type.includes('archive') ||\n        name.endsWith('.zip') ||\n        name.endsWith('.rar'),\n    },\n    excel: {\n      icon: FileSpreadsheetIcon,\n      conditions: (type: string, name: string) =>\n        type.includes('excel') || name.endsWith('.xls') || name.endsWith('.xlsx'),\n    },\n    video: {\n      icon: VideoIcon,\n      conditions: (type: string) => type.includes('video/'),\n    },\n    audio: {\n      icon: HeadphonesIcon,\n      conditions: (type: string) => type.includes('audio/'),\n    },\n    image: {\n      icon: ImageIcon,\n      conditions: (type: string) => type.startsWith('image/'),\n    },\n  }\n\n  for (const { icon: Icon, conditions } of Object.values(iconMap)) {\n    if (conditions(fileType, fileName)) {\n      return <Icon className=\"size-5 opacity-60\" />\n    }\n  }\n\n  return <FileIcon className=\"size-5 opacity-60\" />\n}\n\nconst getFilePreview = (file: { file: File | { type: string; name: string; url?: string } }) => {\n  const fileType = file.file instanceof File ? file.file.type : file.file.type\n  const fileName = file.file instanceof File ? file.file.name : file.file.name\n\n  const renderImage = (src: string) => (\n    <img src={src} alt={fileName} className=\"size-full rounded-t-[inherit] object-cover\" />\n  )\n\n  return (\n    <div className=\"bg-accent flex aspect-square items-center justify-center overflow-hidden rounded-t-[inherit]\">\n      {fileType.startsWith('image/') ? (\n        file.file instanceof File ? (\n          (() => {\n            const previewUrl = URL.createObjectURL(file.file)\n            return renderImage(previewUrl)\n          })()\n        ) : file.file.url ? (\n          renderImage(file.file.url)\n        ) : (\n          <ImageIcon className=\"size-5 opacity-60\" />\n        )\n      ) : (\n        getFileIcon(file)\n      )}\n    </div>\n  )\n}\n\n// Type for tracking upload progress\ntype UploadProgress = {\n  fileId: string\n  progress: number\n  completed: boolean\n}\n\n// Function to simulate file upload with more realistic timing and progress\nconst simulateUpload = (\n  totalBytes: number,\n  onProgress: (progress: number) => void,\n  onComplete: () => void\n) => {\n  let timeoutId: NodeJS.Timeout\n  let uploadedBytes = 0\n  let lastProgressReport = 0\n\n  const simulateChunk = () => {\n    // Simulate variable network conditions with random chunk sizes\n    const chunkSize = Math.floor(Math.random() * 300000) + 2000\n    uploadedBytes = Math.min(totalBytes, uploadedBytes + chunkSize)\n\n    // Calculate progress percentage (0-100)\n    const progressPercent = Math.floor((uploadedBytes / totalBytes) * 100)\n\n    // Only report progress if it's changed by at least 1%\n    if (progressPercent > lastProgressReport) {\n      lastProgressReport = progressPercent\n      onProgress(progressPercent)\n    }\n\n    // Continue simulation if not complete\n    if (uploadedBytes < totalBytes) {\n      // Variable delay between 50ms and 500ms to simulate network fluctuations (reduced for faster uploads)\n      const delay = Math.floor(Math.random() * 450) + 50\n\n      // Occasionally add a longer pause to simulate network congestion (5% chance, shorter duration)\n      const extraDelay = Math.random() < 0.05 ? 500 : 0\n\n      timeoutId = setTimeout(simulateChunk, delay + extraDelay)\n    } else {\n      // Upload complete\n      onComplete()\n    }\n  }\n\n  // Start the simulation\n  timeoutId = setTimeout(simulateChunk, 100)\n\n  // Return a cleanup function to cancel the simulation\n  return () => {\n    if (timeoutId) {\n      clearTimeout(timeoutId)\n    }\n  }\n}\n\nexport default function Component() {\n  const maxSizeMB = 5\n  const maxSize = maxSizeMB * 1024 * 1024 // 5MB default\n  const maxFiles = 6\n\n  // State to track upload progress for each file\n  const [uploadProgress, setUploadProgress] = useState<UploadProgress[]>([])\n\n  // Function to handle newly added files\n  const handleFilesAdded = (addedFiles: FileWithPreview[]) => {\n    // Initialize progress tracking for each new file\n    const newProgressItems = addedFiles.map((file) => ({\n      fileId: file.id,\n      progress: 0,\n      completed: false,\n    }))\n\n    // Add new progress items to state\n    setUploadProgress((prev) => [...prev, ...newProgressItems])\n\n    // Store cleanup functions\n    const cleanupFunctions: Array<() => void> = []\n\n    // Start simulated upload for each file\n    addedFiles.forEach((file) => {\n      const fileSize = file.file instanceof File ? file.file.size : file.file.size\n\n      // Start the upload simulation and store the cleanup function\n      const cleanup = simulateUpload(\n        fileSize,\n        // Progress callback\n        (progress) => {\n          setUploadProgress((prev) =>\n            prev.map((item) => (item.fileId === file.id ? { ...item, progress } : item))\n          )\n        },\n        // Complete callback\n        () => {\n          setUploadProgress((prev) =>\n            prev.map((item) => (item.fileId === file.id ? { ...item, completed: true } : item))\n          )\n        }\n      )\n\n      cleanupFunctions.push(cleanup)\n    })\n\n    // Return a cleanup function that cancels all animations\n    return () => {\n      cleanupFunctions.forEach((cleanup) => cleanup())\n    }\n  }\n\n  // Remove the progress tracking for the file\n  const handleFileRemoved = (fileId: string) => {\n    setUploadProgress((prev) => prev.filter((item) => item.fileId !== fileId))\n  }\n\n  const [\n    { files, isDragging, errors },\n    {\n      handleDragEnter,\n      handleDragLeave,\n      handleDragOver,\n      handleDrop,\n      openFileDialog,\n      removeFile,\n      clearFiles,\n      getInputProps,\n    },\n  ] = useFileUpload({\n    multiple: true,\n    maxFiles,\n    maxSize,\n    initialFiles,\n    onFilesAdded: handleFilesAdded,\n  })\n\n  return (\n    <div className=\"flex flex-col gap-2\">\n      {/* Drop area */}\n      <div\n        onDragEnter={handleDragEnter}\n        onDragLeave={handleDragLeave}\n        onDragOver={handleDragOver}\n        onDrop={handleDrop}\n        data-dragging={isDragging || undefined}\n        data-files={files.length > 0 || undefined}\n        className=\"border-input data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 relative flex min-h-52 flex-col items-center overflow-hidden rounded-xl border border-dashed p-4 transition-colors not-data-[files]:justify-center has-[input:focus]:ring-[3px]\"\n      >\n        <input {...getInputProps()} className=\"sr-only\" aria-label=\"Upload image file\" />\n        {files.length > 0 ? (\n          <div className=\"flex w-full flex-col gap-3\">\n            <div className=\"flex items-center justify-between gap-2\">\n              <h3 className=\"truncate text-sm font-medium\">Files ({files.length})</h3>\n              <div className=\"flex gap-2\">\n                <Button variant=\"outline\" size=\"sm\" onClick={openFileDialog}>\n                  <UploadIcon className=\"-ms-0.5 size-3.5 opacity-60\" aria-hidden=\"true\" />\n                  Add files\n                </Button>\n                <Button\n                  variant=\"outline\"\n                  size=\"sm\"\n                  onClick={() => {\n                    // Clear all progress tracking\n                    setUploadProgress([])\n                    clearFiles()\n                  }}\n                >\n                  <Trash2Icon className=\"-ms-0.5 size-3.5 opacity-60\" aria-hidden=\"true\" />\n                  Remove all\n                </Button>\n              </div>\n            </div>\n\n            <div className=\"w-full space-y-2\">\n              {files.map((file) => {\n                // Find the upload progress for this file once to avoid repeated lookups\n                const fileProgress = uploadProgress.find((p) => p.fileId === file.id)\n                const isUploading = fileProgress && !fileProgress.completed\n\n                return (\n                  <div\n                    key={file.id}\n                    data-uploading={isUploading || undefined}\n                    className=\"bg-background flex flex-col gap-1 rounded-lg border p-2 pe-3 transition-opacity duration-300\"\n                  >\n                    <div className=\"flex items-center justify-between gap-2\">\n                      <div className=\"flex items-center gap-3 overflow-hidden in-data-[uploading=true]:opacity-50\">\n                        <div className=\"flex aspect-square size-10 shrink-0 items-center justify-center rounded border\">\n                          {getFileIcon(file)}\n                        </div>\n                        <div className=\"flex min-w-0 flex-col gap-0.5\">\n                          <p className=\"truncate text-[13px] font-medium\">\n                            {file.file instanceof File ? file.file.name : file.file.name}\n                          </p>\n                          <p className=\"text-muted-foreground text-xs\">\n                            {formatBytes(\n                              file.file instanceof File ? file.file.size : file.file.size\n                            )}\n                          </p>\n                        </div>\n                      </div>\n                      <Button\n                        size=\"icon\"\n                        variant=\"ghost\"\n                        className=\"text-muted-foreground/80 hover:text-foreground -me-2 size-8 hover:bg-transparent\"\n                        onClick={() => {\n                          handleFileRemoved(file.id)\n                          removeFile(file.id)\n                        }}\n                        aria-label=\"Remove file\"\n                      >\n                        <XIcon className=\"size-4\" aria-hidden=\"true\" />\n                      </Button>\n                    </div>\n\n                    {/* Upload progress bar */}\n                    {fileProgress &&\n                      (() => {\n                        const progress = fileProgress.progress || 0\n                        const completed = fileProgress.completed || false\n\n                        if (completed) return null\n\n                        return (\n                          <div className=\"mt-1 flex items-center gap-2\">\n                            <div className=\"h-1.5 w-full overflow-hidden rounded-full bg-gray-100\">\n                              <div\n                                className=\"bg-primary h-full transition-all duration-300 ease-out\"\n                                style={{ width: `${progress}%` }}\n                              />\n                            </div>\n                            <span className=\"text-muted-foreground w-10 text-xs tabular-nums\">\n                              {progress}%\n                            </span>\n                          </div>\n                        )\n                      })()}\n                  </div>\n                )\n              })}\n            </div>\n          </div>\n        ) : (\n          <div className=\"flex flex-col items-center justify-center px-4 py-3 text-center\">\n            <div\n              className=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\"\n              aria-hidden=\"true\"\n            >\n              <ImageIcon className=\"size-4 opacity-60\" />\n            </div>\n            <p className=\"mb-1.5 text-sm font-medium\">Drop your files here</p>\n            <p className=\"text-muted-foreground text-xs\">\n              Max {maxFiles} files ∙ Up to {maxSizeMB}MB\n            </p>\n            <Button variant=\"outline\" className=\"mt-4\" onClick={openFileDialog}>\n              <UploadIcon className=\"-ms-1 opacity-60\" aria-hidden=\"true\" />\n              Select images\n            </Button>\n          </div>\n        )}\n      </div>\n\n      {errors.length > 0 && (\n        <div className=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\">\n          <AlertCircleIcon className=\"size-3 shrink-0\" />\n          <span>{errors[0]}</span>\n        </div>\n      )}\n\n      <p\n        aria-live=\"polite\"\n        role=\"region\"\n        className=\"text-muted-foreground mt-2 text-center text-xs\"\n      >\n        With simulated progress track ∙{' '}\n        <a\n          href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\"\n          className=\"hover:text-foreground underline\"\n          target=\"_blank\"\n        >\n          API\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/hooks/use-file-upload.ts",
          "type": "registry:hook",
          "target": "components/ui/file-upload-13/use-file-upload.ts",
          "content": "'use client'\n\nimport type React from 'react'\nimport {\n  useCallback,\n  useRef,\n  useState,\n  type ChangeEvent,\n  type DragEvent,\n  type InputHTMLAttributes,\n} from 'react'\n\nexport type FileMetadata = {\n  name: string\n  size: number\n  type: string\n  url: string\n  id: string\n}\n\nexport type FileWithPreview = {\n  file: File | FileMetadata\n  id: string\n  preview?: string\n}\n\nexport type FileUploadOptions = {\n  maxFiles?: number // Only used when multiple is true, defaults to Infinity\n  maxSize?: number // in bytes\n  accept?: string\n  multiple?: boolean // Defaults to false\n  initialFiles?: FileMetadata[]\n  onFilesChange?: (files: FileWithPreview[]) => void // Callback when files change\n  onFilesAdded?: (addedFiles: FileWithPreview[]) => void // Callback when new files are added\n}\n\nexport type FileUploadState = {\n  files: FileWithPreview[]\n  isDragging: boolean\n  errors: string[]\n}\n\nexport type FileUploadActions = {\n  addFiles: (files: FileList | File[]) => void\n  removeFile: (id: string) => void\n  clearFiles: () => void\n  clearErrors: () => void\n  handleDragEnter: (e: DragEvent<HTMLElement>) => void\n  handleDragLeave: (e: DragEvent<HTMLElement>) => void\n  handleDragOver: (e: DragEvent<HTMLElement>) => void\n  handleDrop: (e: DragEvent<HTMLElement>) => void\n  handleFileChange: (e: ChangeEvent<HTMLInputElement>) => void\n  openFileDialog: () => void\n  getInputProps: (\n    props?: InputHTMLAttributes<HTMLInputElement>\n  ) => InputHTMLAttributes<HTMLInputElement> & {\n    ref: React.Ref<HTMLInputElement>\n  }\n}\n\nexport const useFileUpload = (\n  options: FileUploadOptions = {}\n): [FileUploadState, FileUploadActions] => {\n  const {\n    maxFiles = Infinity,\n    maxSize = Infinity,\n    accept = '*',\n    multiple = false,\n    initialFiles = [],\n    onFilesChange,\n    onFilesAdded,\n  } = options\n\n  const [state, setState] = useState<FileUploadState>({\n    files: initialFiles.map((file) => ({\n      file,\n      id: file.id,\n      preview: file.url,\n    })),\n    isDragging: false,\n    errors: [],\n  })\n\n  const inputRef = useRef<HTMLInputElement>(null)\n\n  const validateFile = useCallback(\n    (file: File | FileMetadata): string | null => {\n      if (file instanceof File) {\n        if (file.size > maxSize) {\n          return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n        }\n      } else {\n        if (file.size > maxSize) {\n          return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n        }\n      }\n\n      if (accept !== '*') {\n        const acceptedTypes = accept.split(',').map((type) => type.trim())\n        const fileType = file instanceof File ? file.type || '' : file.type\n        const fileExtension = `.${file instanceof File ? file.name.split('.').pop() : file.name.split('.').pop()}`\n\n        const isAccepted = acceptedTypes.some((type) => {\n          if (type.startsWith('.')) {\n            return fileExtension.toLowerCase() === type.toLowerCase()\n          }\n          if (type.endsWith('/*')) {\n            const baseType = type.split('/')[0]\n            return fileType.startsWith(`${baseType}/`)\n          }\n          return fileType === type\n        })\n\n        if (!isAccepted) {\n          return `File \"${file instanceof File ? file.name : file.name}\" is not an accepted file type.`\n        }\n      }\n\n      return null\n    },\n    [accept, maxSize]\n  )\n\n  const createPreview = useCallback((file: File | FileMetadata): string | undefined => {\n    if (file instanceof File) {\n      return URL.createObjectURL(file)\n    }\n    return file.url\n  }, [])\n\n  const generateUniqueId = useCallback((file: File | FileMetadata): string => {\n    if (file instanceof File) {\n      return `${file.name}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`\n    }\n    return file.id\n  }, [])\n\n  const clearFiles = useCallback(() => {\n    setState((prev) => {\n      // Clean up object URLs\n      prev.files.forEach((file) => {\n        if (file.preview && file.file instanceof File && file.file.type.startsWith('image/')) {\n          URL.revokeObjectURL(file.preview)\n        }\n      })\n\n      if (inputRef.current) {\n        inputRef.current.value = ''\n      }\n\n      const newState = {\n        ...prev,\n        files: [],\n        errors: [],\n      }\n\n      onFilesChange?.(newState.files)\n      return newState\n    })\n  }, [onFilesChange])\n\n  const addFiles = useCallback(\n    (newFiles: FileList | File[]) => {\n      if (!newFiles || newFiles.length === 0) return\n\n      const newFilesArray = Array.from(newFiles)\n      const errors: string[] = []\n\n      // Clear existing errors when new files are uploaded\n      setState((prev) => ({ ...prev, errors: [] }))\n\n      // In single file mode, clear existing files first\n      if (!multiple) {\n        clearFiles()\n      }\n\n      // Check if adding these files would exceed maxFiles (only in multiple mode)\n      if (\n        multiple &&\n        maxFiles !== Infinity &&\n        state.files.length + newFilesArray.length > maxFiles\n      ) {\n        errors.push(`You can only upload a maximum of ${maxFiles} files.`)\n        setState((prev) => ({ ...prev, errors }))\n        return\n      }\n\n      const validFiles: FileWithPreview[] = []\n\n      newFilesArray.forEach((file) => {\n        // Only check for duplicates if multiple files are allowed\n        if (multiple) {\n          const isDuplicate = state.files.some(\n            (existingFile) =>\n              existingFile.file.name === file.name && existingFile.file.size === file.size\n          )\n\n          // Skip duplicate files silently\n          if (isDuplicate) {\n            return\n          }\n        }\n\n        // Check file size\n        if (file.size > maxSize) {\n          errors.push(\n            multiple\n              ? `Some files exceed the maximum size of ${formatBytes(maxSize)}.`\n              : `File exceeds the maximum size of ${formatBytes(maxSize)}.`\n          )\n          return\n        }\n\n        const error = validateFile(file)\n        if (error) {\n          errors.push(error)\n        } else {\n          validFiles.push({\n            file,\n            id: generateUniqueId(file),\n            preview: createPreview(file),\n          })\n        }\n      })\n\n      // Only update state if we have valid files to add\n      if (validFiles.length > 0) {\n        // Call the onFilesAdded callback with the newly added valid files\n        onFilesAdded?.(validFiles)\n\n        setState((prev) => {\n          const newFiles = !multiple ? validFiles : [...prev.files, ...validFiles]\n          onFilesChange?.(newFiles)\n          return {\n            ...prev,\n            files: newFiles,\n            errors,\n          }\n        })\n      } else if (errors.length > 0) {\n        setState((prev) => ({\n          ...prev,\n          errors,\n        }))\n      }\n\n      // Reset input value after handling files\n      if (inputRef.current) {\n        inputRef.current.value = ''\n      }\n    },\n    [\n      state.files,\n      maxFiles,\n      multiple,\n      maxSize,\n      validateFile,\n      createPreview,\n      generateUniqueId,\n      clearFiles,\n      onFilesChange,\n      onFilesAdded,\n    ]\n  )\n\n  const removeFile = useCallback(\n    (id: string) => {\n      setState((prev) => {\n        const fileToRemove = prev.files.find((file) => file.id === id)\n        if (\n          fileToRemove &&\n          fileToRemove.preview &&\n          fileToRemove.file instanceof File &&\n          fileToRemove.file.type.startsWith('image/')\n        ) {\n          URL.revokeObjectURL(fileToRemove.preview)\n        }\n\n        const newFiles = prev.files.filter((file) => file.id !== id)\n        onFilesChange?.(newFiles)\n\n        return {\n          ...prev,\n          files: newFiles,\n          errors: [],\n        }\n      })\n    },\n    [onFilesChange]\n  )\n\n  const clearErrors = useCallback(() => {\n    setState((prev) => ({\n      ...prev,\n      errors: [],\n    }))\n  }, [])\n\n  const handleDragEnter = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n    setState((prev) => ({ ...prev, isDragging: true }))\n  }, [])\n\n  const handleDragLeave = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n\n    if (e.currentTarget.contains(e.relatedTarget as Node)) {\n      return\n    }\n\n    setState((prev) => ({ ...prev, isDragging: false }))\n  }, [])\n\n  const handleDragOver = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n  }, [])\n\n  const handleDrop = useCallback(\n    (e: DragEvent<HTMLElement>) => {\n      e.preventDefault()\n      e.stopPropagation()\n      setState((prev) => ({ ...prev, isDragging: false }))\n\n      // Don't process files if the input is disabled\n      if (inputRef.current?.disabled) {\n        return\n      }\n\n      if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n        // In single file mode, only use the first file\n        if (!multiple) {\n          const file = e.dataTransfer.files[0]\n          addFiles([file])\n        } else {\n          addFiles(e.dataTransfer.files)\n        }\n      }\n    },\n    [addFiles, multiple]\n  )\n\n  const handleFileChange = useCallback(\n    (e: ChangeEvent<HTMLInputElement>) => {\n      if (e.target.files && e.target.files.length > 0) {\n        addFiles(e.target.files)\n      }\n    },\n    [addFiles]\n  )\n\n  const openFileDialog = useCallback(() => {\n    if (inputRef.current) {\n      inputRef.current.click()\n    }\n  }, [])\n\n  const getInputProps = useCallback(\n    (props: InputHTMLAttributes<HTMLInputElement> = {}) => {\n      return {\n        ...props,\n        type: 'file' as const,\n        onChange: handleFileChange,\n        accept: props.accept || accept,\n        multiple: props.multiple !== undefined ? props.multiple : multiple,\n        ref: inputRef,\n      }\n    },\n    [accept, multiple, handleFileChange]\n  )\n\n  return [\n    state,\n    {\n      addFiles,\n      removeFile,\n      clearFiles,\n      clearErrors,\n      handleDragEnter,\n      handleDragLeave,\n      handleDragOver,\n      handleDrop,\n      handleFileChange,\n      openFileDialog,\n      getInputProps,\n    },\n  ]\n}\n\n// Helper function to format bytes to human-readable format\nexport const formatBytes = (bytes: number, decimals = 2): string => {\n  if (bytes === 0) return '0 Bytes'\n\n  const k = 1024\n  const dm = decimals < 0 ? 0 : decimals\n  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']\n\n  const i = Math.floor(Math.log(bytes) / Math.log(k))\n\n  return Number.parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + sizes[i]\n}\n"
        },
        {
          "path": "registry/default/components/file-upload/file-upload-13.vue",
          "target": "components/ui/file-upload-13.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, reactive, ref } from 'vue'\nimport {\n  AlertCircleIcon,\n  FileArchiveIcon,\n  FileIcon,\n  FileSpreadsheetIcon,\n  FileTextIcon,\n  HeadphonesIcon,\n  ImageIcon,\n  Trash2Icon,\n  UploadIcon,\n  VideoIcon,\n  XIcon,\n} from 'lucide-vue-next'\nimport { Button } from '@timui/vue'\n\ntype UploadFile = {\n  id: string\n  name: string\n  size: number\n  type: string\n  url?: string\n  file?: File\n  preview?: string\n}\n\ntype UploadProgress = {\n  progress: number\n  completed: boolean\n}\n\nconst maxSizeMB = 5\nconst maxSize = maxSizeMB * 1024 * 1024\nconst maxFiles = 6\n\nconst inputRef = ref<HTMLInputElement | null>(null)\nconst isDragging = ref(false)\nconst errors = ref<string[]>([])\n\nconst files = ref<UploadFile[]>([\n  {\n    id: 'intro.zip-1744638436563-8u5xuls',\n    name: 'intro.zip',\n    size: 252873,\n    type: 'application/zip',\n    url: 'https://example.com/intro.zip',\n  },\n  {\n    id: 'image-01-123456789',\n    name: 'image-01.jpg',\n    size: 1528737,\n    type: 'image/jpeg',\n    url: 'https://picsum.photos/1000/800?grayscale&random=1',\n  },\n  {\n    id: 'audio-123456789',\n    name: 'audio.mp3',\n    size: 1528737,\n    type: 'audio/mpeg',\n    url: 'https://example.com/audio.mp3',\n  },\n])\n\nconst progressMap = reactive<Record<string, UploadProgress>>({})\nconst uploadTimers = new Map<string, number>()\n\nfunction randomId(file: File) {\n  return `${file.name}-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`\n}\n\nfunction formatBytes(bytes: number, decimals = 2): string {\n  if (bytes === 0) return '0 Bytes'\n\n  const k = 1024\n  const dm = decimals < 0 ? 0 : decimals\n  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']\n  const i = Math.floor(Math.log(bytes) / Math.log(k))\n\n  return `${Number.parseFloat((bytes / k ** i).toFixed(dm))} ${sizes[i]}`\n}\n\nfunction getFileIcon(file: UploadFile) {\n  const fileType = file.type\n  const fileName = file.name.toLowerCase()\n\n  if (\n    fileType.includes('pdf') ||\n    fileType.includes('word') ||\n    fileName.endsWith('.pdf') ||\n    fileName.endsWith('.doc') ||\n    fileName.endsWith('.docx')\n  ) {\n    return FileTextIcon\n  }\n\n  if (\n    fileType.includes('zip') ||\n    fileType.includes('archive') ||\n    fileName.endsWith('.zip') ||\n    fileName.endsWith('.rar')\n  ) {\n    return FileArchiveIcon\n  }\n\n  if (\n    fileType.includes('excel') ||\n    fileName.endsWith('.xls') ||\n    fileName.endsWith('.xlsx')\n  ) {\n    return FileSpreadsheetIcon\n  }\n\n  if (fileType.includes('video/')) {\n    return VideoIcon\n  }\n\n  if (fileType.includes('audio/')) {\n    return HeadphonesIcon\n  }\n\n  if (fileType.startsWith('image/')) {\n    return ImageIcon\n  }\n\n  return FileIcon\n}\n\nfunction clearError() {\n  errors.value = []\n}\n\nfunction stopUpload(id: string) {\n  const timer = uploadTimers.get(id)\n  if (timer) {\n    window.clearInterval(timer)\n    uploadTimers.delete(id)\n  }\n}\n\nfunction startUpload(fileId: string, fileSize: number) {\n  stopUpload(fileId)\n\n  progressMap[fileId] = {\n    progress: 0,\n    completed: false,\n  }\n\n  let uploadedBytes = 0\n  const timer = window.setInterval(() => {\n    const chunkSize = Math.floor(Math.random() * 300000) + 2000\n    uploadedBytes = Math.min(fileSize, uploadedBytes + chunkSize)\n\n    const progress = Math.floor((uploadedBytes / fileSize) * 100)\n    progressMap[fileId].progress = progress\n\n    if (progress >= 100) {\n      progressMap[fileId].completed = true\n      stopUpload(fileId)\n    }\n  }, 120)\n\n  uploadTimers.set(fileId, timer)\n}\n\nfunction appendFiles(nextFiles: File[]) {\n  clearError()\n\n  if (!nextFiles.length) {\n    return\n  }\n\n  if (files.value.length + nextFiles.length > maxFiles) {\n    errors.value = [`You can only upload up to ${maxFiles} files.`]\n    return\n  }\n\n  const validFiles: UploadFile[] = []\n\n  nextFiles.forEach((file) => {\n    if (file.size > maxSize) {\n      errors.value = [\n        `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`,\n      ]\n      return\n    }\n\n    const id = randomId(file)\n\n    validFiles.push({\n      id,\n      name: file.name,\n      size: file.size,\n      type: file.type,\n      file,\n      preview: file.type.startsWith('image/') ? URL.createObjectURL(file) : undefined,\n    })\n  })\n\n  if (!validFiles.length) {\n    return\n  }\n\n  files.value = [...files.value, ...validFiles]\n\n  validFiles.forEach((file) => {\n    startUpload(file.id, file.size)\n  })\n\n  if (inputRef.value) {\n    inputRef.value.value = ''\n  }\n}\n\nfunction removeFile(fileId: string) {\n  const target = files.value.find((file) => file.id === fileId)\n\n  if (target?.preview) {\n    URL.revokeObjectURL(target.preview)\n  }\n\n  stopUpload(fileId)\n  delete progressMap[fileId]\n  files.value = files.value.filter((file) => file.id !== fileId)\n}\n\nfunction clearFiles() {\n  files.value.forEach((file) => {\n    if (file.preview) {\n      URL.revokeObjectURL(file.preview)\n    }\n    stopUpload(file.id)\n    delete progressMap[file.id]\n  })\n\n  files.value = []\n  clearError()\n\n  if (inputRef.value) {\n    inputRef.value.value = ''\n  }\n}\n\nfunction openFileDialog() {\n  inputRef.value?.click()\n}\n\nfunction handleInputChange(event: Event) {\n  const target = event.target as HTMLInputElement\n  if (!target.files) return\n  appendFiles(Array.from(target.files))\n}\n\nfunction handleDragEnter(event: DragEvent) {\n  event.preventDefault()\n  event.stopPropagation()\n  isDragging.value = true\n}\n\nfunction handleDragLeave(event: DragEvent) {\n  event.preventDefault()\n  event.stopPropagation()\n\n  const currentTarget = event.currentTarget as HTMLElement\n  if (currentTarget.contains(event.relatedTarget as Node)) {\n    return\n  }\n\n  isDragging.value = false\n}\n\nfunction handleDragOver(event: DragEvent) {\n  event.preventDefault()\n  event.stopPropagation()\n}\n\nfunction handleDrop(event: DragEvent) {\n  event.preventDefault()\n  event.stopPropagation()\n  isDragging.value = false\n\n  if (!event.dataTransfer?.files?.length) {\n    return\n  }\n\n  appendFiles(Array.from(event.dataTransfer.files))\n}\n\nconst fileCount = computed(() => files.value.length)\n\nonBeforeUnmount(() => {\n  clearFiles()\n})\n</script>\n\n<template>\n  <div class=\"flex flex-col gap-2\">\n    <div\n      :data-dragging=\"isDragging || undefined\"\n      :data-files=\"fileCount > 0 || undefined\"\n      class=\"border-input data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 relative flex min-h-52 flex-col items-center overflow-hidden rounded-xl border border-dashed p-4 transition-colors not-data-[files]:justify-center has-[input:focus]:ring-[3px]\"\n      @dragenter=\"handleDragEnter\"\n      @dragleave=\"handleDragLeave\"\n      @dragover=\"handleDragOver\"\n      @drop=\"handleDrop\"\n    >\n      <input\n        ref=\"inputRef\"\n        class=\"sr-only\"\n        type=\"file\"\n        multiple\n        :accept=\"'*'\"\n        aria-label=\"Upload file\"\n        @change=\"handleInputChange\"\n      />\n\n      <template v-if=\"fileCount > 0\">\n        <div class=\"flex w-full flex-col gap-3\">\n          <div class=\"flex items-center justify-between gap-2\">\n            <h3 class=\"truncate text-sm font-medium\">Files ({{ fileCount }})</h3>\n            <div class=\"flex gap-2\">\n              <Button variant=\"outline\" size=\"sm\" @click=\"openFileDialog\">\n                <UploadIcon class=\"-ms-0.5 size-3.5 opacity-60\" aria-hidden=\"true\" />\n                Add files\n              </Button>\n              <Button variant=\"outline\" size=\"sm\" @click=\"clearFiles\">\n                <Trash2Icon class=\"-ms-0.5 size-3.5 opacity-60\" aria-hidden=\"true\" />\n                Remove all\n              </Button>\n            </div>\n          </div>\n\n          <div class=\"w-full space-y-2\">\n            <div\n              v-for=\"file in files\"\n              :key=\"file.id\"\n              :data-uploading=\"progressMap[file.id] && !progressMap[file.id].completed ? true : undefined\"\n              class=\"bg-background flex flex-col gap-1 rounded-lg border p-2 pe-3 transition-opacity duration-300\"\n            >\n              <div class=\"flex items-center justify-between gap-2\">\n                <div class=\"flex items-center gap-3 overflow-hidden in-data-[uploading=true]:opacity-50\">\n                  <div class=\"flex aspect-square size-10 shrink-0 items-center justify-center rounded border\">\n                    <component :is=\"getFileIcon(file)\" class=\"size-5 opacity-60\" />\n                  </div>\n                  <div class=\"flex min-w-0 flex-col gap-0.5\">\n                    <p class=\"truncate text-[13px] font-medium\">{{ file.name }}</p>\n                    <p class=\"text-muted-foreground text-xs\">{{ formatBytes(file.size) }}</p>\n                  </div>\n                </div>\n                <Button\n                  size=\"icon\"\n                  variant=\"ghost\"\n                  class=\"text-muted-foreground/80 hover:text-foreground -me-2 size-8 hover:bg-transparent\"\n                  aria-label=\"Remove file\"\n                  @click=\"removeFile(file.id)\"\n                >\n                  <XIcon class=\"size-4\" aria-hidden=\"true\" />\n                </Button>\n              </div>\n\n              <div\n                v-if=\"progressMap[file.id] && !progressMap[file.id].completed\"\n                class=\"mt-1 flex items-center gap-2\"\n              >\n                <div class=\"h-1.5 w-full overflow-hidden rounded-full bg-gray-100\">\n                  <div\n                    class=\"bg-primary h-full transition-all duration-300 ease-out\"\n                    :style=\"{ width: `${progressMap[file.id].progress}%` }\"\n                  />\n                </div>\n                <span class=\"text-muted-foreground w-10 text-xs tabular-nums\">\n                  {{ progressMap[file.id].progress }}%\n                </span>\n              </div>\n            </div>\n          </div>\n        </div>\n      </template>\n\n      <template v-else>\n        <div class=\"flex flex-col items-center justify-center px-4 py-3 text-center\">\n          <div\n            class=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\"\n            aria-hidden=\"true\"\n          >\n            <ImageIcon class=\"size-4 opacity-60\" />\n          </div>\n          <p class=\"mb-1.5 text-sm font-medium\">Drop your files here</p>\n          <p class=\"text-muted-foreground text-xs\">\n            Max {{ maxFiles }} files ∙ Up to {{ maxSizeMB }}MB\n          </p>\n          <Button variant=\"outline\" class=\"mt-4\" @click=\"openFileDialog\">\n            <UploadIcon class=\"-ms-1 opacity-60\" aria-hidden=\"true\" />\n            Select files\n          </Button>\n        </div>\n      </template>\n    </div>\n\n    <div v-if=\"errors.length > 0\" class=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\">\n      <AlertCircleIcon class=\"size-3 shrink-0\" />\n      <span>{{ errors[0] }}</span>\n    </div>\n\n    <p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-center text-xs\">\n      With simulated progress track ∙\n      <a\n        href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\"\n        class=\"hover:text-foreground underline\"\n        target=\"_blank\"\n        rel=\"noopener noreferrer\"\n      >\n        API\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/file-upload/file-upload-13.html",
          "target": "components/ui/file-upload-13.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex flex-col gap-2\"><div ondragenter=\"${handleDragEnter}\" ondragleave=\"${handleDragLeave}\" ondragover=\"${handleDragOver}\" ondrop=\"${handleDrop}\" data-dragging=\"${isDragging || undefined}\" data-files=\"${files.length > 0 || undefined}\" class=\"border-input data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 relative flex min-h-52 flex-col items-center overflow-hidden rounded-xl border border-dashed p-4 transition-colors not-data-[files]:justify-center has-[input:focus]:ring-[3px]\"><input class=\"sr-only\" aria-label=\"Upload image file\" /><!-- if files.length > 0 -->\n<div class=\"flex w-full flex-col gap-3\"><div class=\"flex items-center justify-between gap-2\"><h3 class=\"truncate text-sm font-medium\">Files (${files.length})</h3><div class=\"flex gap-2\"><Button variant=\"outline\" size=\"sm\" on-click=\"${openFileDialog}\"><UploadIcon class=\"-ms-0.5 size-3.5 opacity-60\" aria-hidden=\"true\" />Add files\n                </Button><Button variant=\"outline\" size=\"sm\" on-click=\"${() => {\n                    // Clear all progress tracking\n                    setUploadProgress([])\n                    clearFiles()\n                  }}\"><Trash2Icon class=\"-ms-0.5 size-3.5 opacity-60\" aria-hidden=\"true\" />Remove all\n                </Button></div></div><div class=\"w-full space-y-2\">${files.map((file) => {\n                // Find the upload progress for this file once to avoid repeated lookups\n                const fileProgress = uploadProgress.find((p) => p.fileId === file.id)\n                const isUploading = fileProgress && !fileProgress.completed\n\n                return (\n                  <div\n                    key={file.id}\n                    data-uploading={isUploading || undefined}\n                    className=\"bg-background flex flex-col gap-1 rounded-lg border p-2 pe-3 transition-opacity duration-300\"\n                  >\n                    <div className=\"flex items-center justify-between gap-2\">\n                      <div className=\"flex items-center gap-3 overflow-hidden in-data-[uploading=true]:opacity-50\">\n                        <div className=\"flex aspect-square size-10 shrink-0 items-center justify-center rounded border\">\n                          {getFileIcon(file)}\n                        </div>\n                        <div className=\"flex min-w-0 flex-col gap-0.5\">\n                          <p className=\"truncate text-[13px] font-medium\">\n                            {file.file instanceof File ? file.file.name : file.file.name}\n                          </p>\n                          <p className=\"text-muted-foreground text-xs\">\n                            {formatBytes(\n                              file.file instanceof File ? file.file.size : file.file.size\n                            )}\n                          </p>\n                        </div>\n                      </div>\n                      <Button\n                        size=\"icon\"\n                        variant=\"ghost\"\n                        className=\"text-muted-foreground/80 hover:text-foreground -me-2 size-8 hover:bg-transparent\"\n                        onClick={() => {\n                          handleFileRemoved(file.id)\n                          removeFile(file.id)\n                        }}\n                        aria-label=\"Remove file\"\n                      >\n                        <XIcon className=\"size-4\" aria-hidden=\"true\" />\n                      </Button>\n                    </div>\n\n                    {/* Upload progress bar */}\n                    {fileProgress &&\n                      (() => {\n                        const progress = fileProgress.progress || 0\n                        const completed = fileProgress.completed || false\n\n                        if (completed) return null\n\n                        return (\n                          <div className=\"mt-1 flex items-center gap-2\">\n                            <div className=\"h-1.5 w-full overflow-hidden rounded-full bg-gray-100\">\n                              <div\n                                className=\"bg-primary h-full transition-all duration-300 ease-out\"\n                                style={{ width: `${progress}%` }}\n                              />\n                            </div>\n                            <span className=\"text-muted-foreground w-10 text-xs tabular-nums\">\n                              {progress}%\n                            </span>\n                          </div>\n                        )\n                      })()}\n                  </div>\n                )\n              })}</div></div>\n<!-- else -->\n<div class=\"flex flex-col items-center justify-center px-4 py-3 text-center\"><div class=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><ImageIcon class=\"size-4 opacity-60\" /></div><p class=\"mb-1.5 text-sm font-medium\">Drop your files here</p><p class=\"text-muted-foreground text-xs\">Max ${maxFiles}files ∙ Up to ${maxSizeMB}MB\n            </p><Button variant=\"outline\" class=\"mt-4\" on-click=\"${openFileDialog}\"><UploadIcon class=\"-ms-1 opacity-60\" aria-hidden=\"true\" />Select images\n            </Button></div>\n<!-- endif --></div><!-- if errors.length > 0 -->\n<div class=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\"><AlertCircleIcon class=\"size-3 shrink-0\" /><span>${errors[0]}</span></div>\n<!-- endif --><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-center text-xs\">With simulated progress track ∙${' '}<a href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\" class=\"hover:text-foreground underline\" target=\"_blank\">API\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/file-upload/file-upload-13.wxml",
          "target": "components/ui/file-upload-13/file-upload-13.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex flex-col gap-2\"><view ondragenter=\"{{handleDragEnter}}\" ondragleave=\"{{handleDragLeave}}\" ondragover=\"{{handleDragOver}}\" ondrop=\"{{handleDrop}}\" data-dragging=\"{{isDragging || undefined}}\" data-files=\"{{files.length > 0 || undefined}}\" class=\"border-input data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 relative flex min-h-52 flex-col items-center overflow-hidden rounded-xl border border-dashed p-4 transition-colors not-data-[files]:justify-center has-[input:focus]:ring-[3px]\"><input class=\"sr-only\" aria-label=\"Upload image file\" /><block wx:if=\"{{files.length > 0}}\">\n<view class=\"flex w-full flex-col gap-3\"><view class=\"flex items-center justify-between gap-2\"><h3 class=\"truncate text-sm font-medium\">Files ({{ files.length }})</h3><view class=\"flex gap-2\"><button variant=\"outline\" size=\"sm\" bindtap=\"openFileDialog\"><uploadicon class=\"-ms-0.5 size-3.5 opacity-60\" aria-hidden=\"true\" />Add files\n                </button><button variant=\"outline\" size=\"sm\" bindtap=\"{\n                    // Clear all progress tracking\n                    setUploadProgress([])\n                    clearFiles()\n                  }\"><trash2icon class=\"-ms-0.5 size-3.5 opacity-60\" aria-hidden=\"true\" />Remove all\n                </button></view></view><view class=\"w-full space-y-2\">{{ files.map((file) => {\n                // Find the upload progress for this file once to avoid repeated lookups\n                const fileProgress = uploadProgress.find((p) => p.fileId === file.id)\n                const isUploading = fileProgress && !fileProgress.completed\n\n                return (\n                  <div\n                    key={file.id}\n                    data-uploading={isUploading || undefined}\n                    className=\"bg-background flex flex-col gap-1 rounded-lg border p-2 pe-3 transition-opacity duration-300\"\n                  >\n                    <div className=\"flex items-center justify-between gap-2\">\n                      <div className=\"flex items-center gap-3 overflow-hidden in-data-[uploading=true]:opacity-50\">\n                        <div className=\"flex aspect-square size-10 shrink-0 items-center justify-center rounded border\">\n                          {getFileIcon(file)}\n                        </div>\n                        <div className=\"flex min-w-0 flex-col gap-0.5\">\n                          <p className=\"truncate text-[13px] font-medium\">\n                            {file.file instanceof File ? file.file.name : file.file.name}\n                          </p>\n                          <p className=\"text-muted-foreground text-xs\">\n                            {formatBytes(\n                              file.file instanceof File ? file.file.size : file.file.size\n                            )}\n                          </p>\n                        </div>\n                      </div>\n                      <Button\n                        size=\"icon\"\n                        variant=\"ghost\"\n                        className=\"text-muted-foreground/80 hover:text-foreground -me-2 size-8 hover:bg-transparent\"\n                        onClick={() => {\n                          handleFileRemoved(file.id)\n                          removeFile(file.id)\n                        }}\n                        aria-label=\"Remove file\"\n                      >\n                        <XIcon className=\"size-4\" aria-hidden=\"true\" />\n                      </Button>\n                    </div>\n\n                    {/* Upload progress bar */}\n                    {fileProgress &&\n                      (() => {\n                        const progress = fileProgress.progress || 0\n                        const completed = fileProgress.completed || false\n\n                        if (completed) return null\n\n                        return (\n                          <div className=\"mt-1 flex items-center gap-2\">\n                            <div className=\"h-1.5 w-full overflow-hidden rounded-full bg-gray-100\">\n                              <div\n                                className=\"bg-primary h-full transition-all duration-300 ease-out\"\n                                style={{ width: `${progress}%` }}\n                              />\n                            </div>\n                            <span className=\"text-muted-foreground w-10 text-xs tabular-nums\">\n                              {progress}%\n                            </span>\n                          </div>\n                        )\n                      })()}\n                  </div>\n                )\n              }) }}</view></view>\n</block>\n<block wx:else>\n<view class=\"flex flex-col items-center justify-center px-4 py-3 text-center\"><view class=\"bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\"><imageicon class=\"size-4 opacity-60\" /></view><text class=\"mb-1.5 text-sm font-medium\">Drop your files here</text><text class=\"text-muted-foreground text-xs\">Max {{ maxFiles }}files ∙ Up to {{ maxSizeMB }}MB\n            </text><button variant=\"outline\" class=\"mt-4\" bindtap=\"openFileDialog\"><uploadicon class=\"-ms-1 opacity-60\" aria-hidden=\"true\" />Select images\n            </button></view>\n</block></view><view wx:if=\"{{errors.length > 0}}\" class=\"text-destructive flex items-center gap-1 text-xs\" role=\"alert\"><alertcircleicon class=\"size-3 shrink-0\" /><text>{{ errors[0] }}</text></view><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-center text-xs\">With simulated progress track ∙{{ ' ' }}<a href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\" class=\"hover:text-foreground underline\" target=\"_blank\">API\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "upload",
          "file",
          "image",
          "drag and drop"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "file-upload-13",
          "group": "file-upload",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "file-upload-13",
              "path": "registry/default/components/file-upload/file-upload-13.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "file-upload-13",
              "path": "registry/default/components/file-upload/file-upload-13.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "file-upload-13",
              "path": "registry/default/components/file-upload/file-upload-13.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "file-upload-13",
              "path": "registry/default/components/file-upload/file-upload-13.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "file-upload",
        "title": "File Upload · Files ({files.length})"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "file-upload"
      ]
    },
    {
      "name": "image-cropper-01",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/cropper.json",
        "https://ui.timkit.cn/r/dialog.json",
        "https://ui.timkit.cn/r/select.json",
        "https://ui.timkit.cn/r/slider.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/image-cropper/image-cropper-01.tsx",
          "type": "registry:component",
          "target": "components/ui/image-cropper-01.tsx",
          "content": "'use client'\n\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport {\n  Button,\n  Cropper,\n  CropperCropArea,\n  CropperDescription,\n  CropperImage,\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n  Slider,\n} from '@timui/react'\nimport { ArrowLeftIcon, CircleUserRoundIcon, XIcon, ZoomInIcon, ZoomOutIcon } from 'lucide-react'\n\nimport { useFileUpload } from '@/registry/default/hooks/use-file-upload'\n\n// Define type for pixel crop area\ntype Area = { x: number; y: number; width: number; height: number }\n\n// Helper function to create a cropped image blob\nconst createImage = (url: string): Promise<HTMLImageElement> =>\n  new Promise((resolve, reject) => {\n    const image = new Image()\n    image.addEventListener('load', () => resolve(image))\n    image.addEventListener('error', (error) => reject(error))\n    image.setAttribute('crossOrigin', 'anonymous') // Needed for canvas Tainted check\n    image.src = url\n  })\n\nasync function getCroppedImg(\n  imageSrc: string,\n  pixelCrop: Area,\n  outputWidth: number = pixelCrop.width, // Optional: specify output size\n  outputHeight: number = pixelCrop.height\n): Promise<Blob | null> {\n  try {\n    const image = await createImage(imageSrc)\n    const canvas = document.createElement('canvas')\n    const ctx = canvas.getContext('2d')\n\n    if (!ctx) {\n      return null\n    }\n\n    // Set canvas size to desired output size\n    canvas.width = outputWidth\n    canvas.height = outputHeight\n\n    // Draw the cropped image onto the canvas\n    ctx.drawImage(\n      image,\n      pixelCrop.x,\n      pixelCrop.y,\n      pixelCrop.width,\n      pixelCrop.height,\n      0,\n      0,\n      outputWidth, // Draw onto the output size\n      outputHeight\n    )\n\n    // Convert canvas to blob\n    return new Promise((resolve) => {\n      canvas.toBlob((blob) => {\n        resolve(blob)\n      }, 'image/jpeg') // Specify format and quality if needed\n    })\n  } catch (error) {\n    console.error('Error in getCroppedImg:', error)\n    return null\n  }\n}\n\nexport default function Component() {\n  const [\n    { files, isDragging },\n    {\n      handleDragEnter,\n      handleDragLeave,\n      handleDragOver,\n      handleDrop,\n      openFileDialog,\n      removeFile,\n      getInputProps,\n    },\n  ] = useFileUpload({\n    accept: 'image/*',\n  })\n\n  const previewUrl = files[0]?.preview || null\n  const fileId = files[0]?.id\n\n  const [finalImageUrl, setFinalImageUrl] = useState<string | null>(null)\n  const [isDialogOpen, setIsDialogOpen] = useState(false)\n\n  // Ref to track the previous file ID to detect new uploads\n  const previousFileIdRef = useRef<string | undefined | null>(null)\n\n  // State to store the desired crop area in pixels\n  const [croppedAreaPixels, setCroppedAreaPixels] = useState<Area | null>(null)\n\n  // State for zoom level\n  const [zoom, setZoom] = useState(1)\n\n  // Callback for Cropper to provide crop data - Wrap with useCallback\n  const handleCropChange = useCallback((pixels: Area | null) => {\n    setCroppedAreaPixels(pixels)\n  }, [])\n\n  const handleApply = async () => {\n    // Check if we have the necessary data\n    if (!previewUrl || !fileId || !croppedAreaPixels) {\n      console.error('Missing data for apply:', {\n        previewUrl,\n        fileId,\n        croppedAreaPixels,\n      })\n      // Remove file if apply is clicked without crop data?\n      if (fileId) {\n        removeFile(fileId)\n        setCroppedAreaPixels(null)\n      }\n      return\n    }\n\n    try {\n      // 1. Get the cropped image blob using the helper\n      const croppedBlob = await getCroppedImg(previewUrl, croppedAreaPixels)\n\n      if (!croppedBlob) {\n        throw new Error('Failed to generate cropped image blob.')\n      }\n\n      // 2. Create a NEW object URL from the cropped blob\n      const newFinalUrl = URL.createObjectURL(croppedBlob)\n\n      // 3. Revoke the OLD finalImageUrl if it exists\n      if (finalImageUrl) {\n        URL.revokeObjectURL(finalImageUrl)\n      }\n\n      // 4. Set the final avatar state to the NEW URL\n      setFinalImageUrl(newFinalUrl)\n\n      // 5. Close the dialog (don't remove the file yet)\n      setIsDialogOpen(false)\n    } catch (error) {\n      console.error('Error during apply:', error)\n      // Close the dialog even if cropping fails\n      setIsDialogOpen(false)\n    }\n  }\n\n  const handleRemoveFinalImage = () => {\n    if (finalImageUrl) {\n      URL.revokeObjectURL(finalImageUrl)\n    }\n    setFinalImageUrl(null)\n  }\n\n  useEffect(() => {\n    const currentFinalUrl = finalImageUrl\n    // Cleanup function\n    return () => {\n      if (currentFinalUrl && currentFinalUrl.startsWith('blob:')) {\n        URL.revokeObjectURL(currentFinalUrl)\n      }\n    }\n  }, [finalImageUrl])\n\n  // Effect to open dialog when a *new* file is ready\n  useEffect(() => {\n    // Check if fileId exists and is different from the previous one\n    if (fileId && fileId !== previousFileIdRef.current) {\n      setIsDialogOpen(true) // Open dialog for the new file\n      setCroppedAreaPixels(null) // Reset crop area for the new file\n      setZoom(1) // Reset zoom for the new file\n    }\n    // Update the ref to the current fileId for the next render\n    previousFileIdRef.current = fileId\n  }, [fileId]) // Depend only on fileId\n\n  return (\n    <div className=\"flex flex-col items-center gap-2\">\n      <div className=\"relative inline-flex\">\n        {/* Drop area - uses finalImageUrl */}\n        <button\n          className=\"border-input hover:bg-accent/50 data-[dragging=true]:bg-accent/50 focus-visible:border-ring focus-visible:ring-ring/50 relative flex size-16 items-center justify-center overflow-hidden rounded-full border border-dashed transition-colors outline-none focus-visible:ring-[3px] has-disabled:pointer-events-none has-disabled:opacity-50 has-[img]:border-none\"\n          onClick={openFileDialog}\n          onDragEnter={handleDragEnter}\n          onDragLeave={handleDragLeave}\n          onDragOver={handleDragOver}\n          onDrop={handleDrop}\n          data-dragging={isDragging || undefined}\n          aria-label={finalImageUrl ? 'Change image' : 'Upload image'}\n        >\n          {finalImageUrl ? (\n            <img\n              className=\"size-full object-cover\"\n              src={finalImageUrl}\n              alt=\"User avatar\"\n              width={64}\n              height={64}\n              style={{ objectFit: 'cover' }}\n            />\n          ) : (\n            <div aria-hidden=\"true\">\n              <CircleUserRoundIcon className=\"size-4 opacity-60\" />\n            </div>\n          )}\n        </button>\n        {/* Remove button - depends on finalImageUrl */}\n        {finalImageUrl && (\n          <Button\n            onClick={handleRemoveFinalImage}\n            size=\"icon\"\n            className=\"border-background focus-visible:border-background absolute -top-1 -right-1 size-6 rounded-full border-2 shadow-none\"\n            aria-label=\"Remove image\"\n          >\n            <XIcon className=\"size-3.5\" />\n          </Button>\n        )}\n        <input\n          {...getInputProps()}\n          className=\"sr-only\"\n          aria-label=\"Upload image file\"\n          tabIndex={-1}\n        />\n      </div>\n\n      {/* Cropper Dialog - Use isDialogOpen for open prop */}\n      <Dialog open={isDialogOpen} onOpenChange={setIsDialogOpen}>\n        <DialogContent className=\"gap-0 p-0 sm:max-w-140 *:[button]:hidden\">\n          <DialogDescription className=\"sr-only\">Crop image dialog</DialogDescription>\n          <DialogHeader className=\"contents space-y-0 text-left\">\n            <DialogTitle className=\"flex items-center justify-between border-b p-4 text-base\">\n              <div className=\"flex items-center gap-2\">\n                <Button\n                  type=\"button\"\n                  variant=\"ghost\"\n                  size=\"icon\"\n                  className=\"-my-1 opacity-60\"\n                  onClick={() => setIsDialogOpen(false)}\n                  aria-label=\"Cancel\"\n                >\n                  <ArrowLeftIcon aria-hidden=\"true\" />\n                </Button>\n                <span>Crop image</span>\n              </div>\n              <Button className=\"-my-1\" onClick={handleApply} disabled={!previewUrl} autoFocus>\n                Apply\n              </Button>\n            </DialogTitle>\n          </DialogHeader>\n          {previewUrl && (\n            <Cropper\n              className=\"h-96 sm:h-120\"\n              image={previewUrl}\n              zoom={zoom}\n              onCropChange={handleCropChange}\n              onZoomChange={setZoom}\n            >\n              <CropperDescription />\n              <CropperImage />\n              <CropperCropArea />\n            </Cropper>\n          )}\n          <DialogFooter className=\"border-t px-4 py-6\">\n            <div className=\"mx-auto flex w-full max-w-80 items-center gap-4\">\n              <ZoomOutIcon className=\"shrink-0 opacity-60\" size={16} aria-hidden=\"true\" />\n              <Slider\n                defaultValue={[1]}\n                value={[zoom]}\n                min={1}\n                max={3}\n                step={0.1}\n                onValueChange={(value) => setZoom(value[0])}\n                aria-label=\"Zoom slider\"\n              />\n              <ZoomInIcon className=\"shrink-0 opacity-60\" size={16} aria-hidden=\"true\" />\n            </div>\n          </DialogFooter>\n        </DialogContent>\n      </Dialog>\n\n      <p aria-live=\"polite\" role=\"region\" className=\"text-muted-foreground mt-2 text-xs\">\n        Avatar{' '}\n        <a\n          href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\"\n          className=\"hover:text-foreground underline\"\n          target=\"_blank\"\n        >\n          uploader\n        </a>{' '}\n        with{' '}\n        <a\n          href=\"https://github.com/origin-space/image-cropper\"\n          className=\"hover:text-foreground underline\"\n          target=\"_blank\"\n        >\n          cropper\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/hooks/use-file-upload.ts",
          "type": "registry:hook",
          "target": "components/ui/image-cropper-01/use-file-upload.ts",
          "content": "'use client'\n\nimport type React from 'react'\nimport {\n  useCallback,\n  useRef,\n  useState,\n  type ChangeEvent,\n  type DragEvent,\n  type InputHTMLAttributes,\n} from 'react'\n\nexport type FileMetadata = {\n  name: string\n  size: number\n  type: string\n  url: string\n  id: string\n}\n\nexport type FileWithPreview = {\n  file: File | FileMetadata\n  id: string\n  preview?: string\n}\n\nexport type FileUploadOptions = {\n  maxFiles?: number // Only used when multiple is true, defaults to Infinity\n  maxSize?: number // in bytes\n  accept?: string\n  multiple?: boolean // Defaults to false\n  initialFiles?: FileMetadata[]\n  onFilesChange?: (files: FileWithPreview[]) => void // Callback when files change\n  onFilesAdded?: (addedFiles: FileWithPreview[]) => void // Callback when new files are added\n}\n\nexport type FileUploadState = {\n  files: FileWithPreview[]\n  isDragging: boolean\n  errors: string[]\n}\n\nexport type FileUploadActions = {\n  addFiles: (files: FileList | File[]) => void\n  removeFile: (id: string) => void\n  clearFiles: () => void\n  clearErrors: () => void\n  handleDragEnter: (e: DragEvent<HTMLElement>) => void\n  handleDragLeave: (e: DragEvent<HTMLElement>) => void\n  handleDragOver: (e: DragEvent<HTMLElement>) => void\n  handleDrop: (e: DragEvent<HTMLElement>) => void\n  handleFileChange: (e: ChangeEvent<HTMLInputElement>) => void\n  openFileDialog: () => void\n  getInputProps: (\n    props?: InputHTMLAttributes<HTMLInputElement>\n  ) => InputHTMLAttributes<HTMLInputElement> & {\n    ref: React.Ref<HTMLInputElement>\n  }\n}\n\nexport const useFileUpload = (\n  options: FileUploadOptions = {}\n): [FileUploadState, FileUploadActions] => {\n  const {\n    maxFiles = Infinity,\n    maxSize = Infinity,\n    accept = '*',\n    multiple = false,\n    initialFiles = [],\n    onFilesChange,\n    onFilesAdded,\n  } = options\n\n  const [state, setState] = useState<FileUploadState>({\n    files: initialFiles.map((file) => ({\n      file,\n      id: file.id,\n      preview: file.url,\n    })),\n    isDragging: false,\n    errors: [],\n  })\n\n  const inputRef = useRef<HTMLInputElement>(null)\n\n  const validateFile = useCallback(\n    (file: File | FileMetadata): string | null => {\n      if (file instanceof File) {\n        if (file.size > maxSize) {\n          return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n        }\n      } else {\n        if (file.size > maxSize) {\n          return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n        }\n      }\n\n      if (accept !== '*') {\n        const acceptedTypes = accept.split(',').map((type) => type.trim())\n        const fileType = file instanceof File ? file.type || '' : file.type\n        const fileExtension = `.${file instanceof File ? file.name.split('.').pop() : file.name.split('.').pop()}`\n\n        const isAccepted = acceptedTypes.some((type) => {\n          if (type.startsWith('.')) {\n            return fileExtension.toLowerCase() === type.toLowerCase()\n          }\n          if (type.endsWith('/*')) {\n            const baseType = type.split('/')[0]\n            return fileType.startsWith(`${baseType}/`)\n          }\n          return fileType === type\n        })\n\n        if (!isAccepted) {\n          return `File \"${file instanceof File ? file.name : file.name}\" is not an accepted file type.`\n        }\n      }\n\n      return null\n    },\n    [accept, maxSize]\n  )\n\n  const createPreview = useCallback((file: File | FileMetadata): string | undefined => {\n    if (file instanceof File) {\n      return URL.createObjectURL(file)\n    }\n    return file.url\n  }, [])\n\n  const generateUniqueId = useCallback((file: File | FileMetadata): string => {\n    if (file instanceof File) {\n      return `${file.name}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`\n    }\n    return file.id\n  }, [])\n\n  const clearFiles = useCallback(() => {\n    setState((prev) => {\n      // Clean up object URLs\n      prev.files.forEach((file) => {\n        if (file.preview && file.file instanceof File && file.file.type.startsWith('image/')) {\n          URL.revokeObjectURL(file.preview)\n        }\n      })\n\n      if (inputRef.current) {\n        inputRef.current.value = ''\n      }\n\n      const newState = {\n        ...prev,\n        files: [],\n        errors: [],\n      }\n\n      onFilesChange?.(newState.files)\n      return newState\n    })\n  }, [onFilesChange])\n\n  const addFiles = useCallback(\n    (newFiles: FileList | File[]) => {\n      if (!newFiles || newFiles.length === 0) return\n\n      const newFilesArray = Array.from(newFiles)\n      const errors: string[] = []\n\n      // Clear existing errors when new files are uploaded\n      setState((prev) => ({ ...prev, errors: [] }))\n\n      // In single file mode, clear existing files first\n      if (!multiple) {\n        clearFiles()\n      }\n\n      // Check if adding these files would exceed maxFiles (only in multiple mode)\n      if (\n        multiple &&\n        maxFiles !== Infinity &&\n        state.files.length + newFilesArray.length > maxFiles\n      ) {\n        errors.push(`You can only upload a maximum of ${maxFiles} files.`)\n        setState((prev) => ({ ...prev, errors }))\n        return\n      }\n\n      const validFiles: FileWithPreview[] = []\n\n      newFilesArray.forEach((file) => {\n        // Only check for duplicates if multiple files are allowed\n        if (multiple) {\n          const isDuplicate = state.files.some(\n            (existingFile) =>\n              existingFile.file.name === file.name && existingFile.file.size === file.size\n          )\n\n          // Skip duplicate files silently\n          if (isDuplicate) {\n            return\n          }\n        }\n\n        // Check file size\n        if (file.size > maxSize) {\n          errors.push(\n            multiple\n              ? `Some files exceed the maximum size of ${formatBytes(maxSize)}.`\n              : `File exceeds the maximum size of ${formatBytes(maxSize)}.`\n          )\n          return\n        }\n\n        const error = validateFile(file)\n        if (error) {\n          errors.push(error)\n        } else {\n          validFiles.push({\n            file,\n            id: generateUniqueId(file),\n            preview: createPreview(file),\n          })\n        }\n      })\n\n      // Only update state if we have valid files to add\n      if (validFiles.length > 0) {\n        // Call the onFilesAdded callback with the newly added valid files\n        onFilesAdded?.(validFiles)\n\n        setState((prev) => {\n          const newFiles = !multiple ? validFiles : [...prev.files, ...validFiles]\n          onFilesChange?.(newFiles)\n          return {\n            ...prev,\n            files: newFiles,\n            errors,\n          }\n        })\n      } else if (errors.length > 0) {\n        setState((prev) => ({\n          ...prev,\n          errors,\n        }))\n      }\n\n      // Reset input value after handling files\n      if (inputRef.current) {\n        inputRef.current.value = ''\n      }\n    },\n    [\n      state.files,\n      maxFiles,\n      multiple,\n      maxSize,\n      validateFile,\n      createPreview,\n      generateUniqueId,\n      clearFiles,\n      onFilesChange,\n      onFilesAdded,\n    ]\n  )\n\n  const removeFile = useCallback(\n    (id: string) => {\n      setState((prev) => {\n        const fileToRemove = prev.files.find((file) => file.id === id)\n        if (\n          fileToRemove &&\n          fileToRemove.preview &&\n          fileToRemove.file instanceof File &&\n          fileToRemove.file.type.startsWith('image/')\n        ) {\n          URL.revokeObjectURL(fileToRemove.preview)\n        }\n\n        const newFiles = prev.files.filter((file) => file.id !== id)\n        onFilesChange?.(newFiles)\n\n        return {\n          ...prev,\n          files: newFiles,\n          errors: [],\n        }\n      })\n    },\n    [onFilesChange]\n  )\n\n  const clearErrors = useCallback(() => {\n    setState((prev) => ({\n      ...prev,\n      errors: [],\n    }))\n  }, [])\n\n  const handleDragEnter = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n    setState((prev) => ({ ...prev, isDragging: true }))\n  }, [])\n\n  const handleDragLeave = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n\n    if (e.currentTarget.contains(e.relatedTarget as Node)) {\n      return\n    }\n\n    setState((prev) => ({ ...prev, isDragging: false }))\n  }, [])\n\n  const handleDragOver = useCallback((e: DragEvent<HTMLElement>) => {\n    e.preventDefault()\n    e.stopPropagation()\n  }, [])\n\n  const handleDrop = useCallback(\n    (e: DragEvent<HTMLElement>) => {\n      e.preventDefault()\n      e.stopPropagation()\n      setState((prev) => ({ ...prev, isDragging: false }))\n\n      // Don't process files if the input is disabled\n      if (inputRef.current?.disabled) {\n        return\n      }\n\n      if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n        // In single file mode, only use the first file\n        if (!multiple) {\n          const file = e.dataTransfer.files[0]\n          addFiles([file])\n        } else {\n          addFiles(e.dataTransfer.files)\n        }\n      }\n    },\n    [addFiles, multiple]\n  )\n\n  const handleFileChange = useCallback(\n    (e: ChangeEvent<HTMLInputElement>) => {\n      if (e.target.files && e.target.files.length > 0) {\n        addFiles(e.target.files)\n      }\n    },\n    [addFiles]\n  )\n\n  const openFileDialog = useCallback(() => {\n    if (inputRef.current) {\n      inputRef.current.click()\n    }\n  }, [])\n\n  const getInputProps = useCallback(\n    (props: InputHTMLAttributes<HTMLInputElement> = {}) => {\n      return {\n        ...props,\n        type: 'file' as const,\n        onChange: handleFileChange,\n        accept: props.accept || accept,\n        multiple: props.multiple !== undefined ? props.multiple : multiple,\n        ref: inputRef,\n      }\n    },\n    [accept, multiple, handleFileChange]\n  )\n\n  return [\n    state,\n    {\n      addFiles,\n      removeFile,\n      clearFiles,\n      clearErrors,\n      handleDragEnter,\n      handleDragLeave,\n      handleDragOver,\n      handleDrop,\n      handleFileChange,\n      openFileDialog,\n      getInputProps,\n    },\n  ]\n}\n\n// Helper function to format bytes to human-readable format\nexport const formatBytes = (bytes: number, decimals = 2): string => {\n  if (bytes === 0) return '0 Bytes'\n\n  const k = 1024\n  const dm = decimals < 0 ? 0 : decimals\n  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']\n\n  const i = Math.floor(Math.log(bytes) / Math.log(k))\n\n  return Number.parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + sizes[i]\n}\n"
        },
        {
          "path": "registry/default/components/image-cropper/image-cropper-01.vue",
          "target": "components/ui/image-cropper-01.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, ref, watch } from 'vue';\nimport { ArrowLeftIcon, CircleUserRoundIcon, XIcon, ZoomInIcon, ZoomOutIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { Cropper, CropperCropArea, CropperDescription, CropperImage } from '@timui/vue';\nimport { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@timui/vue';\nimport { Slider } from '@timui/vue';\nimport { useFileUpload } from '@/registry/default/hooks/use-file-upload-vue';\n\ntype Area = { x: number; y: number; width: number; height: number };\n\nconst createImage = (url: string): Promise<HTMLImageElement> =>\n  new Promise((resolve, reject) => {\n    const image = new Image();\n    image.addEventListener('load', () => resolve(image));\n    image.addEventListener('error', (error) => reject(error));\n    image.setAttribute('crossOrigin', 'anonymous');\n    image.src = url;\n  });\n\nasync function getCroppedImg(\n  imageSrc: string,\n  pixelCrop: Area,\n  outputWidth: number = pixelCrop.width,\n  outputHeight: number = pixelCrop.height,\n): Promise<Blob | null> {\n  try {\n    const image = await createImage(imageSrc);\n    const canvas = document.createElement('canvas');\n    const ctx = canvas.getContext('2d');\n\n    if (!ctx) return null;\n\n    canvas.width = outputWidth;\n    canvas.height = outputHeight;\n\n    ctx.drawImage(\n      image,\n      pixelCrop.x,\n      pixelCrop.y,\n      pixelCrop.width,\n      pixelCrop.height,\n      0,\n      0,\n      outputWidth,\n      outputHeight,\n    );\n\n    return new Promise((resolve) => {\n      canvas.toBlob((blob) => resolve(blob), 'image/jpeg');\n    });\n  } catch (error) {\n    console.error('Error in getCroppedImg:', error);\n    return null;\n  }\n}\n\nconst [\n  { files, isDragging },\n  {\n    handleDragEnter,\n    handleDragLeave,\n    handleDragOver,\n    handleDrop,\n    openFileDialog,\n    removeFile,\n    getInputProps,\n  },\n] = useFileUpload({\n  accept: 'image/*',\n});\n\nconst previewUrl = computed(() => files.value[0]?.preview ?? null);\nconst fileId = computed(() => files.value[0]?.id ?? null);\n\nconst finalImageUrl = ref<string | null>(null);\nconst isDialogOpen = ref(false);\nconst croppedAreaPixels = ref<Area | null>(null);\nconst zoom = ref(1);\nconst previousFileId = ref<string | null>(null);\n\nfunction setIsDialogOpen(nextOpen: boolean) {\n  isDialogOpen.value = nextOpen;\n}\n\nfunction setZoom(nextZoom: number) {\n  zoom.value = nextZoom;\n}\n\nfunction handleCropChange(pixels: Area | null) {\n  croppedAreaPixels.value = pixels;\n}\n\nfunction handleZoomValueChange(values: number[]) {\n  setZoom(values[0] ?? 1);\n}\n\nasync function handleApply() {\n  if (!previewUrl.value || !fileId.value) {\n    return;\n  }\n\n  let area = croppedAreaPixels.value;\n\n  if (!area) {\n    const image = await createImage(previewUrl.value);\n    area = {\n      x: 0,\n      y: 0,\n      width: image.width,\n      height: image.height,\n    };\n  }\n\n  const croppedBlob = await getCroppedImg(previewUrl.value, area);\n  if (!croppedBlob) {\n    isDialogOpen.value = false;\n    return;\n  }\n\n  const nextFinalImageUrl = URL.createObjectURL(croppedBlob);\n\n  if (finalImageUrl.value?.startsWith('blob:')) {\n    URL.revokeObjectURL(finalImageUrl.value);\n  }\n\n  finalImageUrl.value = nextFinalImageUrl;\n  isDialogOpen.value = false;\n}\n\nfunction handleRemoveFinalImage() {\n  if (finalImageUrl.value?.startsWith('blob:')) {\n    URL.revokeObjectURL(finalImageUrl.value);\n  }\n  finalImageUrl.value = null;\n\n  const currentFileId = fileId.value;\n  if (currentFileId) {\n    removeFile(currentFileId);\n  }\n}\n\nwatch(fileId, (nextFileId) => {\n  if (nextFileId && nextFileId !== previousFileId.value) {\n    isDialogOpen.value = true;\n    croppedAreaPixels.value = null;\n    zoom.value = 1;\n  }\n  previousFileId.value = nextFileId;\n});\n\nonBeforeUnmount(() => {\n  if (finalImageUrl.value?.startsWith('blob:')) {\n    URL.revokeObjectURL(finalImageUrl.value);\n  }\n});\n</script>\n\n<template>\n  <div class=\"flex flex-col items-center gap-2\">\n    <div class=\"relative inline-flex\">\n      <button\n        class=\"border-input hover:bg-accent/50 data-[dragging=true]:bg-accent/50 focus-visible:border-ring focus-visible:ring-ring/50 relative flex size-16 items-center justify-center overflow-hidden rounded-full border border-dashed transition-colors outline-none focus-visible:ring-[3px] has-disabled:pointer-events-none has-disabled:opacity-50 has-[img]:border-none\"\n        @click=\"openFileDialog\"\n        @dragenter=\"handleDragEnter\"\n        @dragleave=\"handleDragLeave\"\n        @dragover=\"handleDragOver\"\n        @drop=\"handleDrop\"\n        :data-dragging=\"isDragging || undefined\"\n        :aria-label=\"finalImageUrl ? 'Change image' : 'Upload image'\"\n      >\n        <template v-if=\"finalImageUrl\">\n          <img\n            class=\"size-full object-cover\"\n            :src=\"finalImageUrl\"\n            alt=\"User avatar\"\n            :width=\"64\"\n            :height=\"64\"\n            :style=\"{ objectFit: 'cover' }\"\n          />\n        </template>\n        <template v-else>\n          <div aria-hidden=\"true\">\n            <CircleUserRoundIcon class=\"size-4 opacity-60\" />\n          </div>\n        </template>\n      </button>\n\n      <Button\n        v-if=\"finalImageUrl\"\n        @click=\"handleRemoveFinalImage\"\n        size=\"icon\"\n        class=\"border-background focus-visible:border-background absolute -top-1 -right-1 size-6 rounded-full border-2 shadow-none\"\n        aria-label=\"Remove image\"\n      >\n        <XIcon class=\"size-3.5\" />\n      </Button>\n\n      <input\n        v-bind=\"getInputProps()\"\n        class=\"sr-only\"\n        aria-label=\"Upload image file\"\n        :tabIndex=\"-1\"\n      />\n    </div>\n\n    <Dialog :open=\"isDialogOpen\" @update:open=\"setIsDialogOpen\">\n      <DialogContent class=\"gap-0 p-0 sm:max-w-140 *:[button]:hidden\">\n        <DialogDescription class=\"sr-only\">Crop image dialog</DialogDescription>\n        <DialogHeader class=\"contents space-y-0 text-left\">\n          <DialogTitle class=\"flex items-center justify-between border-b p-4 text-base\">\n            <div class=\"flex items-center gap-2\">\n              <Button\n                type=\"button\"\n                variant=\"ghost\"\n                size=\"icon\"\n                class=\"-my-1 opacity-60\"\n                @click=\"setIsDialogOpen(false)\"\n                aria-label=\"Cancel\"\n              >\n                <ArrowLeftIcon aria-hidden=\"true\" />\n              </Button>\n              <span>Crop image</span>\n            </div>\n            <Button class=\"-my-1\" @click=\"handleApply\" :disabled=\"!previewUrl\" autoFocus>\n              Apply\n            </Button>\n          </DialogTitle>\n        </DialogHeader>\n\n        <Cropper\n          v-if=\"previewUrl\"\n          class=\"h-96 sm:h-120\"\n          :image=\"previewUrl\"\n          :zoom=\"zoom\"\n          :onCropChange=\"handleCropChange\"\n          :onZoomChange=\"setZoom\"\n        >\n          <CropperDescription />\n          <CropperImage />\n          <CropperCropArea />\n        </Cropper>\n\n        <DialogFooter class=\"border-t px-4 py-6\">\n          <div class=\"mx-auto flex w-full max-w-80 items-center gap-4\">\n            <ZoomOutIcon class=\"shrink-0 opacity-60\" :size=\"16\" aria-hidden=\"true\" />\n            <Slider\n              :default-value=\"[1]\"\n              :value=\"[zoom]\"\n              :min=\"1\"\n              :max=\"3\"\n              :step=\"0.1\"\n              @update:modelValue=\"handleZoomValueChange\"\n              aria-label=\"Zoom slider\"\n            />\n            <ZoomInIcon class=\"shrink-0 opacity-60\" :size=\"16\" aria-hidden=\"true\" />\n          </div>\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n\n    <p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">\n      Avatar\n      <a\n        href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\"\n        class=\"hover:text-foreground underline\"\n        target=\"_blank\"\n      >\n        uploader\n      </a>\n      with\n      <a\n        href=\"https://github.com/origin-space/image-cropper\"\n        class=\"hover:text-foreground underline\"\n        target=\"_blank\"\n      >\n        cropper\n      </a>\n    </p>\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/components/image-cropper/image-cropper-01.html",
          "target": "components/ui/image-cropper-01.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex flex-col items-center gap-2\"><div class=\"relative inline-flex\"><button class=\"border-input hover:bg-accent/50 data-[dragging=true]:bg-accent/50 focus-visible:border-ring focus-visible:ring-ring/50 relative flex size-16 items-center justify-center overflow-hidden rounded-full border border-dashed transition-colors outline-none focus-visible:ring-[3px] has-disabled:pointer-events-none has-disabled:opacity-50 has-[img]:border-none\" on-click=\"${openFileDialog}\" ondragenter=\"${handleDragEnter}\" ondragleave=\"${handleDragLeave}\" ondragover=\"${handleDragOver}\" ondrop=\"${handleDrop}\" data-dragging=\"${isDragging || undefined}\" aria-label=\"${finalImageUrl ? 'Change image' : 'Upload image'}\"><!-- if finalImageUrl -->\n<img class=\"size-full object-cover\" src=\"${finalImageUrl}\" alt=\"User avatar\" width=\"${64}\" height=\"${64}\" style=\"${{ objectFit: 'cover' }}\" />\n<!-- else -->\n<div aria-hidden=\"true\"><CircleUserRoundIcon class=\"size-4 opacity-60\" /></div>\n<!-- endif --></button><!-- if finalImageUrl -->\n<Button on-click=\"${handleRemoveFinalImage}\" size=\"icon\" class=\"border-background focus-visible:border-background absolute -top-1 -right-1 size-6 rounded-full border-2 shadow-none\" aria-label=\"Remove image\"><XIcon class=\"size-3.5\" /></Button>\n<!-- endif --><input class=\"sr-only\" aria-label=\"Upload image file\" tabindex=\"${-1}\" /></div><Dialog open=\"${isDialogOpen}\" on-open-change=\"${setIsDialogOpen}\"><DialogContent class=\"gap-0 p-0 sm:max-w-140 *:[button]:hidden\"><DialogDescription class=\"sr-only\">Crop image dialog</DialogDescription><DialogHeader class=\"contents space-y-0 text-left\"><DialogTitle class=\"flex items-center justify-between border-b p-4 text-base\"><div class=\"flex items-center gap-2\"><Button type=\"button\" variant=\"ghost\" size=\"icon\" class=\"-my-1 opacity-60\" on-click=\"${() => setIsDialogOpen(false)}\" aria-label=\"Cancel\"><ArrowLeftIcon aria-hidden=\"true\" /></Button><span>Crop image</span></div><Button class=\"-my-1\" on-click=\"${handleApply}\" disabled=\"${!previewUrl}\" autofocus>Apply\n              </Button></DialogTitle></DialogHeader><!-- if previewUrl -->\n<Cropper class=\"h-96 sm:h-120\" image=\"${previewUrl}\" zoom=\"${zoom}\" oncropchange=\"${handleCropChange}\" onzoomchange=\"${setZoom}\"><CropperDescription /><CropperImage /><CropperCropArea /></Cropper>\n<!-- endif --><DialogFooter class=\"border-t px-4 py-6\"><div class=\"mx-auto flex w-full max-w-80 items-center gap-4\"><ZoomOutIcon class=\"shrink-0 opacity-60\" size=\"${16}\" aria-hidden=\"true\" /><Slider default-value=\"${[1]}\" value=\"${[zoom]}\" min=\"${1}\" max=\"${3}\" step=\"${0.1}\" on-value-change=\"${(value) => setZoom(value[0])}\" aria-label=\"Zoom slider\" /><ZoomInIcon class=\"shrink-0 opacity-60\" size=\"${16}\" aria-hidden=\"true\" /></div></DialogFooter></DialogContent></Dialog><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Avatar${' '}<a href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\" class=\"hover:text-foreground underline\" target=\"_blank\">uploader\n        </a>${' '}with${' '}<a href=\"https://github.com/origin-space/image-cropper\" class=\"hover:text-foreground underline\" target=\"_blank\">cropper\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/image-cropper/image-cropper-01.wxml",
          "target": "components/ui/image-cropper-01/image-cropper-01.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex flex-col items-center gap-2\"><view class=\"relative inline-flex\"><button class=\"border-input hover:bg-accent/50 data-[dragging=true]:bg-accent/50 focus-visible:border-ring focus-visible:ring-ring/50 relative flex size-16 items-center justify-center overflow-hidden rounded-full border border-dashed transition-colors outline-none focus-visible:ring-[3px] has-disabled:pointer-events-none has-disabled:opacity-50 has-[img]:border-none\" bindtap=\"openFileDialog\" ondragenter=\"{{handleDragEnter}}\" ondragleave=\"{{handleDragLeave}}\" ondragover=\"{{handleDragOver}}\" ondrop=\"{{handleDrop}}\" data-dragging=\"{{isDragging || undefined}}\" aria-label=\"{{finalImageUrl ? 'Change image' : 'Upload image'}}\"><block wx:if=\"{{finalImageUrl}}\">\n<image class=\"size-full object-cover\" src=\"{{finalImageUrl}}\" alt=\"User avatar\" width=\"{{64}}\" height=\"{{64}}\" style=\"{{{ objectFit: 'cover' }}}\" />\n</block>\n<block wx:else>\n<view aria-hidden=\"true\"><circleuserroundicon class=\"size-4 opacity-60\" /></view>\n</block></button><button wx:if=\"{{finalImageUrl}}\" bindtap=\"handleRemoveFinalImage\" size=\"icon\" class=\"border-background focus-visible:border-background absolute -top-1 -right-1 size-6 rounded-full border-2 shadow-none\" aria-label=\"Remove image\"><xicon class=\"size-3.5\" /></button><input class=\"sr-only\" aria-label=\"Upload image file\" tabindex=\"{{-1}}\" /></view><dialog open=\"{{isDialogOpen}}\" bindchange=\"setIsDialogOpen\"><dialogcontent class=\"gap-0 p-0 sm:max-w-140 *:[button]:hidden\"><dialogdescription class=\"sr-only\">Crop image dialog</dialogdescription><dialogheader class=\"contents space-y-0 text-left\"><dialogtitle class=\"flex items-center justify-between border-b p-4 text-base\"><view class=\"flex items-center gap-2\"><button type=\"button\" variant=\"ghost\" size=\"icon\" class=\"-my-1 opacity-60\" bindtap=\"setIsDialogOpen(false)\" aria-label=\"Cancel\"><arrowlefticon aria-hidden=\"true\" /></button><text>Crop image</text></view><button class=\"-my-1\" bindtap=\"handleApply\" disabled=\"{{!previewUrl}}\" autofocus>Apply\n              </button></dialogtitle></dialogheader><cropper wx:if=\"{{previewUrl}}\" class=\"h-96 sm:h-120\" image=\"{{previewUrl}}\" zoom=\"{{zoom}}\" oncropchange=\"{{handleCropChange}}\" onzoomchange=\"{{setZoom}}\"><cropperdescription /><cropperimage /><croppercroparea /></cropper><dialogfooter class=\"border-t px-4 py-6\"><view class=\"mx-auto flex w-full max-w-80 items-center gap-4\"><zoomouticon class=\"shrink-0 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" /><slider default-value=\"{{[1]}}\" value=\"{{[zoom]}}\" min=\"{{1}}\" max=\"{{3}}\" step=\"{{0.1}}\" bindchange=\"setZoom(value[0])\" aria-label=\"Zoom slider\" /><zoominicon class=\"shrink-0 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" /></view></dialogfooter></dialogcontent></dialog><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Avatar{{ ' ' }}<a href=\"https://github.com/origin-space/originui/tree/main/docs/use-file-upload.md\" class=\"hover:text-foreground underline\" target=\"_blank\">uploader\n        </a>{{ ' ' }}with{{ ' ' }}<a href=\"https://github.com/origin-space/image-cropper\" class=\"hover:text-foreground underline\" target=\"_blank\">cropper\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "upload",
          "file",
          "image",
          "drag and drop",
          "crop",
          "dialog",
          "slider",
          "zoom"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "image-cropper-01",
          "group": "image-cropper",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "image-cropper-01",
              "path": "registry/default/components/image-cropper/image-cropper-01.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "image-cropper-01",
              "path": "registry/default/components/image-cropper/image-cropper-01.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "image-cropper-01",
              "path": "registry/default/components/image-cropper/image-cropper-01.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "image-cropper-01",
              "path": "registry/default/components/image-cropper/image-cropper-01.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "file-upload",
        "title": "Image Cropper · Remove image"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "file-upload",
        "image-cropper"
      ]
    },
    {
      "name": "image-cropper-02",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/cropper.json"
      ],
      "files": [
        {
          "path": "registry/default/components/image-cropper/image-cropper-02.tsx",
          "type": "registry:component",
          "target": "components/ui/image-cropper-02.tsx",
          "content": "import { Cropper, CropperCropArea, CropperDescription, CropperImage } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"flex flex-col items-center gap-2\">\n      <Cropper\n        className=\"h-80\"\n        image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-01_bcxaic.jpg\"\n      >\n        <CropperDescription />\n        <CropperImage />\n        <CropperCropArea />\n      </Cropper>\n\n      <p aria-live=\"polite\" role=\"region\" className=\"text-muted-foreground mt-2 text-xs\">\n        Basic cropper ∙{' '}\n        <a\n          href=\"https://github.com/origin-space/image-cropper\"\n          className=\"hover:text-foreground underline\"\n          target=\"_blank\"\n        >\n          API\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/image-cropper/image-cropper-02.vue",
          "target": "components/ui/image-cropper-02.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Cropper, CropperCropArea, CropperDescription, CropperImage } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"flex flex-col items-center gap-2\"><Cropper class=\"h-80\" image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-01_bcxaic.jpg\"><CropperDescription /><CropperImage /><CropperCropArea /></Cropper><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Basic cropper ∙{{ ' ' }}<a href=\"https://github.com/origin-space/image-cropper\" class=\"hover:text-foreground underline\" target=\"_blank\">API\n        </a></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/image-cropper/image-cropper-02.html",
          "target": "components/ui/image-cropper-02.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex flex-col items-center gap-2\"><Cropper class=\"h-80\" image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-01_bcxaic.jpg\"><CropperDescription /><CropperImage /><CropperCropArea /></Cropper><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Basic cropper ∙${' '}<a href=\"https://github.com/origin-space/image-cropper\" class=\"hover:text-foreground underline\" target=\"_blank\">API\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/image-cropper/image-cropper-02.wxml",
          "target": "components/ui/image-cropper-02/image-cropper-02.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex flex-col items-center gap-2\"><cropper class=\"h-80\" image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-01_bcxaic.jpg\"><cropperdescription /><cropperimage /><croppercroparea /></cropper><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Basic cropper ∙{{ ' ' }}<a href=\"https://github.com/origin-space/image-cropper\" class=\"hover:text-foreground underline\" target=\"_blank\">API\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "image",
          "crop",
          "zoom"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "image-cropper-02",
          "group": "image-cropper",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "image-cropper-02",
              "path": "registry/default/components/image-cropper/image-cropper-02.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "image-cropper-02",
              "path": "registry/default/components/image-cropper/image-cropper-02.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "image-cropper-02",
              "path": "registry/default/components/image-cropper/image-cropper-02.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "image-cropper-02",
              "path": "registry/default/components/image-cropper/image-cropper-02.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "image-cropper",
        "title": "Image Cropper · Interactive State"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "image-cropper"
      ]
    },
    {
      "name": "image-cropper-03",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/cropper.json"
      ],
      "files": [
        {
          "path": "registry/default/components/image-cropper/image-cropper-03.tsx",
          "type": "registry:component",
          "target": "components/ui/image-cropper-03.tsx",
          "content": "import { Cropper, CropperCropArea, CropperDescription, CropperImage } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"flex flex-col items-center gap-2\">\n      <Cropper\n        className=\"h-80\"\n        image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-02_a2xwtd.jpg\"\n        aspectRatio={16 / 9}\n      >\n        <CropperDescription />\n        <CropperImage />\n        <CropperCropArea />\n      </Cropper>\n\n      <p aria-live=\"polite\" role=\"region\" className=\"text-muted-foreground mt-2 text-xs\">\n        Cropper with aspect ratio 16:9 ∙{' '}\n        <a\n          href=\"https://github.com/origin-space/image-cropper\"\n          className=\"hover:text-foreground underline\"\n          target=\"_blank\"\n        >\n          API\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/image-cropper/image-cropper-03.vue",
          "target": "components/ui/image-cropper-03.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Cropper, CropperCropArea, CropperDescription, CropperImage } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"flex flex-col items-center gap-2\"><Cropper class=\"h-80\" image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-02_a2xwtd.jpg\" :aspectRatio=\"16 / 9\"><CropperDescription /><CropperImage /><CropperCropArea /></Cropper><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Cropper with aspect ratio 16:9 ∙{{ ' ' }}<a href=\"https://github.com/origin-space/image-cropper\" class=\"hover:text-foreground underline\" target=\"_blank\">API\n        </a></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/image-cropper/image-cropper-03.html",
          "target": "components/ui/image-cropper-03.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex flex-col items-center gap-2\"><Cropper class=\"h-80\" image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-02_a2xwtd.jpg\" aspectratio=\"${16 / 9}\"><CropperDescription /><CropperImage /><CropperCropArea /></Cropper><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Cropper with aspect ratio 16:9 ∙${' '}<a href=\"https://github.com/origin-space/image-cropper\" class=\"hover:text-foreground underline\" target=\"_blank\">API\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/image-cropper/image-cropper-03.wxml",
          "target": "components/ui/image-cropper-03/image-cropper-03.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex flex-col items-center gap-2\"><cropper class=\"h-80\" image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-02_a2xwtd.jpg\" aspectratio=\"{{16 / 9}}\"><cropperdescription /><cropperimage /><croppercroparea /></cropper><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Cropper with aspect ratio 16:9 ∙{{ ' ' }}<a href=\"https://github.com/origin-space/image-cropper\" class=\"hover:text-foreground underline\" target=\"_blank\">API\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "image",
          "crop",
          "zoom"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "image-cropper-03",
          "group": "image-cropper",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "image-cropper-03",
              "path": "registry/default/components/image-cropper/image-cropper-03.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "image-cropper-03",
              "path": "registry/default/components/image-cropper/image-cropper-03.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "image-cropper-03",
              "path": "registry/default/components/image-cropper/image-cropper-03.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "image-cropper-03",
              "path": "registry/default/components/image-cropper/image-cropper-03.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "image-cropper",
        "title": "Image Cropper · Interactive State"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "image-cropper"
      ]
    },
    {
      "name": "image-cropper-04",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/cropper.json"
      ],
      "files": [
        {
          "path": "registry/default/components/image-cropper/image-cropper-04.tsx",
          "type": "registry:component",
          "target": "components/ui/image-cropper-04.tsx",
          "content": "import { Cropper, CropperCropArea, CropperDescription, CropperImage } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"flex flex-col items-center gap-2\">\n      <Cropper\n        className=\"h-80\"\n        image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-03_uym8r0.jpg\"\n      >\n        <CropperDescription />\n        <CropperImage />\n        <CropperCropArea className=\"border-blue-500\" />\n      </Cropper>\n\n      <p aria-live=\"polite\" role=\"region\" className=\"text-muted-foreground mt-2 text-xs\">\n        Cropper with custom crop area color ∙{' '}\n        <a\n          href=\"https://github.com/origin-space/image-cropper\"\n          className=\"hover:text-foreground underline\"\n          target=\"_blank\"\n        >\n          API\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/image-cropper/image-cropper-04.vue",
          "target": "components/ui/image-cropper-04.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Cropper, CropperCropArea, CropperDescription, CropperImage } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"flex flex-col items-center gap-2\"><Cropper class=\"h-80\" image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-03_uym8r0.jpg\"><CropperDescription /><CropperImage /><CropperCropArea class=\"border-blue-500\" /></Cropper><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Cropper with custom crop area color ∙{{ ' ' }}<a href=\"https://github.com/origin-space/image-cropper\" class=\"hover:text-foreground underline\" target=\"_blank\">API\n        </a></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/image-cropper/image-cropper-04.html",
          "target": "components/ui/image-cropper-04.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex flex-col items-center gap-2\"><Cropper class=\"h-80\" image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-03_uym8r0.jpg\"><CropperDescription /><CropperImage /><CropperCropArea class=\"border-blue-500\" /></Cropper><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Cropper with custom crop area color ∙${' '}<a href=\"https://github.com/origin-space/image-cropper\" class=\"hover:text-foreground underline\" target=\"_blank\">API\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/image-cropper/image-cropper-04.wxml",
          "target": "components/ui/image-cropper-04/image-cropper-04.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex flex-col items-center gap-2\"><cropper class=\"h-80\" image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-03_uym8r0.jpg\"><cropperdescription /><cropperimage /><croppercroparea class=\"border-blue-500\" /></cropper><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Cropper with custom crop area color ∙{{ ' ' }}<a href=\"https://github.com/origin-space/image-cropper\" class=\"hover:text-foreground underline\" target=\"_blank\">API\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "image",
          "crop",
          "zoom"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "image-cropper-04",
          "group": "image-cropper",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "image-cropper-04",
              "path": "registry/default/components/image-cropper/image-cropper-04.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "image-cropper-04",
              "path": "registry/default/components/image-cropper/image-cropper-04.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "image-cropper-04",
              "path": "registry/default/components/image-cropper/image-cropper-04.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "image-cropper-04",
              "path": "registry/default/components/image-cropper/image-cropper-04.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "image-cropper",
        "title": "Image Cropper · Interactive State"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "image-cropper"
      ]
    },
    {
      "name": "image-cropper-05",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/cropper.json"
      ],
      "files": [
        {
          "path": "registry/default/components/image-cropper/image-cropper-05.tsx",
          "type": "registry:component",
          "target": "components/ui/image-cropper-05.tsx",
          "content": "import { Cropper, CropperCropArea, CropperDescription, CropperImage } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"flex flex-col items-center gap-2\">\n      <Cropper\n        className=\"h-80 bg-black\"\n        image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-04_jflxhw.jpg\"\n      >\n        <CropperDescription />\n        <CropperImage />\n        <CropperCropArea className=\"shadow-[0_0_0_9999px_rgba(255,255,255,0.5)]\" />\n      </Cropper>\n\n      <p aria-live=\"polite\" role=\"region\" className=\"text-muted-foreground mt-2 text-xs\">\n        Cropper with custom mask overlay ∙{' '}\n        <a\n          href=\"https://github.com/origin-space/image-cropper\"\n          className=\"hover:text-foreground underline\"\n          target=\"_blank\"\n        >\n          API\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/image-cropper/image-cropper-05.vue",
          "target": "components/ui/image-cropper-05.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Cropper, CropperCropArea, CropperDescription, CropperImage } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"flex flex-col items-center gap-2\"><Cropper class=\"h-80 bg-black\" image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-04_jflxhw.jpg\"><CropperDescription /><CropperImage /><CropperCropArea class=\"shadow-[0_0_0_9999px_rgba(255,255,255,0.5)]\" /></Cropper><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Cropper with custom mask overlay ∙{{ ' ' }}<a href=\"https://github.com/origin-space/image-cropper\" class=\"hover:text-foreground underline\" target=\"_blank\">API\n        </a></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/image-cropper/image-cropper-05.html",
          "target": "components/ui/image-cropper-05.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex flex-col items-center gap-2\"><Cropper class=\"h-80 bg-black\" image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-04_jflxhw.jpg\"><CropperDescription /><CropperImage /><CropperCropArea class=\"shadow-[0_0_0_9999px_rgba(255,255,255,0.5)]\" /></Cropper><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Cropper with custom mask overlay ∙${' '}<a href=\"https://github.com/origin-space/image-cropper\" class=\"hover:text-foreground underline\" target=\"_blank\">API\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/image-cropper/image-cropper-05.wxml",
          "target": "components/ui/image-cropper-05/image-cropper-05.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex flex-col items-center gap-2\"><cropper class=\"h-80 bg-black\" image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-04_jflxhw.jpg\"><cropperdescription /><cropperimage /><croppercroparea class=\"shadow-[0_0_0_9999px_rgba(255,255,255,0.5)]\" /></cropper><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Cropper with custom mask overlay ∙{{ ' ' }}<a href=\"https://github.com/origin-space/image-cropper\" class=\"hover:text-foreground underline\" target=\"_blank\">API\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "image",
          "crop",
          "zoom"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "image-cropper-05",
          "group": "image-cropper",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "image-cropper-05",
              "path": "registry/default/components/image-cropper/image-cropper-05.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "image-cropper-05",
              "path": "registry/default/components/image-cropper/image-cropper-05.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "image-cropper-05",
              "path": "registry/default/components/image-cropper/image-cropper-05.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "image-cropper-05",
              "path": "registry/default/components/image-cropper/image-cropper-05.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "image-cropper",
        "title": "Image Cropper · Interactive State"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "image-cropper"
      ]
    },
    {
      "name": "image-cropper-06",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/cropper.json"
      ],
      "files": [
        {
          "path": "registry/default/components/image-cropper/image-cropper-06.tsx",
          "type": "registry:component",
          "target": "components/ui/image-cropper-06.tsx",
          "content": "import { Cropper, CropperCropArea, CropperDescription, CropperImage } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"flex flex-col items-center gap-2\">\n      <Cropper\n        className=\"aspect-square size-80\"\n        cropPadding={0}\n        image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-05_evczb3.jpg\"\n      >\n        <CropperDescription />\n        <CropperImage />\n        <CropperCropArea className=\"border-4 border-blue-500\" />\n      </Cropper>\n\n      <p aria-live=\"polite\" role=\"region\" className=\"text-muted-foreground mt-2 text-xs\">\n        Cropper with full size crop area ∙{' '}\n        <a\n          href=\"https://github.com/origin-space/image-cropper\"\n          className=\"hover:text-foreground underline\"\n          target=\"_blank\"\n        >\n          API\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/image-cropper/image-cropper-06.vue",
          "target": "components/ui/image-cropper-06.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Cropper, CropperCropArea, CropperDescription, CropperImage } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"flex flex-col items-center gap-2\"><Cropper class=\"aspect-square size-80\" :cropPadding=\"0\" image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-05_evczb3.jpg\"><CropperDescription /><CropperImage /><CropperCropArea class=\"border-4 border-blue-500\" /></Cropper><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Cropper with full size crop area ∙{{ ' ' }}<a href=\"https://github.com/origin-space/image-cropper\" class=\"hover:text-foreground underline\" target=\"_blank\">API\n        </a></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/image-cropper/image-cropper-06.html",
          "target": "components/ui/image-cropper-06.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex flex-col items-center gap-2\"><Cropper class=\"aspect-square size-80\" croppadding=\"${0}\" image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-05_evczb3.jpg\"><CropperDescription /><CropperImage /><CropperCropArea class=\"border-4 border-blue-500\" /></Cropper><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Cropper with full size crop area ∙${' '}<a href=\"https://github.com/origin-space/image-cropper\" class=\"hover:text-foreground underline\" target=\"_blank\">API\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/image-cropper/image-cropper-06.wxml",
          "target": "components/ui/image-cropper-06/image-cropper-06.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex flex-col items-center gap-2\"><cropper class=\"aspect-square size-80\" croppadding=\"{{0}}\" image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-05_evczb3.jpg\"><cropperdescription /><cropperimage /><croppercroparea class=\"border-4 border-blue-500\" /></cropper><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Cropper with full size crop area ∙{{ ' ' }}<a href=\"https://github.com/origin-space/image-cropper\" class=\"hover:text-foreground underline\" target=\"_blank\">API\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "image",
          "crop",
          "zoom"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "image-cropper-06",
          "group": "image-cropper",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "image-cropper-06",
              "path": "registry/default/components/image-cropper/image-cropper-06.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "image-cropper-06",
              "path": "registry/default/components/image-cropper/image-cropper-06.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "image-cropper-06",
              "path": "registry/default/components/image-cropper/image-cropper-06.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "image-cropper-06",
              "path": "registry/default/components/image-cropper/image-cropper-06.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "image-cropper",
        "title": "Image Cropper · Interactive State"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "image-cropper"
      ]
    },
    {
      "name": "image-cropper-07",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/cropper.json"
      ],
      "files": [
        {
          "path": "registry/default/components/image-cropper/image-cropper-07.tsx",
          "type": "registry:component",
          "target": "components/ui/image-cropper-07.tsx",
          "content": "import { Cropper, CropperCropArea, CropperDescription, CropperImage } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"flex flex-col items-center gap-2\">\n      <Cropper\n        className=\"h-80\"\n        image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-06_dduwky.jpg\"\n      >\n        <CropperDescription />\n        <CropperImage />\n        <CropperCropArea className=\"rounded-full\" />\n      </Cropper>\n\n      <p aria-live=\"polite\" role=\"region\" className=\"text-muted-foreground mt-2 text-xs\">\n        Cropper with full-rounded mask ∙{' '}\n        <a\n          href=\"https://github.com/origin-space/image-cropper\"\n          className=\"hover:text-foreground underline\"\n          target=\"_blank\"\n        >\n          API\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/image-cropper/image-cropper-07.vue",
          "target": "components/ui/image-cropper-07.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Cropper, CropperCropArea, CropperDescription, CropperImage } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"flex flex-col items-center gap-2\"><Cropper class=\"h-80\" image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-06_dduwky.jpg\"><CropperDescription /><CropperImage /><CropperCropArea class=\"rounded-full\" /></Cropper><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Cropper with full-rounded mask ∙{{ ' ' }}<a href=\"https://github.com/origin-space/image-cropper\" class=\"hover:text-foreground underline\" target=\"_blank\">API\n        </a></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/image-cropper/image-cropper-07.html",
          "target": "components/ui/image-cropper-07.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex flex-col items-center gap-2\"><Cropper class=\"h-80\" image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-06_dduwky.jpg\"><CropperDescription /><CropperImage /><CropperCropArea class=\"rounded-full\" /></Cropper><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Cropper with full-rounded mask ∙${' '}<a href=\"https://github.com/origin-space/image-cropper\" class=\"hover:text-foreground underline\" target=\"_blank\">API\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/image-cropper/image-cropper-07.wxml",
          "target": "components/ui/image-cropper-07/image-cropper-07.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex flex-col items-center gap-2\"><cropper class=\"h-80\" image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-06_dduwky.jpg\"><cropperdescription /><cropperimage /><croppercroparea class=\"rounded-full\" /></cropper><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Cropper with full-rounded mask ∙{{ ' ' }}<a href=\"https://github.com/origin-space/image-cropper\" class=\"hover:text-foreground underline\" target=\"_blank\">API\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "image",
          "crop",
          "zoom"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "image-cropper-07",
          "group": "image-cropper",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "image-cropper-07",
              "path": "registry/default/components/image-cropper/image-cropper-07.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "image-cropper-07",
              "path": "registry/default/components/image-cropper/image-cropper-07.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "image-cropper-07",
              "path": "registry/default/components/image-cropper/image-cropper-07.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "image-cropper-07",
              "path": "registry/default/components/image-cropper/image-cropper-07.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "image-cropper",
        "title": "Image Cropper · Interactive State"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "image-cropper"
      ]
    },
    {
      "name": "image-cropper-08",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/cropper.json",
        "https://ui.timkit.cn/r/select.json"
      ],
      "files": [
        {
          "path": "registry/default/components/image-cropper/image-cropper-08.tsx",
          "type": "registry:component",
          "target": "components/ui/image-cropper-08.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Cropper, CropperCropArea, CropperDescription, CropperImage, Slider } from '@timui/react'\n\nexport default function Component() {\n  const [zoom, setZoom] = useState(1)\n\n  return (\n    <div className=\"flex flex-col items-center gap-2\">\n      <div className=\"flex w-full flex-col gap-4\">\n        <Cropper\n          className=\"h-80\"\n          image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-07_scsejv.jpg\"\n          zoom={zoom}\n          onZoomChange={setZoom}\n        >\n          <CropperDescription />\n          <CropperImage />\n          <CropperCropArea />\n        </Cropper>\n        <div className=\"mx-auto flex w-full max-w-80 items-center gap-1\">\n          <Slider\n            defaultValue={[1]}\n            value={[zoom]}\n            min={1}\n            max={3}\n            step={0.1}\n            onValueChange={(value) => setZoom(value[0])}\n            aria-label=\"Zoom slider\"\n          />\n          <output className=\"block w-10 shrink-0 text-right text-sm font-medium tabular-nums\">\n            {parseFloat(zoom.toFixed(1))}x\n          </output>\n        </div>\n      </div>\n\n      <p aria-live=\"polite\" role=\"region\" className=\"text-muted-foreground mt-2 text-xs\">\n        Cropper with zoom slider ∙{' '}\n        <a\n          href=\"https://github.com/origin-space/image-cropper\"\n          className=\"hover:text-foreground underline\"\n          target=\"_blank\"\n        >\n          API\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/image-cropper/image-cropper-08.vue",
          "target": "components/ui/image-cropper-08.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Cropper, CropperCropArea, CropperDescription, CropperImage } from '@timui/vue';\nimport { Slider } from '@timui/vue';\n\n\n\nconst zoom = ref(1);\n\n\nfunction setZoom(next: typeof zoom.value | ((prev: typeof zoom.value) => typeof zoom.value)) {\n  zoom.value = typeof next === 'function'\n    ? (next as (prev: typeof zoom.value) => typeof zoom.value)(zoom.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <div class=\"flex flex-col items-center gap-2\"><div class=\"flex w-full flex-col gap-4\"><Cropper class=\"h-80\" image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-07_scsejv.jpg\" :zoom=\"zoom\" :onZoomChange=\"setZoom\"><CropperDescription /><CropperImage /><CropperCropArea /></Cropper><div class=\"mx-auto flex w-full max-w-80 items-center gap-1\"><Slider :default-value=\"[1]\" :value=\"[zoom]\" :min=\"1\" :max=\"3\" :step=\"0.1\" @update:modelValue=\"setZoom(value[0])\" aria-label=\"Zoom slider\" /><output class=\"block w-10 shrink-0 text-right text-sm font-medium tabular-nums\">{{ parseFloat(zoom.toFixed(1)) }}x\n          </output></div></div><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Cropper with zoom slider ∙{{ ' ' }}<a href=\"https://github.com/origin-space/image-cropper\" class=\"hover:text-foreground underline\" target=\"_blank\">API\n        </a></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/image-cropper/image-cropper-08.html",
          "target": "components/ui/image-cropper-08.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex flex-col items-center gap-2\"><div class=\"flex w-full flex-col gap-4\"><Cropper class=\"h-80\" image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-07_scsejv.jpg\" zoom=\"${zoom}\" onzoomchange=\"${setZoom}\"><CropperDescription /><CropperImage /><CropperCropArea /></Cropper><div class=\"mx-auto flex w-full max-w-80 items-center gap-1\"><Slider default-value=\"${[1]}\" value=\"${[zoom]}\" min=\"${1}\" max=\"${3}\" step=\"${0.1}\" on-value-change=\"${(value) => setZoom(value[0])}\" aria-label=\"Zoom slider\" /><output class=\"block w-10 shrink-0 text-right text-sm font-medium tabular-nums\">${parseFloat(zoom.toFixed(1))}x\n          </output></div></div><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Cropper with zoom slider ∙${' '}<a href=\"https://github.com/origin-space/image-cropper\" class=\"hover:text-foreground underline\" target=\"_blank\">API\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/image-cropper/image-cropper-08.wxml",
          "target": "components/ui/image-cropper-08/image-cropper-08.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex flex-col items-center gap-2\"><view class=\"flex w-full flex-col gap-4\"><cropper class=\"h-80\" image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-07_scsejv.jpg\" zoom=\"{{zoom}}\" onzoomchange=\"{{setZoom}}\"><cropperdescription /><cropperimage /><croppercroparea /></cropper><view class=\"mx-auto flex w-full max-w-80 items-center gap-1\"><slider default-value=\"{{[1]}}\" value=\"{{[zoom]}}\" min=\"{{1}}\" max=\"{{3}}\" step=\"{{0.1}}\" bindchange=\"setZoom(value[0])\" aria-label=\"Zoom slider\" /><output class=\"block w-10 shrink-0 text-right text-sm font-medium tabular-nums\">{{ parseFloat(zoom.toFixed(1)) }}x\n          </output></view></view><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Cropper with zoom slider ∙{{ ' ' }}<a href=\"https://github.com/origin-space/image-cropper\" class=\"hover:text-foreground underline\" target=\"_blank\">API\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "image",
          "crop",
          "zoom",
          "slider"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "image-cropper-08",
          "group": "image-cropper",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "image-cropper-08",
              "path": "registry/default/components/image-cropper/image-cropper-08.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "image-cropper-08",
              "path": "registry/default/components/image-cropper/image-cropper-08.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "image-cropper-08",
              "path": "registry/default/components/image-cropper/image-cropper-08.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "image-cropper-08",
              "path": "registry/default/components/image-cropper/image-cropper-08.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "image-cropper",
        "title": "Image Cropper · Zoom slider"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "image-cropper"
      ]
    },
    {
      "name": "image-cropper-09",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/cropper.json"
      ],
      "files": [
        {
          "path": "registry/default/components/image-cropper/image-cropper-09.tsx",
          "type": "registry:component",
          "target": "components/ui/image-cropper-09.tsx",
          "content": "import { Cropper, CropperCropArea, CropperDescription, CropperImage } from '@timui/react'\n\nexport default function Component() {\n  return (\n    <div className=\"flex flex-col items-center gap-2\">\n      <Cropper\n        className=\"h-80\"\n        minZoom={2}\n        maxZoom={10}\n        image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-08_wneftq.jpg\"\n      >\n        <CropperDescription />\n        <CropperImage />\n        <CropperCropArea />\n      </Cropper>\n\n      <p aria-live=\"polite\" role=\"region\" className=\"text-muted-foreground mt-2 text-xs\">\n        Cropper with custom zoom limits ∙{' '}\n        <a\n          href=\"https://github.com/origin-space/image-cropper\"\n          className=\"hover:text-foreground underline\"\n          target=\"_blank\"\n        >\n          API\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/image-cropper/image-cropper-09.vue",
          "target": "components/ui/image-cropper-09.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Cropper, CropperCropArea, CropperDescription, CropperImage } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <div class=\"flex flex-col items-center gap-2\"><Cropper class=\"h-80\" :minZoom=\"2\" :maxZoom=\"10\" image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-08_wneftq.jpg\"><CropperDescription /><CropperImage /><CropperCropArea /></Cropper><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Cropper with custom zoom limits ∙{{ ' ' }}<a href=\"https://github.com/origin-space/image-cropper\" class=\"hover:text-foreground underline\" target=\"_blank\">API\n        </a></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/image-cropper/image-cropper-09.html",
          "target": "components/ui/image-cropper-09.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex flex-col items-center gap-2\"><Cropper class=\"h-80\" minzoom=\"${2}\" maxzoom=\"${10}\" image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-08_wneftq.jpg\"><CropperDescription /><CropperImage /><CropperCropArea /></Cropper><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Cropper with custom zoom limits ∙${' '}<a href=\"https://github.com/origin-space/image-cropper\" class=\"hover:text-foreground underline\" target=\"_blank\">API\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/image-cropper/image-cropper-09.wxml",
          "target": "components/ui/image-cropper-09/image-cropper-09.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex flex-col items-center gap-2\"><cropper class=\"h-80\" minzoom=\"{{2}}\" maxzoom=\"{{10}}\" image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-08_wneftq.jpg\"><cropperdescription /><cropperimage /><croppercroparea /></cropper><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Cropper with custom zoom limits ∙{{ ' ' }}<a href=\"https://github.com/origin-space/image-cropper\" class=\"hover:text-foreground underline\" target=\"_blank\">API\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "image",
          "crop",
          "zoom"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "image-cropper-09",
          "group": "image-cropper",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "image-cropper-09",
              "path": "registry/default/components/image-cropper/image-cropper-09.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "image-cropper-09",
              "path": "registry/default/components/image-cropper/image-cropper-09.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "image-cropper-09",
              "path": "registry/default/components/image-cropper/image-cropper-09.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "image-cropper-09",
              "path": "registry/default/components/image-cropper/image-cropper-09.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "image-cropper",
        "title": "Image Cropper · Interactive State"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "image-cropper"
      ]
    },
    {
      "name": "image-cropper-10",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/cropper.json"
      ],
      "files": [
        {
          "path": "registry/default/components/image-cropper/image-cropper-10.tsx",
          "type": "registry:component",
          "target": "components/ui/image-cropper-10.tsx",
          "content": "'use client'\n\nimport React from 'react'\nimport { Cropper, CropperCropArea, CropperDescription, CropperImage } from '@timui/react'\n\ntype Area = { x: number; y: number; width: number; height: number }\n\nexport default function Component() {\n  const [cropData, setCropData] = React.useState<Area | null>(null)\n\n  return (\n    <div className=\"flex flex-col items-center gap-2\">\n      <div className=\"flex w-full flex-col gap-4\">\n        <Cropper\n          className=\"h-80\"\n          cropPadding={20}\n          image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-09_qskkln.jpg\"\n          onCropChange={setCropData}\n        >\n          <CropperDescription />\n          <CropperImage />\n          <CropperCropArea />\n        </Cropper>\n\n        {cropData && (\n          <pre className=\"bg-muted text-foreground/80 overflow-auto rounded-md border px-4 py-3 font-mono text-xs\">\n            <code>{JSON.stringify(cropData, null, 2)}</code>\n          </pre>\n        )}\n      </div>\n\n      <p aria-live=\"polite\" role=\"region\" className=\"text-muted-foreground mt-2 text-xs\">\n        Cropper with crop data output ∙{' '}\n        <a\n          href=\"https://github.com/origin-space/image-cropper\"\n          className=\"hover:text-foreground underline\"\n          target=\"_blank\"\n          rel=\"noopener noreferrer\"\n        >\n          API\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/image-cropper/image-cropper-10.vue",
          "target": "components/ui/image-cropper-10.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Cropper, CropperCropArea, CropperDescription, CropperImage } from '@timui/vue';\n\n\n\nconst cropData = ref<Area | null>(null);\n\n\nfunction setCropData(next: typeof cropData.value | ((prev: typeof cropData.value) => typeof cropData.value)) {\n  cropData.value = typeof next === 'function'\n    ? (next as (prev: typeof cropData.value) => typeof cropData.value)(cropData.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <div class=\"flex flex-col items-center gap-2\"><div class=\"flex w-full flex-col gap-4\"><Cropper class=\"h-80\" :cropPadding=\"20\" image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-09_qskkln.jpg\" :onCropChange=\"setCropData\"><CropperDescription /><CropperImage /><CropperCropArea /></Cropper><pre v-if=\"cropData\" class=\"bg-muted text-foreground/80 overflow-auto rounded-md border px-4 py-3 font-mono text-xs\"><code>{{ JSON.stringify(cropData, null, 2) }}</code></pre></div><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Cropper with crop data output ∙{{ ' ' }}<a href=\"https://github.com/origin-space/image-cropper\" class=\"hover:text-foreground underline\" target=\"_blank\" rel=\"noopener noreferrer\">API\n        </a></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/image-cropper/image-cropper-10.html",
          "target": "components/ui/image-cropper-10.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex flex-col items-center gap-2\"><div class=\"flex w-full flex-col gap-4\"><Cropper class=\"h-80\" croppadding=\"${20}\" image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-09_qskkln.jpg\" oncropchange=\"${setCropData}\"><CropperDescription /><CropperImage /><CropperCropArea /></Cropper><!-- if cropData -->\n<pre class=\"bg-muted text-foreground/80 overflow-auto rounded-md border px-4 py-3 font-mono text-xs\"><code>${JSON.stringify(cropData, null, 2)}</code></pre>\n<!-- endif --></div><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Cropper with crop data output ∙${' '}<a href=\"https://github.com/origin-space/image-cropper\" class=\"hover:text-foreground underline\" target=\"_blank\" rel=\"noopener noreferrer\">API\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/image-cropper/image-cropper-10.wxml",
          "target": "components/ui/image-cropper-10/image-cropper-10.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex flex-col items-center gap-2\"><view class=\"flex w-full flex-col gap-4\"><cropper class=\"h-80\" croppadding=\"{{20}}\" image=\"https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-09_qskkln.jpg\" oncropchange=\"{{setCropData}}\"><cropperdescription /><cropperimage /><croppercroparea /></cropper><pre wx:if=\"{{cropData}}\" class=\"bg-muted text-foreground/80 overflow-auto rounded-md border px-4 py-3 font-mono text-xs\"><code>{{ JSON.stringify(cropData, null, 2) }}</code></pre></view><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Cropper with crop data output ∙{{ ' ' }}<a href=\"https://github.com/origin-space/image-cropper\" class=\"hover:text-foreground underline\" target=\"_blank\" rel=\"noopener noreferrer\">API\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "image",
          "crop",
          "zoom"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "image-cropper-10",
          "group": "image-cropper",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "image-cropper-10",
              "path": "registry/default/components/image-cropper/image-cropper-10.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "image-cropper-10",
              "path": "registry/default/components/image-cropper/image-cropper-10.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "image-cropper-10",
              "path": "registry/default/components/image-cropper/image-cropper-10.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "image-cropper-10",
              "path": "registry/default/components/image-cropper/image-cropper-10.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "image-cropper",
        "title": "Image Cropper · Interactive State"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "image-cropper"
      ]
    },
    {
      "name": "image-cropper-11",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/cropper.json"
      ],
      "files": [
        {
          "path": "registry/default/components/image-cropper/image-cropper-11.tsx",
          "type": "registry:component",
          "target": "components/ui/image-cropper-11.tsx",
          "content": "'use client'\n\nimport { useCallback, useEffect, useState } from 'react'\nimport { Button, Cropper, CropperCropArea, CropperDescription, CropperImage } from '@timui/react'\n\n// Define type for pixel crop area\ntype Area = { x: number; y: number; width: number; height: number }\n\n// --- Start: Copied Helper Functions ---\nconst createImage = (url: string): Promise<HTMLImageElement> =>\n  new Promise((resolve, reject) => {\n    const image = new Image()\n    image.addEventListener('load', () => resolve(image))\n    image.addEventListener('error', (error) => reject(error))\n    image.setAttribute('crossOrigin', 'anonymous') // Needed for canvas Tainted check\n    image.src = url\n  })\n\nasync function getCroppedImg(\n  imageSrc: string,\n  pixelCrop: Area,\n  outputWidth: number = pixelCrop.width, // Optional: specify output size\n  outputHeight: number = pixelCrop.height\n): Promise<Blob | null> {\n  try {\n    const image = await createImage(imageSrc)\n    const canvas = document.createElement('canvas')\n    const ctx = canvas.getContext('2d')\n\n    if (!ctx) {\n      return null\n    }\n\n    // Set canvas size to desired output size\n    canvas.width = outputWidth\n    canvas.height = outputHeight\n\n    // Draw the cropped image onto the canvas\n    ctx.drawImage(\n      image,\n      pixelCrop.x,\n      pixelCrop.y,\n      pixelCrop.width,\n      pixelCrop.height,\n      0,\n      0,\n      outputWidth, // Draw onto the output size\n      outputHeight\n    )\n\n    // Convert canvas to blob\n    return new Promise((resolve) => {\n      canvas.toBlob((blob) => {\n        resolve(blob)\n      }, 'image/jpeg') // Specify format and quality if needed\n    })\n  } catch (error) {\n    console.error('Error in getCroppedImg:', error)\n    return null\n  }\n}\n// --- End: Copied Helper Functions ---\n\nconst ORIGINAL_IMAGE_URL =\n  'https://raw.githubusercontent.com/origin-space/origin-images/refs/heads/main/cropper-10_k24zxk.jpg'\n\nexport default function Component() {\n  const [croppedAreaPixels, setCroppedAreaPixels] = useState<Area | null>(null)\n  const [croppedImageUrl, setCroppedImageUrl] = useState<string | null>(null)\n\n  // Callback to update crop area state\n  const handleCropChange = useCallback((pixels: Area | null) => {\n    setCroppedAreaPixels(pixels)\n  }, [])\n\n  // Function to handle the crop button click\n  const handleCrop = async () => {\n    if (!croppedAreaPixels) {\n      console.error('No crop area selected.')\n      return\n    }\n\n    try {\n      const croppedBlob = await getCroppedImg(ORIGINAL_IMAGE_URL, croppedAreaPixels)\n      if (!croppedBlob) {\n        throw new Error('Failed to generate cropped image blob.')\n      }\n\n      // Create a new object URL\n      const newCroppedUrl = URL.createObjectURL(croppedBlob)\n\n      // Revoke the old URL if it exists\n      if (croppedImageUrl) {\n        URL.revokeObjectURL(croppedImageUrl)\n      }\n\n      // Set the new URL\n      setCroppedImageUrl(newCroppedUrl)\n    } catch (error) {\n      console.error('Error during cropping:', error)\n      // Optionally: Clear the old image URL on error\n      if (croppedImageUrl) {\n        URL.revokeObjectURL(croppedImageUrl)\n      }\n      setCroppedImageUrl(null)\n    }\n  }\n\n  // Effect for cleaning up the object URL\n  useEffect(() => {\n    // This is the cleanup function that runs when the component unmounts\n    // or when croppedImageUrl changes before the next effect runs.\n    const currentUrl = croppedImageUrl\n    return () => {\n      if (currentUrl && currentUrl.startsWith('blob:')) {\n        URL.revokeObjectURL(currentUrl)\n        console.log('Revoked URL:', currentUrl) // Optional: for debugging\n      }\n    }\n  }, [croppedImageUrl]) // Dependency array ensures cleanup runs when URL changes\n\n  return (\n    <div className=\"flex flex-col items-center gap-2\">\n      <div className=\"flex w-full flex-col gap-4 md:flex-row\">\n        <Cropper\n          className=\"h-64 md:flex-1\"\n          image={ORIGINAL_IMAGE_URL}\n          onCropChange={handleCropChange}\n        >\n          <CropperDescription />\n          <CropperImage />\n          <CropperCropArea />\n        </Cropper>\n        <div className=\"flex w-26 flex-col gap-4\">\n          <Button onClick={handleCrop} disabled={!croppedAreaPixels}>\n            Crop preview\n          </Button>\n          {/* Display Area */}\n          <div className=\"aspect-square w-full shrink-0 overflow-hidden rounded-lg border\">\n            {croppedImageUrl ? (\n              <img\n                src={croppedImageUrl}\n                alt=\"Cropped result\"\n                className=\"h-full w-full object-cover\"\n              />\n            ) : (\n              <div className=\"bg-muted text-muted-foreground/80 flex h-full w-full items-center justify-center p-2 text-center text-xs\">\n                Image preview\n              </div>\n            )}\n          </div>\n        </div>\n      </div>\n\n      <p aria-live=\"polite\" role=\"region\" className=\"text-muted-foreground mt-2 text-xs\">\n        Cropper with image preview ∙{' '}\n        <a\n          href=\"https://github.com/origin-space/image-cropper\"\n          className=\"hover:text-foreground underline\"\n          target=\"_blank\"\n          rel=\"noopener noreferrer\"\n        >\n          API\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/image-cropper/image-cropper-11.vue",
          "target": "components/ui/image-cropper-11.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Button } from '@timui/vue';\nimport { Cropper, CropperCropArea, CropperDescription, CropperImage } from '@timui/vue';\n\n\n\nconst croppedAreaPixels = ref<Area | null>(null);\nconst croppedImageUrl = ref<string | null>(null);\n\n</script>\n\n<template>\n  <div class=\"flex flex-col items-center gap-2\"><div class=\"flex w-full flex-col gap-4 md:flex-row\"><Cropper class=\"h-64 md:flex-1\" :image=\"ORIGINAL_IMAGE_URL\" :onCropChange=\"handleCropChange\"><CropperDescription /><CropperImage /><CropperCropArea /></Cropper><div class=\"flex w-26 flex-col gap-4\"><Button @click=\"handleCrop\" :disabled=\"!croppedAreaPixels\">Crop preview\n          </Button><div class=\"aspect-square w-full shrink-0 overflow-hidden rounded-lg border\"><template v-if=\"croppedImageUrl\">\n<img :src=\"croppedImageUrl\" alt=\"Cropped result\" class=\"h-full w-full object-cover\" />\n</template>\n<template v-else>\n<div class=\"bg-muted text-muted-foreground/80 flex h-full w-full items-center justify-center p-2 text-center text-xs\">Image preview\n              </div>\n</template></div></div></div><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Cropper with image preview ∙{{ ' ' }}<a href=\"https://github.com/origin-space/image-cropper\" class=\"hover:text-foreground underline\" target=\"_blank\" rel=\"noopener noreferrer\">API\n        </a></p></div>\n</template>\n"
        },
        {
          "path": "registry/default/components/image-cropper/image-cropper-11.html",
          "target": "components/ui/image-cropper-11.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex flex-col items-center gap-2\"><div class=\"flex w-full flex-col gap-4 md:flex-row\"><Cropper class=\"h-64 md:flex-1\" image=\"${ORIGINAL_IMAGE_URL}\" oncropchange=\"${handleCropChange}\"><CropperDescription /><CropperImage /><CropperCropArea /></Cropper><div class=\"flex w-26 flex-col gap-4\"><Button on-click=\"${handleCrop}\" disabled=\"${!croppedAreaPixels}\">Crop preview\n          </Button><div class=\"aspect-square w-full shrink-0 overflow-hidden rounded-lg border\"><!-- if croppedImageUrl -->\n<img src=\"${croppedImageUrl}\" alt=\"Cropped result\" class=\"h-full w-full object-cover\" />\n<!-- else -->\n<div class=\"bg-muted text-muted-foreground/80 flex h-full w-full items-center justify-center p-2 text-center text-xs\">Image preview\n              </div>\n<!-- endif --></div></div></div><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Cropper with image preview ∙${' '}<a href=\"https://github.com/origin-space/image-cropper\" class=\"hover:text-foreground underline\" target=\"_blank\" rel=\"noopener noreferrer\">API\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/image-cropper/image-cropper-11.wxml",
          "target": "components/ui/image-cropper-11/image-cropper-11.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex flex-col items-center gap-2\"><view class=\"flex w-full flex-col gap-4 md:flex-row\"><cropper class=\"h-64 md:flex-1\" image=\"{{ORIGINAL_IMAGE_URL}}\" oncropchange=\"{{handleCropChange}}\"><cropperdescription /><cropperimage /><croppercroparea /></cropper><view class=\"flex w-26 flex-col gap-4\"><button bindtap=\"handleCrop\" disabled=\"{{!croppedAreaPixels}}\">Crop preview\n          </button><view class=\"aspect-square w-full shrink-0 overflow-hidden rounded-lg border\"><block wx:if=\"{{croppedImageUrl}}\">\n<image src=\"{{croppedImageUrl}}\" alt=\"Cropped result\" class=\"h-full w-full object-cover\" />\n</block>\n<block wx:else>\n<view class=\"bg-muted text-muted-foreground/80 flex h-full w-full items-center justify-center p-2 text-center text-xs\">Image preview\n              </view>\n</block></view></view></view><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Cropper with image preview ∙{{ ' ' }}<a href=\"https://github.com/origin-space/image-cropper\" class=\"hover:text-foreground underline\" target=\"_blank\" rel=\"noopener noreferrer\">API\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "image",
          "crop",
          "zoom"
        ],
        "colSpan": 2,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "image-cropper-11",
          "group": "image-cropper",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "image-cropper-11",
              "path": "registry/default/components/image-cropper/image-cropper-11.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "image-cropper-11",
              "path": "registry/default/components/image-cropper/image-cropper-11.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "image-cropper-11",
              "path": "registry/default/components/image-cropper/image-cropper-11.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "image-cropper-11",
              "path": "registry/default/components/image-cropper/image-cropper-11.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "image-cropper",
        "title": "Image Cropper · Disabled State"
      },
      "dependencies": [
        "@timui/react"
      ],
      "categories": [
        "image-cropper"
      ]
    },
    {
      "name": "tree-01",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/tree.json"
      ],
      "files": [
        {
          "path": "registry/default/components/tree/tree-01.tsx",
          "type": "registry:component",
          "target": "components/ui/tree-01.tsx",
          "content": "'use client'\n\nimport React from 'react'\nimport { hotkeysCoreFeature, syncDataLoaderFeature } from '@headless-tree/core'\nimport { useTree } from '@headless-tree/react'\nimport { Tree, TreeItem, TreeItemLabel } from '@timui/react'\n\ninterface Item {\n  name: string\n  children?: string[]\n}\n\nconst items: Record<string, Item> = {\n  company: {\n    name: 'Company',\n    children: ['engineering', 'marketing', 'operations'],\n  },\n  engineering: {\n    name: 'Engineering',\n    children: ['frontend', 'backend', 'platform-team'],\n  },\n  frontend: { name: 'Frontend', children: ['design-system', 'web-platform'] },\n  'design-system': {\n    name: 'Design System',\n    children: ['components', 'tokens', 'guidelines'],\n  },\n  components: { name: 'Components' },\n  tokens: { name: 'Tokens' },\n  guidelines: { name: 'Guidelines' },\n  'web-platform': { name: 'Web Platform' },\n  backend: { name: 'Backend', children: ['apis', 'infrastructure'] },\n  apis: { name: 'APIs' },\n  infrastructure: { name: 'Infrastructure' },\n  'platform-team': { name: 'Platform Team' },\n  marketing: { name: 'Marketing', children: ['content', 'seo'] },\n  content: { name: 'Content' },\n  seo: { name: 'SEO' },\n  operations: { name: 'Operations', children: ['hr', 'finance'] },\n  hr: { name: 'HR' },\n  finance: { name: 'Finance' },\n}\n\nconst indent = 20\n\nexport default function Component() {\n  const tree = useTree<Item>({\n    initialState: {\n      expandedItems: ['engineering', 'frontend', 'design-system'],\n    },\n    indent,\n    rootItemId: 'company',\n    getItemName: (item) => item.getItemData().name,\n    isItemFolder: (item) => (item.getItemData()?.children?.length ?? 0) > 0,\n    dataLoader: {\n      getItem: (itemId) => items[itemId],\n      getChildren: (itemId) => items[itemId].children ?? [],\n    },\n    features: [syncDataLoaderFeature, hotkeysCoreFeature],\n  })\n\n  return (\n    <div className=\"flex h-full flex-col gap-2 *:first:grow\">\n      <Tree indent={indent} tree={tree}>\n        {tree.getItems().map((item) => {\n          return (\n            <TreeItem key={item.getId()} item={item}>\n              <TreeItemLabel />\n            </TreeItem>\n          )\n        })}\n      </Tree>\n\n      <p aria-live=\"polite\" role=\"region\" className=\"text-muted-foreground mt-2 text-xs\">\n        Basic tree with no extra features ∙{' '}\n        <a\n          href=\"https://headless-tree.lukasbach.com\"\n          className=\"hover:text-foreground underline\"\n          target=\"_blank\"\n          rel=\"noopener noreferrer\"\n        >\n          API\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tree/tree-01.vue",
          "target": "components/ui/tree-01.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport TreeDemoBase from './tree-demo-base.vue'\n</script>\n\n<template>\n  <TreeDemoBase variant=\"basic\" description=\"Basic tree with no extra features\" />\n</template>\n"
        },
        {
          "path": "registry/default/components/tree/tree-01.html",
          "target": "components/ui/tree-01.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex h-full flex-col gap-2 *:first:grow\"><Tree indent=\"${indent}\" tree=\"${tree}\">${tree.getItems().map((item) => {\n          return (\n            <TreeItem key={item.getId()} item={item}>\n              <TreeItemLabel />\n            </TreeItem>\n          )\n        })}</Tree><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Basic tree with no extra features ∙${' '}<a href=\"https://headless-tree.lukasbach.com\" class=\"hover:text-foreground underline\" target=\"_blank\" rel=\"noopener noreferrer\">API\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/tree/tree-01.wxml",
          "target": "components/ui/tree-01/tree-01.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex h-full flex-col gap-2 *:first:grow\"><tree indent=\"{{indent}}\" tree=\"{{tree}}\">{{ tree.getItems().map((item) => {\n          return (\n            <TreeItem key={item.getId()} item={item}>\n              <TreeItemLabel />\n            </TreeItem>\n          )\n        }) }}</tree><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Basic tree with no extra features ∙{{ ' ' }}<a href=\"https://headless-tree.lukasbach.com\" class=\"hover:text-foreground underline\" target=\"_blank\" rel=\"noopener noreferrer\">API\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tree"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tree-01",
          "group": "tree",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tree-01",
              "path": "registry/default/components/tree/tree-01.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tree-01",
              "path": "registry/default/components/tree/tree-01.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tree-01",
              "path": "registry/default/components/tree/tree-01.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tree-01",
              "path": "registry/default/components/tree/tree-01.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@headless-tree/core",
              "@headless-tree/react",
              "@timui/react"
            ]
          },
          "vue": {},
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tree",
        "title": "Tree · Interactive State"
      },
      "dependencies": [
        "@headless-tree/core",
        "@headless-tree/react",
        "@timui/react"
      ],
      "categories": [
        "tree"
      ]
    },
    {
      "name": "tree-02",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/tree.json"
      ],
      "files": [
        {
          "path": "registry/default/components/tree/tree-02.tsx",
          "type": "registry:component",
          "target": "components/ui/tree-02.tsx",
          "content": "'use client'\n\nimport React from 'react'\nimport { hotkeysCoreFeature, syncDataLoaderFeature } from '@headless-tree/core'\nimport { useTree } from '@headless-tree/react'\nimport { Tree, TreeItem, TreeItemLabel } from '@timui/react'\n\ninterface Item {\n  name: string\n  children?: string[]\n}\n\nconst items: Record<string, Item> = {\n  company: {\n    name: 'Company',\n    children: ['engineering', 'marketing', 'operations'],\n  },\n  engineering: {\n    name: 'Engineering',\n    children: ['frontend', 'backend', 'platform-team'],\n  },\n  frontend: { name: 'Frontend', children: ['design-system', 'web-platform'] },\n  'design-system': {\n    name: 'Design System',\n    children: ['components', 'tokens', 'guidelines'],\n  },\n  components: { name: 'Components' },\n  tokens: { name: 'Tokens' },\n  guidelines: { name: 'Guidelines' },\n  'web-platform': { name: 'Web Platform' },\n  backend: { name: 'Backend', children: ['apis', 'infrastructure'] },\n  apis: { name: 'APIs' },\n  infrastructure: { name: 'Infrastructure' },\n  'platform-team': { name: 'Platform Team' },\n  marketing: { name: 'Marketing', children: ['content', 'seo'] },\n  content: { name: 'Content' },\n  seo: { name: 'SEO' },\n  operations: { name: 'Operations', children: ['hr', 'finance'] },\n  hr: { name: 'HR' },\n  finance: { name: 'Finance' },\n}\n\nconst indent = 20\n\nexport default function Component() {\n  const tree = useTree<Item>({\n    initialState: {\n      expandedItems: ['engineering', 'frontend', 'design-system'],\n    },\n    indent,\n    rootItemId: 'company',\n    getItemName: (item) => item.getItemData().name,\n    isItemFolder: (item) => (item.getItemData()?.children?.length ?? 0) > 0,\n    dataLoader: {\n      getItem: (itemId) => items[itemId],\n      getChildren: (itemId) => items[itemId].children ?? [],\n    },\n    features: [syncDataLoaderFeature, hotkeysCoreFeature],\n  })\n\n  return (\n    <div className=\"flex h-full flex-col gap-2 *:first:grow\">\n      <div>\n        <Tree\n          className=\"relative before:absolute before:inset-0 before:-ms-1 before:bg-[repeating-linear-gradient(to_right,transparent_0,transparent_calc(var(--tree-indent)-1px),var(--border)_calc(var(--tree-indent)-1px),var(--border)_calc(var(--tree-indent)))]\"\n          indent={indent}\n          tree={tree}\n        >\n          {tree.getItems().map((item) => {\n            return (\n              <TreeItem key={item.getId()} item={item}>\n                <TreeItemLabel className=\"before:bg-background relative before:absolute before:inset-x-0 before:-inset-y-0.5 before:-z-10\" />\n              </TreeItem>\n            )\n          })}\n        </Tree>\n      </div>\n\n      <p aria-live=\"polite\" role=\"region\" className=\"text-muted-foreground mt-2 text-xs\">\n        Basic tree with vertical lines ∙{' '}\n        <a\n          href=\"https://headless-tree.lukasbach.com\"\n          className=\"hover:text-foreground underline\"\n          target=\"_blank\"\n          rel=\"noopener noreferrer\"\n        >\n          API\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tree/tree-02.vue",
          "target": "components/ui/tree-02.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport TreeDemoBase from './tree-demo-base.vue'\n</script>\n\n<template>\n  <TreeDemoBase variant=\"lines\" description=\"Basic tree with vertical lines\" />\n</template>\n"
        },
        {
          "path": "registry/default/components/tree/tree-02.html",
          "target": "components/ui/tree-02.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex h-full flex-col gap-2 *:first:grow\"><div><Tree class=\"relative before:absolute before:inset-0 before:-ms-1 before:bg-[repeating-linear-gradient(to_right,transparent_0,transparent_calc(var(--tree-indent)-1px),var(--border)_calc(var(--tree-indent)-1px),var(--border)_calc(var(--tree-indent)))]\" indent=\"${indent}\" tree=\"${tree}\">${tree.getItems().map((item) => {\n            return (\n              <TreeItem key={item.getId()} item={item}>\n                <TreeItemLabel className=\"before:bg-background relative before:absolute before:inset-x-0 before:-inset-y-0.5 before:-z-10\" />\n              </TreeItem>\n            )\n          })}</Tree></div><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Basic tree with vertical lines ∙${' '}<a href=\"https://headless-tree.lukasbach.com\" class=\"hover:text-foreground underline\" target=\"_blank\" rel=\"noopener noreferrer\">API\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/tree/tree-02.wxml",
          "target": "components/ui/tree-02/tree-02.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex h-full flex-col gap-2 *:first:grow\"><view><tree class=\"relative before:absolute before:inset-0 before:-ms-1 before:bg-[repeating-linear-gradient(to_right,transparent_0,transparent_calc(var(--tree-indent)-1px),var(--border)_calc(var(--tree-indent)-1px),var(--border)_calc(var(--tree-indent)))]\" indent=\"{{indent}}\" tree=\"{{tree}}\">{{ tree.getItems().map((item) => {\n            return (\n              <TreeItem key={item.getId()} item={item}>\n                <TreeItemLabel className=\"before:bg-background relative before:absolute before:inset-x-0 before:-inset-y-0.5 before:-z-10\" />\n              </TreeItem>\n            )\n          }) }}</tree></view><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Basic tree with vertical lines ∙{{ ' ' }}<a href=\"https://headless-tree.lukasbach.com\" class=\"hover:text-foreground underline\" target=\"_blank\" rel=\"noopener noreferrer\">API\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tree"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tree-02",
          "group": "tree",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tree-02",
              "path": "registry/default/components/tree/tree-02.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tree-02",
              "path": "registry/default/components/tree/tree-02.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tree-02",
              "path": "registry/default/components/tree/tree-02.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tree-02",
              "path": "registry/default/components/tree/tree-02.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@headless-tree/core",
              "@headless-tree/react",
              "@timui/react"
            ]
          },
          "vue": {},
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tree",
        "title": "Tree · Interactive State"
      },
      "dependencies": [
        "@headless-tree/core",
        "@headless-tree/react",
        "@timui/react"
      ],
      "categories": [
        "tree"
      ]
    },
    {
      "name": "tree-03",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/tree.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/tree/tree-03.tsx",
          "type": "registry:component",
          "target": "components/ui/tree-03.tsx",
          "content": "'use client'\n\nimport React from 'react'\nimport { hotkeysCoreFeature, syncDataLoaderFeature } from '@headless-tree/core'\nimport { useTree } from '@headless-tree/react'\nimport { Tree, TreeItem, TreeItemLabel } from '@timui/react'\nimport { FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react'\n\ninterface Item {\n  name: string\n  children?: string[]\n}\n\nconst items: Record<string, Item> = {\n  company: {\n    name: 'Company',\n    children: ['engineering', 'marketing', 'operations'],\n  },\n  engineering: {\n    name: 'Engineering',\n    children: ['frontend', 'backend', 'platform-team'],\n  },\n  frontend: { name: 'Frontend', children: ['design-system', 'web-platform'] },\n  'design-system': {\n    name: 'Design System',\n    children: ['components', 'tokens', 'guidelines'],\n  },\n  components: { name: 'Components' },\n  tokens: { name: 'Tokens' },\n  guidelines: { name: 'Guidelines' },\n  'web-platform': { name: 'Web Platform' },\n  backend: { name: 'Backend', children: ['apis', 'infrastructure'] },\n  apis: { name: 'APIs' },\n  infrastructure: { name: 'Infrastructure' },\n  'platform-team': { name: 'Platform Team' },\n  marketing: { name: 'Marketing', children: ['content', 'seo'] },\n  content: { name: 'Content' },\n  seo: { name: 'SEO' },\n  operations: { name: 'Operations', children: ['hr', 'finance'] },\n  hr: { name: 'HR' },\n  finance: { name: 'Finance' },\n}\n\nconst indent = 20\n\nexport default function Component() {\n  const tree = useTree<Item>({\n    initialState: {\n      expandedItems: ['engineering', 'frontend', 'design-system'],\n    },\n    indent,\n    rootItemId: 'company',\n    getItemName: (item) => item.getItemData().name,\n    isItemFolder: (item) => (item.getItemData()?.children?.length ?? 0) > 0,\n    dataLoader: {\n      getItem: (itemId) => items[itemId],\n      getChildren: (itemId) => items[itemId].children ?? [],\n    },\n    features: [syncDataLoaderFeature, hotkeysCoreFeature],\n  })\n\n  return (\n    <div className=\"flex h-full flex-col gap-2 *:first:grow\">\n      <div>\n        <Tree\n          className=\"relative before:absolute before:inset-0 before:-ms-1 before:bg-[repeating-linear-gradient(to_right,transparent_0,transparent_calc(var(--tree-indent)-1px),var(--border)_calc(var(--tree-indent)-1px),var(--border)_calc(var(--tree-indent)))]\"\n          indent={indent}\n          tree={tree}\n        >\n          {tree.getItems().map((item) => {\n            return (\n              <TreeItem key={item.getId()} item={item}>\n                <TreeItemLabel className=\"before:bg-background relative before:absolute before:inset-x-0 before:-inset-y-0.5 before:-z-10\">\n                  <span className=\"flex items-center gap-2\">\n                    {item.isFolder() ? (\n                      item.isExpanded() ? (\n                        <FolderOpenIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                      ) : (\n                        <FolderIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                      )\n                    ) : (\n                      <FileIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    )}\n                    {item.getItemName()}\n                  </span>\n                </TreeItemLabel>\n              </TreeItem>\n            )\n          })}\n        </Tree>\n      </div>\n\n      <p aria-live=\"polite\" role=\"region\" className=\"text-muted-foreground mt-2 text-xs\">\n        Basic tree with icons ∙{' '}\n        <a\n          href=\"https://headless-tree.lukasbach.com\"\n          className=\"hover:text-foreground underline\"\n          target=\"_blank\"\n          rel=\"noopener noreferrer\"\n        >\n          API\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tree/tree-03.vue",
          "target": "components/ui/tree-03.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport TreeDemoBase from './tree-demo-base.vue'\n</script>\n\n<template>\n  <TreeDemoBase variant=\"icons\" description=\"Basic tree with icons\" />\n</template>\n"
        },
        {
          "path": "registry/default/components/tree/tree-03.html",
          "target": "components/ui/tree-03.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex h-full flex-col gap-2 *:first:grow\"><div><Tree class=\"relative before:absolute before:inset-0 before:-ms-1 before:bg-[repeating-linear-gradient(to_right,transparent_0,transparent_calc(var(--tree-indent)-1px),var(--border)_calc(var(--tree-indent)-1px),var(--border)_calc(var(--tree-indent)))]\" indent=\"${indent}\" tree=\"${tree}\">${tree.getItems().map((item) => {\n            return (\n              <TreeItem key={item.getId()} item={item}>\n                <TreeItemLabel className=\"before:bg-background relative before:absolute before:inset-x-0 before:-inset-y-0.5 before:-z-10\">\n                  <span className=\"flex items-center gap-2\">\n                    {item.isFolder() ? (\n                      item.isExpanded() ? (\n                        <FolderOpenIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                      ) : (\n                        <FolderIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                      )\n                    ) : (\n                      <FileIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    )}\n                    {item.getItemName()}\n                  </span>\n                </TreeItemLabel>\n              </TreeItem>\n            )\n          })}</Tree></div><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Basic tree with icons ∙${' '}<a href=\"https://headless-tree.lukasbach.com\" class=\"hover:text-foreground underline\" target=\"_blank\" rel=\"noopener noreferrer\">API\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/tree/tree-03.wxml",
          "target": "components/ui/tree-03/tree-03.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex h-full flex-col gap-2 *:first:grow\"><view><tree class=\"relative before:absolute before:inset-0 before:-ms-1 before:bg-[repeating-linear-gradient(to_right,transparent_0,transparent_calc(var(--tree-indent)-1px),var(--border)_calc(var(--tree-indent)-1px),var(--border)_calc(var(--tree-indent)))]\" indent=\"{{indent}}\" tree=\"{{tree}}\">{{ tree.getItems().map((item) => {\n            return (\n              <TreeItem key={item.getId()} item={item}>\n                <TreeItemLabel className=\"before:bg-background relative before:absolute before:inset-x-0 before:-inset-y-0.5 before:-z-10\">\n                  <span className=\"flex items-center gap-2\">\n                    {item.isFolder() ? (\n                      item.isExpanded() ? (\n                        <FolderOpenIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                      ) : (\n                        <FolderIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                      )\n                    ) : (\n                      <FileIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    )}\n                    {item.getItemName()}\n                  </span>\n                </TreeItemLabel>\n              </TreeItem>\n            )\n          }) }}</tree></view><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Basic tree with icons ∙{{ ' ' }}<a href=\"https://headless-tree.lukasbach.com\" class=\"hover:text-foreground underline\" target=\"_blank\" rel=\"noopener noreferrer\">API\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tree"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tree-03",
          "group": "tree",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tree-03",
              "path": "registry/default/components/tree/tree-03.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tree-03",
              "path": "registry/default/components/tree/tree-03.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tree-03",
              "path": "registry/default/components/tree/tree-03.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tree-03",
              "path": "registry/default/components/tree/tree-03.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@headless-tree/core",
              "@headless-tree/react",
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {},
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tree",
        "title": "Tree · Interactive State"
      },
      "dependencies": [
        "@headless-tree/core",
        "@headless-tree/react",
        "@timui/react"
      ],
      "categories": [
        "tree"
      ]
    },
    {
      "name": "tree-04",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/tree.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/tree/tree-04.tsx",
          "type": "registry:component",
          "target": "components/ui/tree-04.tsx",
          "content": "'use client'\n\nimport React from 'react'\nimport { hotkeysCoreFeature, syncDataLoaderFeature } from '@headless-tree/core'\nimport { useTree } from '@headless-tree/react'\nimport { Tree, TreeItem, TreeItemLabel } from '@timui/react'\nimport { FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react'\n\ninterface Item {\n  name: string\n  children?: string[]\n}\n\nconst items: Record<string, Item> = {\n  company: {\n    name: 'Company',\n    children: ['engineering', 'marketing', 'operations'],\n  },\n  engineering: {\n    name: 'Engineering',\n    children: ['frontend', 'backend', 'platform-team'],\n  },\n  frontend: { name: 'Frontend', children: ['design-system', 'web-platform'] },\n  'design-system': {\n    name: 'Design System',\n    children: ['components', 'tokens', 'guidelines'],\n  },\n  components: { name: 'Components' },\n  tokens: { name: 'Tokens' },\n  guidelines: { name: 'Guidelines' },\n  'web-platform': { name: 'Web Platform' },\n  backend: { name: 'Backend', children: ['apis', 'infrastructure'] },\n  apis: { name: 'APIs' },\n  infrastructure: { name: 'Infrastructure' },\n  'platform-team': { name: 'Platform Team' },\n  marketing: { name: 'Marketing', children: ['content', 'seo'] },\n  content: { name: 'Content' },\n  seo: { name: 'SEO' },\n  operations: { name: 'Operations', children: ['hr', 'finance'] },\n  hr: { name: 'HR' },\n  finance: { name: 'Finance' },\n}\n\nconst indent = 20\n\nexport default function Component() {\n  const tree = useTree<Item>({\n    initialState: {\n      expandedItems: ['engineering', 'frontend', 'design-system'],\n    },\n    indent,\n    rootItemId: 'company',\n    getItemName: (item) => item.getItemData().name,\n    isItemFolder: (item) => (item.getItemData()?.children?.length ?? 0) > 0,\n    dataLoader: {\n      getItem: (itemId) => items[itemId],\n      getChildren: (itemId) => items[itemId].children ?? [],\n    },\n    features: [syncDataLoaderFeature, hotkeysCoreFeature],\n  })\n\n  return (\n    <div className=\"flex h-full flex-col gap-2 *:first:grow\">\n      <div>\n        <Tree\n          className=\"relative before:absolute before:inset-0 before:-ms-1 before:bg-[repeating-linear-gradient(to_right,transparent_0,transparent_calc(var(--tree-indent)-1px),var(--border)_calc(var(--tree-indent)-1px),var(--border)_calc(var(--tree-indent)))]\"\n          indent={indent}\n          tree={tree}\n        >\n          {tree.getItems().map((item) => {\n            return (\n              <TreeItem key={item.getId()} item={item}>\n                <TreeItemLabel className=\"before:bg-background relative before:absolute before:inset-x-0 before:-inset-y-0.5 before:-z-10\">\n                  <span className=\"-order-1 flex flex-1 items-center gap-2\">\n                    {item.isFolder() ? (\n                      item.isExpanded() ? (\n                        <FolderOpenIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                      ) : (\n                        <FolderIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                      )\n                    ) : (\n                      <FileIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    )}\n                    {item.getItemName()}\n                  </span>\n                </TreeItemLabel>\n              </TreeItem>\n            )\n          })}\n        </Tree>\n      </div>\n\n      <p aria-live=\"polite\" role=\"region\" className=\"text-muted-foreground mt-2 text-xs\">\n        Basic tree with caret icon on the right ∙{' '}\n        <a\n          href=\"https://headless-tree.lukasbach.com\"\n          className=\"hover:text-foreground underline\"\n          target=\"_blank\"\n          rel=\"noopener noreferrer\"\n        >\n          API\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tree/tree-04.vue",
          "target": "components/ui/tree-04.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport TreeDemoBase from './tree-demo-base.vue'\n</script>\n\n<template>\n  <TreeDemoBase variant=\"caret-right\" description=\"Basic tree with caret icon on the right\" />\n</template>\n"
        },
        {
          "path": "registry/default/components/tree/tree-04.html",
          "target": "components/ui/tree-04.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex h-full flex-col gap-2 *:first:grow\"><div><Tree class=\"relative before:absolute before:inset-0 before:-ms-1 before:bg-[repeating-linear-gradient(to_right,transparent_0,transparent_calc(var(--tree-indent)-1px),var(--border)_calc(var(--tree-indent)-1px),var(--border)_calc(var(--tree-indent)))]\" indent=\"${indent}\" tree=\"${tree}\">${tree.getItems().map((item) => {\n            return (\n              <TreeItem key={item.getId()} item={item}>\n                <TreeItemLabel className=\"before:bg-background relative before:absolute before:inset-x-0 before:-inset-y-0.5 before:-z-10\">\n                  <span className=\"-order-1 flex flex-1 items-center gap-2\">\n                    {item.isFolder() ? (\n                      item.isExpanded() ? (\n                        <FolderOpenIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                      ) : (\n                        <FolderIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                      )\n                    ) : (\n                      <FileIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    )}\n                    {item.getItemName()}\n                  </span>\n                </TreeItemLabel>\n              </TreeItem>\n            )\n          })}</Tree></div><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Basic tree with caret icon on the right ∙${' '}<a href=\"https://headless-tree.lukasbach.com\" class=\"hover:text-foreground underline\" target=\"_blank\" rel=\"noopener noreferrer\">API\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/tree/tree-04.wxml",
          "target": "components/ui/tree-04/tree-04.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex h-full flex-col gap-2 *:first:grow\"><view><tree class=\"relative before:absolute before:inset-0 before:-ms-1 before:bg-[repeating-linear-gradient(to_right,transparent_0,transparent_calc(var(--tree-indent)-1px),var(--border)_calc(var(--tree-indent)-1px),var(--border)_calc(var(--tree-indent)))]\" indent=\"{{indent}}\" tree=\"{{tree}}\">{{ tree.getItems().map((item) => {\n            return (\n              <TreeItem key={item.getId()} item={item}>\n                <TreeItemLabel className=\"before:bg-background relative before:absolute before:inset-x-0 before:-inset-y-0.5 before:-z-10\">\n                  <span className=\"-order-1 flex flex-1 items-center gap-2\">\n                    {item.isFolder() ? (\n                      item.isExpanded() ? (\n                        <FolderOpenIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                      ) : (\n                        <FolderIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                      )\n                    ) : (\n                      <FileIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    )}\n                    {item.getItemName()}\n                  </span>\n                </TreeItemLabel>\n              </TreeItem>\n            )\n          }) }}</tree></view><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Basic tree with caret icon on the right ∙{{ ' ' }}<a href=\"https://headless-tree.lukasbach.com\" class=\"hover:text-foreground underline\" target=\"_blank\" rel=\"noopener noreferrer\">API\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tree"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tree-04",
          "group": "tree",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tree-04",
              "path": "registry/default/components/tree/tree-04.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tree-04",
              "path": "registry/default/components/tree/tree-04.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tree-04",
              "path": "registry/default/components/tree/tree-04.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tree-04",
              "path": "registry/default/components/tree/tree-04.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@headless-tree/core",
              "@headless-tree/react",
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {},
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tree",
        "title": "Tree · Interactive State"
      },
      "dependencies": [
        "@headless-tree/core",
        "@headless-tree/react",
        "@timui/react"
      ],
      "categories": [
        "tree"
      ]
    },
    {
      "name": "tree-05",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/tree.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/tree/tree-05.tsx",
          "type": "registry:component",
          "target": "components/ui/tree-05.tsx",
          "content": "'use client'\n\nimport React, { useState } from 'react'\nimport {\n  createOnDropHandler,\n  dragAndDropFeature,\n  hotkeysCoreFeature,\n  keyboardDragAndDropFeature,\n  selectionFeature,\n  syncDataLoaderFeature,\n} from '@headless-tree/core'\nimport { AssistiveTreeDescription, useTree } from '@headless-tree/react'\nimport { Tree, TreeDragLine, TreeItem, TreeItemLabel } from '@timui/react'\nimport { FolderIcon, FolderOpenIcon } from 'lucide-react'\n\ninterface Item {\n  name: string\n  children?: string[]\n}\n\nconst initialItems: Record<string, Item> = {\n  company: {\n    name: 'Company',\n    children: ['engineering', 'marketing', 'operations'],\n  },\n  engineering: {\n    name: 'Engineering',\n    children: ['frontend', 'backend', 'platform-team'],\n  },\n  frontend: { name: 'Frontend', children: ['design-system', 'web-platform'] },\n  'design-system': {\n    name: 'Design System',\n    children: ['components', 'tokens', 'guidelines'],\n  },\n  components: { name: 'Components' },\n  tokens: { name: 'Tokens' },\n  guidelines: { name: 'Guidelines' },\n  'web-platform': { name: 'Web Platform' },\n  backend: { name: 'Backend', children: ['apis', 'infrastructure'] },\n  apis: { name: 'APIs' },\n  infrastructure: { name: 'Infrastructure' },\n  'platform-team': { name: 'Platform Team' },\n  marketing: { name: 'Marketing', children: ['content', 'seo'] },\n  content: { name: 'Content' },\n  seo: { name: 'SEO' },\n  operations: { name: 'Operations', children: ['hr', 'finance'] },\n  hr: { name: 'HR' },\n  finance: { name: 'Finance' },\n}\n\nconst indent = 20\n\nexport default function Component() {\n  const [items, setItems] = useState(initialItems)\n\n  const tree = useTree<Item>({\n    initialState: {\n      expandedItems: ['engineering', 'frontend', 'design-system'],\n      selectedItems: ['components'],\n    },\n    indent,\n    rootItemId: 'company',\n    getItemName: (item) => item.getItemData().name,\n    isItemFolder: (item) => (item.getItemData()?.children?.length ?? 0) > 0,\n    canReorder: true,\n    onDrop: createOnDropHandler((parentItem, newChildrenIds) => {\n      setItems((prevItems) => ({\n        ...prevItems,\n        [parentItem.getId()]: {\n          ...prevItems[parentItem.getId()],\n          children: newChildrenIds,\n        },\n      }))\n    }),\n    dataLoader: {\n      getItem: (itemId) => items[itemId],\n      getChildren: (itemId) => items[itemId].children ?? [],\n    },\n    features: [\n      syncDataLoaderFeature,\n      selectionFeature,\n      hotkeysCoreFeature,\n      dragAndDropFeature,\n      keyboardDragAndDropFeature,\n    ],\n  })\n\n  return (\n    <div className=\"flex h-full flex-col gap-2 *:first:grow\">\n      <Tree indent={indent} tree={tree}>\n        <AssistiveTreeDescription tree={tree} />\n        {tree.getItems().map((item) => {\n          return (\n            <TreeItem key={item.getId()} item={item}>\n              <TreeItemLabel>\n                <span className=\"flex items-center gap-2\">\n                  {item.isFolder() &&\n                    (item.isExpanded() ? (\n                      <FolderOpenIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    ) : (\n                      <FolderIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    ))}\n                  {item.getItemName()}\n                </span>\n              </TreeItemLabel>\n            </TreeItem>\n          )\n        })}\n        <TreeDragLine />\n      </Tree>\n\n      <p aria-live=\"polite\" role=\"region\" className=\"text-muted-foreground mt-2 text-xs\">\n        Tree with multi-select and drag and drop ∙{' '}\n        <a\n          href=\"https://headless-tree.lukasbach.com\"\n          className=\"hover:text-foreground underline\"\n          target=\"_blank\"\n          rel=\"noopener noreferrer\"\n        >\n          API\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tree/tree-05.vue",
          "target": "components/ui/tree-05.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport TreeDemoBase from './tree-demo-base.vue'\n</script>\n\n<template>\n  <TreeDemoBase variant=\"multi-select\" description=\"Tree with multi-select and drag and drop\" />\n</template>\n"
        },
        {
          "path": "registry/default/components/tree/tree-05.html",
          "target": "components/ui/tree-05.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex h-full flex-col gap-2 *:first:grow\"><Tree indent=\"${indent}\" tree=\"${tree}\"><AssistiveTreeDescription tree=\"${tree}\" />${tree.getItems().map((item) => {\n          return (\n            <TreeItem key={item.getId()} item={item}>\n              <TreeItemLabel>\n                <span className=\"flex items-center gap-2\">\n                  {item.isFolder() &&\n                    (item.isExpanded() ? (\n                      <FolderOpenIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    ) : (\n                      <FolderIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    ))}\n                  {item.getItemName()}\n                </span>\n              </TreeItemLabel>\n            </TreeItem>\n          )\n        })}<TreeDragLine /></Tree><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Tree with multi-select and drag and drop ∙${' '}<a href=\"https://headless-tree.lukasbach.com\" class=\"hover:text-foreground underline\" target=\"_blank\" rel=\"noopener noreferrer\">API\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/tree/tree-05.wxml",
          "target": "components/ui/tree-05/tree-05.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex h-full flex-col gap-2 *:first:grow\"><tree indent=\"{{indent}}\" tree=\"{{tree}}\"><assistivetreedescription tree=\"{{tree}}\" />{{ tree.getItems().map((item) => {\n          return (\n            <TreeItem key={item.getId()} item={item}>\n              <TreeItemLabel>\n                <span className=\"flex items-center gap-2\">\n                  {item.isFolder() &&\n                    (item.isExpanded() ? (\n                      <FolderOpenIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    ) : (\n                      <FolderIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    ))}\n                  {item.getItemName()}\n                </span>\n              </TreeItemLabel>\n            </TreeItem>\n          )\n        }) }}<treedragline /></tree><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Tree with multi-select and drag and drop ∙{{ ' ' }}<a href=\"https://headless-tree.lukasbach.com\" class=\"hover:text-foreground underline\" target=\"_blank\" rel=\"noopener noreferrer\">API\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tree"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tree-05",
          "group": "tree",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tree-05",
              "path": "registry/default/components/tree/tree-05.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tree-05",
              "path": "registry/default/components/tree/tree-05.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tree-05",
              "path": "registry/default/components/tree/tree-05.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tree-05",
              "path": "registry/default/components/tree/tree-05.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@headless-tree/core",
              "@headless-tree/react",
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {},
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tree",
        "title": "Tree · Interactive State"
      },
      "dependencies": [
        "@headless-tree/core",
        "@headless-tree/react",
        "@timui/react"
      ],
      "categories": [
        "tree"
      ]
    },
    {
      "name": "tree-06",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/tree.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/tree/tree-06.tsx",
          "type": "registry:component",
          "target": "components/ui/tree-06.tsx",
          "content": "'use client'\n\nimport React, { useState } from 'react'\nimport {\n  hotkeysCoreFeature,\n  renamingFeature,\n  selectionFeature,\n  syncDataLoaderFeature,\n} from '@headless-tree/core'\nimport { useTree } from '@headless-tree/react'\nimport { Input, Tree, TreeItem, TreeItemLabel } from '@timui/react'\nimport { FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react'\n\ninterface Item {\n  name: string\n  children?: string[]\n}\n\n// Initial data\nconst initialItems: Record<string, Item> = {\n  company: {\n    name: 'Company',\n    children: ['engineering', 'marketing', 'operations'],\n  },\n  engineering: {\n    name: 'Engineering',\n    children: ['frontend', 'backend', 'platform-team'],\n  },\n  frontend: { name: 'Frontend', children: ['design-system', 'web-platform'] },\n  'design-system': {\n    name: 'Design System',\n    children: ['components', 'tokens', 'guidelines'],\n  },\n  components: { name: 'Components' },\n  tokens: { name: 'Tokens' },\n  guidelines: { name: 'Guidelines' },\n  'web-platform': { name: 'Web Platform' },\n  backend: { name: 'Backend', children: ['apis', 'infrastructure'] },\n  apis: { name: 'APIs' },\n  infrastructure: { name: 'Infrastructure' },\n  'platform-team': { name: 'Platform Team' },\n  marketing: { name: 'Marketing', children: ['content', 'seo'] },\n  content: { name: 'Content' },\n  seo: { name: 'SEO' },\n  operations: { name: 'Operations', children: ['hr', 'finance'] },\n  hr: { name: 'HR' },\n  finance: { name: 'Finance' },\n}\n\nconst indent = 20\n\nexport default function Component() {\n  const [items, setItems] = useState(initialItems)\n\n  const tree = useTree<Item>({\n    initialState: {\n      expandedItems: ['engineering', 'frontend', 'design-system'],\n    },\n    indent,\n    rootItemId: 'company',\n    getItemName: (item) => item.getItemData().name,\n    isItemFolder: (item) => (item.getItemData()?.children?.length ?? 0) > 0,\n    dataLoader: {\n      getItem: (itemId) => items[itemId],\n      getChildren: (itemId) => items[itemId].children ?? [],\n    },\n    onRename: (item, newName) => {\n      // Update the item name in our state\n      const itemId = item.getId()\n      setItems((prevItems) => ({\n        ...prevItems,\n        [itemId]: {\n          ...prevItems[itemId],\n          name: newName,\n        },\n      }))\n    },\n    features: [syncDataLoaderFeature, hotkeysCoreFeature, renamingFeature, selectionFeature],\n  })\n\n  return (\n    <div className=\"flex h-full flex-col gap-2 *:first:grow\">\n      <Tree indent={indent} tree={tree}>\n        {tree.getItems().map((item) => {\n          return (\n            <TreeItem key={item.getId()} item={item}>\n              <TreeItemLabel>\n                <span className=\"flex items-center gap-2\">\n                  {item.isFolder() ? (\n                    item.isExpanded() ? (\n                      <FolderOpenIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    ) : (\n                      <FolderIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    )\n                  ) : (\n                    <FileIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                  )}\n                  {item.isRenaming() ? (\n                    <Input {...item.getRenameInputProps()} autoFocus className=\"-my-0.5 h-6 px-1\" />\n                  ) : (\n                    item.getItemName()\n                  )}\n                </span>\n              </TreeItemLabel>\n            </TreeItem>\n          )\n        })}\n      </Tree>\n\n      <p aria-live=\"polite\" role=\"region\" className=\"text-muted-foreground mt-2 text-xs\">\n        Tree with renaming (press F2 to rename) ∙{' '}\n        <a\n          href=\"https://headless-tree.lukasbach.com\"\n          className=\"hover:text-foreground underline\"\n          target=\"_blank\"\n          rel=\"noopener noreferrer\"\n        >\n          API\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tree/tree-06.vue",
          "target": "components/ui/tree-06.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport TreeDemoBase from './tree-demo-base.vue'\n</script>\n\n<template>\n  <TreeDemoBase variant=\"renaming\" description=\"Tree with renaming (press F2 to rename)\" />\n</template>\n"
        },
        {
          "path": "registry/default/components/tree/tree-06.html",
          "target": "components/ui/tree-06.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex h-full flex-col gap-2 *:first:grow\"><Tree indent=\"${indent}\" tree=\"${tree}\">${tree.getItems().map((item) => {\n          return (\n            <TreeItem key={item.getId()} item={item}>\n              <TreeItemLabel>\n                <span className=\"flex items-center gap-2\">\n                  {item.isFolder() ? (\n                    item.isExpanded() ? (\n                      <FolderOpenIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    ) : (\n                      <FolderIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    )\n                  ) : (\n                    <FileIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                  )}\n                  {item.isRenaming() ? (\n                    <Input {...item.getRenameInputProps()} autoFocus className=\"-my-0.5 h-6 px-1\" />\n                  ) : (\n                    item.getItemName()\n                  )}\n                </span>\n              </TreeItemLabel>\n            </TreeItem>\n          )\n        })}</Tree><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Tree with renaming (press F2 to rename) ∙${' '}<a href=\"https://headless-tree.lukasbach.com\" class=\"hover:text-foreground underline\" target=\"_blank\" rel=\"noopener noreferrer\">API\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/tree/tree-06.wxml",
          "target": "components/ui/tree-06/tree-06.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex h-full flex-col gap-2 *:first:grow\"><tree indent=\"{{indent}}\" tree=\"{{tree}}\">{{ tree.getItems().map((item) => {\n          return (\n            <TreeItem key={item.getId()} item={item}>\n              <TreeItemLabel>\n                <span className=\"flex items-center gap-2\">\n                  {item.isFolder() ? (\n                    item.isExpanded() ? (\n                      <FolderOpenIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    ) : (\n                      <FolderIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    )\n                  ) : (\n                    <FileIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                  )}\n                  {item.isRenaming() ? (\n                    <Input {...item.getRenameInputProps()} autoFocus className=\"-my-0.5 h-6 px-1\" />\n                  ) : (\n                    item.getItemName()\n                  )}\n                </span>\n              </TreeItemLabel>\n            </TreeItem>\n          )\n        }) }}</tree><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Tree with renaming (press F2 to rename) ∙{{ ' ' }}<a href=\"https://headless-tree.lukasbach.com\" class=\"hover:text-foreground underline\" target=\"_blank\" rel=\"noopener noreferrer\">API\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tree"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tree-06",
          "group": "tree",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tree-06",
              "path": "registry/default/components/tree/tree-06.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tree-06",
              "path": "registry/default/components/tree/tree-06.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tree-06",
              "path": "registry/default/components/tree/tree-06.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tree-06",
              "path": "registry/default/components/tree/tree-06.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@headless-tree/core",
              "@headless-tree/react",
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {},
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tree",
        "title": "Tree · Interactive State"
      },
      "dependencies": [
        "@headless-tree/core",
        "@headless-tree/react",
        "@timui/react"
      ],
      "categories": [
        "tree"
      ]
    },
    {
      "name": "tree-07",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/tree.json",
        "https://ui.timkit.cn/r/input.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/tree/tree-07.tsx",
          "type": "registry:component",
          "target": "components/ui/tree-07.tsx",
          "content": "'use client'\n\nimport React, { useState } from 'react'\nimport {\n  expandAllFeature,\n  hotkeysCoreFeature,\n  searchFeature,\n  selectionFeature,\n  syncDataLoaderFeature,\n  TreeState,\n} from '@headless-tree/core'\nimport { useTree } from '@headless-tree/react'\nimport { Input, Tree, TreeItem, TreeItemLabel } from '@timui/react'\nimport { FolderIcon, FolderOpenIcon, SearchIcon } from 'lucide-react'\n\ninterface Item {\n  name: string\n  children?: string[]\n}\n\nconst items: Record<string, Item> = {\n  company: {\n    name: 'Company',\n    children: ['engineering', 'marketing', 'operations'],\n  },\n  engineering: {\n    name: 'Engineering',\n    children: ['frontend', 'backend', 'platform-team'],\n  },\n  frontend: { name: 'Frontend', children: ['design-system', 'web-platform'] },\n  'design-system': {\n    name: 'Design System',\n    children: ['components', 'tokens', 'guidelines'],\n  },\n  components: { name: 'Components' },\n  tokens: { name: 'Tokens' },\n  guidelines: { name: 'Guidelines' },\n  'web-platform': { name: 'Web Platform' },\n  backend: { name: 'Backend', children: ['apis', 'infrastructure'] },\n  apis: { name: 'APIs' },\n  infrastructure: { name: 'Infrastructure' },\n  'platform-team': { name: 'Platform Team' },\n  marketing: { name: 'Marketing', children: ['content', 'seo'] },\n  content: { name: 'Content' },\n  seo: { name: 'SEO' },\n  operations: { name: 'Operations', children: ['hr', 'finance'] },\n  hr: { name: 'HR' },\n  finance: { name: 'Finance' },\n}\n\nconst indent = 20\n\nexport default function Component() {\n  // Store the initial expanded items to reset when search is cleared\n  const initialExpandedItems = ['engineering', 'frontend', 'design-system']\n  const [state, setState] = useState<Partial<TreeState<Item>>>({})\n\n  const tree = useTree<Item>({\n    state,\n    setState,\n    initialState: {\n      expandedItems: initialExpandedItems,\n    },\n    indent,\n    rootItemId: 'company',\n    getItemName: (item) => item.getItemData().name,\n    isItemFolder: (item) => (item.getItemData()?.children?.length ?? 0) > 0,\n    dataLoader: {\n      getItem: (itemId) => items[itemId],\n      getChildren: (itemId) => items[itemId].children ?? [],\n    },\n    features: [\n      syncDataLoaderFeature,\n      hotkeysCoreFeature,\n      selectionFeature,\n      searchFeature,\n      expandAllFeature,\n    ],\n  })\n\n  return (\n    <div className=\"flex h-full flex-col gap-2 *:nth-2:grow\">\n      <div className=\"relative\">\n        <Input\n          className=\"peer ps-9\"\n          {...{\n            ...tree.getSearchInputElementProps(),\n            onChange: (e) => {\n              // First call the original onChange handler from getSearchInputElementProps\n              const originalProps = tree.getSearchInputElementProps()\n              if (originalProps.onChange) {\n                originalProps.onChange(e)\n              }\n\n              // Then handle our custom logic\n              const value = e.target.value\n\n              if (value.length > 0) {\n                // If input has at least one character, expand all items\n                tree.expandAll()\n              } else {\n                // If input is cleared, reset to initial expanded state\n                setState((prevState) => {\n                  return {\n                    ...prevState,\n                    expandedItems: initialExpandedItems,\n                  }\n                })\n              }\n            },\n          }}\n          type=\"search\"\n          placeholder=\"Quick search...\"\n        />\n        <div className=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\">\n          <SearchIcon className=\"size-4\" aria-hidden=\"true\" />\n        </div>\n      </div>\n\n      <Tree indent={indent} tree={tree}>\n        {tree.getItems().map((item) => {\n          return (\n            <TreeItem key={item.getId()} item={item}>\n              <TreeItemLabel>\n                <span className=\"flex items-center gap-2\">\n                  {item.isFolder() &&\n                    (item.isExpanded() ? (\n                      <FolderOpenIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    ) : (\n                      <FolderIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    ))}\n                  {item.getItemName()}\n                </span>\n              </TreeItemLabel>\n            </TreeItem>\n          )\n        })}\n      </Tree>\n\n      <p aria-live=\"polite\" role=\"region\" className=\"text-muted-foreground mt-2 text-xs\">\n        Tree with search highlight ∙{' '}\n        <a\n          href=\"https://headless-tree.lukasbach.com\"\n          className=\"hover:text-foreground underline\"\n          target=\"_blank\"\n          rel=\"noopener noreferrer\"\n        >\n          API\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tree/tree-07.vue",
          "target": "components/ui/tree-07.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport TreeDemoBase from './tree-demo-base.vue'\n</script>\n\n<template>\n  <TreeDemoBase variant=\"search\" description=\"Tree with search highlight\" />\n</template>\n"
        },
        {
          "path": "registry/default/components/tree/tree-07.html",
          "target": "components/ui/tree-07.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex h-full flex-col gap-2 *:nth-2:grow\"><div class=\"relative\"><Input class=\"peer ps-9\" type=\"search\" placeholder=\"Quick search...\" /><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\"><SearchIcon class=\"size-4\" aria-hidden=\"true\" /></div></div><Tree indent=\"${indent}\" tree=\"${tree}\">${tree.getItems().map((item) => {\n          return (\n            <TreeItem key={item.getId()} item={item}>\n              <TreeItemLabel>\n                <span className=\"flex items-center gap-2\">\n                  {item.isFolder() &&\n                    (item.isExpanded() ? (\n                      <FolderOpenIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    ) : (\n                      <FolderIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    ))}\n                  {item.getItemName()}\n                </span>\n              </TreeItemLabel>\n            </TreeItem>\n          )\n        })}</Tree><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Tree with search highlight ∙${' '}<a href=\"https://headless-tree.lukasbach.com\" class=\"hover:text-foreground underline\" target=\"_blank\" rel=\"noopener noreferrer\">API\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/tree/tree-07.wxml",
          "target": "components/ui/tree-07/tree-07.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex h-full flex-col gap-2 *:nth-2:grow\"><view class=\"relative\"><input class=\"peer ps-9\" type=\"search\" placeholder=\"Quick search...\" /><view class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\"><searchicon class=\"size-4\" aria-hidden=\"true\" /></view></view><tree indent=\"{{indent}}\" tree=\"{{tree}}\">{{ tree.getItems().map((item) => {\n          return (\n            <TreeItem key={item.getId()} item={item}>\n              <TreeItemLabel>\n                <span className=\"flex items-center gap-2\">\n                  {item.isFolder() &&\n                    (item.isExpanded() ? (\n                      <FolderOpenIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    ) : (\n                      <FolderIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    ))}\n                  {item.getItemName()}\n                </span>\n              </TreeItemLabel>\n            </TreeItem>\n          )\n        }) }}</tree><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Tree with search highlight ∙{{ ' ' }}<a href=\"https://headless-tree.lukasbach.com\" class=\"hover:text-foreground underline\" target=\"_blank\" rel=\"noopener noreferrer\">API\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tree",
          "filter",
          "search"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tree-07",
          "group": "tree",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tree-07",
              "path": "registry/default/components/tree/tree-07.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tree-07",
              "path": "registry/default/components/tree/tree-07.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tree-07",
              "path": "registry/default/components/tree/tree-07.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tree-07",
              "path": "registry/default/components/tree/tree-07.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@headless-tree/core",
              "@headless-tree/react",
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {},
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tree",
        "title": "Tree · Disabled State"
      },
      "dependencies": [
        "@headless-tree/core",
        "@headless-tree/react",
        "@timui/react"
      ],
      "categories": [
        "tree"
      ]
    },
    {
      "name": "tree-08",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/tree.json",
        "https://ui.timkit.cn/r/input.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/tree/tree-08.tsx",
          "type": "registry:component",
          "target": "components/ui/tree-08.tsx",
          "content": "'use client'\n\nimport React, { useEffect, useRef, useState } from 'react'\nimport {\n  expandAllFeature,\n  hotkeysCoreFeature,\n  searchFeature,\n  selectionFeature,\n  syncDataLoaderFeature,\n  TreeState,\n} from '@headless-tree/core'\nimport { useTree } from '@headless-tree/react'\nimport { Input, Tree, TreeItem, TreeItemLabel } from '@timui/react'\nimport { CircleXIcon, FilterIcon, FolderIcon, FolderOpenIcon } from 'lucide-react'\n\ninterface Item {\n  name: string\n  children?: string[]\n}\n\nconst items: Record<string, Item> = {\n  company: {\n    name: 'Company',\n    children: ['engineering', 'marketing', 'operations'],\n  },\n  engineering: {\n    name: 'Engineering',\n    children: ['frontend', 'backend', 'platform-team'],\n  },\n  frontend: { name: 'Frontend', children: ['design-system', 'web-platform'] },\n  'design-system': {\n    name: 'Design System',\n    children: ['components', 'tokens', 'guidelines'],\n  },\n  components: { name: 'Components' },\n  tokens: { name: 'Tokens' },\n  guidelines: { name: 'Guidelines' },\n  'web-platform': { name: 'Web Platform' },\n  backend: { name: 'Backend', children: ['apis', 'infrastructure'] },\n  apis: { name: 'APIs' },\n  infrastructure: { name: 'Infrastructure' },\n  'platform-team': { name: 'Platform Team' },\n  marketing: { name: 'Marketing', children: ['content', 'seo'] },\n  content: { name: 'Content' },\n  seo: { name: 'SEO' },\n  operations: { name: 'Operations', children: ['hr', 'finance'] },\n  hr: { name: 'HR' },\n  finance: { name: 'Finance' },\n}\n\nconst indent = 20\n\nexport default function Component() {\n  // Store the initial expanded items to reset when search is cleared\n  const initialExpandedItems = ['engineering', 'frontend', 'design-system']\n  const [state, setState] = useState<Partial<TreeState<Item>>>({})\n  const [searchValue, setSearchValue] = useState('')\n  const inputRef = useRef<HTMLInputElement>(null)\n\n  const tree = useTree<Item>({\n    state,\n    setState,\n    initialState: {\n      expandedItems: initialExpandedItems,\n    },\n    indent,\n    rootItemId: 'company',\n    getItemName: (item) => item.getItemData().name,\n    isItemFolder: (item) => (item.getItemData()?.children?.length ?? 0) > 0,\n    dataLoader: {\n      getItem: (itemId) => items[itemId],\n      getChildren: (itemId) => items[itemId].children ?? [],\n    },\n    features: [\n      syncDataLoaderFeature,\n      hotkeysCoreFeature,\n      selectionFeature,\n      searchFeature,\n      expandAllFeature,\n    ],\n  })\n\n  // Handle clearing the search\n  const handleClearSearch = () => {\n    setSearchValue('')\n\n    // Manually trigger the tree's search onChange with an empty value\n    // to ensure item.isMatchingSearch() is correctly updated.\n    const searchProps = tree.getSearchInputElementProps()\n    if (searchProps.onChange) {\n      const syntheticEvent = {\n        target: { value: '' },\n      } as React.ChangeEvent<HTMLInputElement> // Cast to the expected event type\n      searchProps.onChange(syntheticEvent)\n    }\n\n    // Reset tree state to initial expanded items\n    setState((prevState) => ({\n      ...prevState,\n      expandedItems: initialExpandedItems,\n    }))\n\n    // Clear custom filtered items\n    setFilteredItems([])\n\n    if (inputRef.current) {\n      inputRef.current.focus()\n      // Also clear the internal search input\n      inputRef.current.value = ''\n    }\n  }\n\n  // Keep track of filtered items separately from the tree's internal search state\n  const [filteredItems, setFilteredItems] = useState<string[]>([])\n\n  // This function determines if an item should be visible based on our custom filtering\n  const shouldShowItem = (itemId: string) => {\n    if (!searchValue || searchValue.length === 0) return true\n    return filteredItems.includes(itemId)\n  }\n\n  // Update filtered items when search value changes\n  useEffect(() => {\n    if (!searchValue || searchValue.length === 0) {\n      setFilteredItems([])\n      return\n    }\n\n    // Get all items\n    const allItems = tree.getItems()\n\n    // First, find direct matches\n    const directMatches = allItems\n      .filter((item) => {\n        const name = item.getItemName().toLowerCase()\n        return name.includes(searchValue.toLowerCase())\n      })\n      .map((item) => item.getId())\n\n    // Then, find all parent IDs of matching items\n    const parentIds = new Set<string>()\n    directMatches.forEach((matchId) => {\n      let item = tree.getItems().find((i) => i.getId() === matchId)\n      while (item?.getParent && item.getParent()) {\n        const parent = item.getParent()\n        if (parent) {\n          parentIds.add(parent.getId())\n          item = parent\n        } else {\n          break\n        }\n      }\n    })\n\n    // Find all children of matching items\n    const childrenIds = new Set<string>()\n    directMatches.forEach((matchId) => {\n      const item = tree.getItems().find((i) => i.getId() === matchId)\n      if (item && item.isFolder()) {\n        // Get all descendants recursively\n        const getDescendants = (itemId: string) => {\n          const children = items[itemId]?.children || []\n          children.forEach((childId) => {\n            childrenIds.add(childId)\n            if (items[childId]?.children?.length) {\n              getDescendants(childId)\n            }\n          })\n        }\n\n        getDescendants(item.getId())\n      }\n    })\n\n    // Combine direct matches, parents, and children\n    setFilteredItems([...directMatches, ...Array.from(parentIds), ...Array.from(childrenIds)])\n\n    // Keep all folders expanded during search to ensure all matches are visible\n    // Store current expanded state first\n    const currentExpandedItems = tree.getState().expandedItems || []\n\n    // Get all folder IDs that need to be expanded to show matches\n    const folderIdsToExpand = allItems.filter((item) => item.isFolder()).map((item) => item.getId())\n\n    // Update expanded items in the tree state\n    setState((prevState) => ({\n      ...prevState,\n      expandedItems: [...new Set([...currentExpandedItems, ...folderIdsToExpand])],\n    }))\n  }, [searchValue, tree])\n\n  return (\n    <div className=\"flex h-full flex-col gap-2 *:nth-2:grow\">\n      <div className=\"relative\">\n        <Input\n          ref={inputRef}\n          className=\"peer ps-9\"\n          value={searchValue}\n          onChange={(e) => {\n            const value = e.target.value\n            setSearchValue(value)\n\n            // Apply the search to the tree's internal state as well\n            const searchProps = tree.getSearchInputElementProps()\n            if (searchProps.onChange) {\n              searchProps.onChange(e)\n            }\n\n            if (value.length > 0) {\n              // If input has at least one character, expand all items\n              tree.expandAll()\n            } else {\n              // If input is cleared, reset to initial expanded state\n              setState((prevState) => ({\n                ...prevState,\n                expandedItems: initialExpandedItems,\n              }))\n              setFilteredItems([])\n            }\n          }}\n          // Prevent the internal search from being cleared on blur\n          onBlur={(e) => {\n            // Prevent default blur behavior\n            e.preventDefault()\n\n            // Re-apply the search to ensure it stays active\n            if (searchValue && searchValue.length > 0) {\n              const searchProps = tree.getSearchInputElementProps()\n              if (searchProps.onChange) {\n                const syntheticEvent = {\n                  target: { value: searchValue },\n                } as React.ChangeEvent<HTMLInputElement>\n                searchProps.onChange(syntheticEvent)\n              }\n            }\n          }}\n          type=\"search\"\n          placeholder=\"Filter items...\"\n        />\n        <div className=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\">\n          <FilterIcon className=\"size-4\" aria-hidden=\"true\" />\n        </div>\n        {searchValue && (\n          <button\n            className=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\"\n            aria-label=\"Clear search\"\n            onClick={handleClearSearch}\n          >\n            <CircleXIcon className=\"size-4\" aria-hidden=\"true\" />\n          </button>\n        )}\n      </div>\n\n      <Tree indent={indent} tree={tree}>\n        {searchValue && filteredItems.length === 0 ? (\n          <p className=\"px-3 py-4 text-center text-sm\">No items found for \"{searchValue}\"</p>\n        ) : (\n          tree.getItems().map((item) => {\n            const isVisible = shouldShowItem(item.getId())\n\n            return (\n              <TreeItem\n                key={item.getId()}\n                item={item}\n                data-visible={isVisible || !searchValue}\n                className=\"data-[visible=false]:hidden\"\n              >\n                <TreeItemLabel>\n                  <span className=\"flex items-center gap-2\">\n                    {item.isFolder() &&\n                      (item.isExpanded() ? (\n                        <FolderOpenIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                      ) : (\n                        <FolderIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                      ))}\n                    {item.getItemName()}\n                  </span>\n                </TreeItemLabel>\n              </TreeItem>\n            )\n          })\n        )}\n      </Tree>\n\n      <p aria-live=\"polite\" role=\"region\" className=\"text-muted-foreground mt-2 text-xs\">\n        Tree with filtering ∙{' '}\n        <a\n          href=\"https://headless-tree.lukasbach.com\"\n          className=\"hover:text-foreground underline\"\n          target=\"_blank\"\n          rel=\"noopener noreferrer\"\n        >\n          API\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tree/tree-08.vue",
          "target": "components/ui/tree-08.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport TreeDemoBase from './tree-demo-base.vue'\n</script>\n\n<template>\n  <TreeDemoBase variant=\"filter\" description=\"Tree with filtering\" />\n</template>\n"
        },
        {
          "path": "registry/default/components/tree/tree-08.html",
          "target": "components/ui/tree-08.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex h-full flex-col gap-2 *:nth-2:grow\"><div class=\"relative\"><Input ref=\"${inputRef}\" class=\"peer ps-9\" value=\"${searchValue}\" onchange=\"${(e) => {\n            const value = e.target.value\n            setSearchValue(value)\n\n            // Apply the search to the tree's internal state as well\n            const searchProps = tree.getSearchInputElementProps()\n            if (searchProps.onChange) {\n              searchProps.onChange(e)\n            }\n\n            if (value.length > 0) {\n              // If input has at least one character, expand all items\n              tree.expandAll()\n            } else {\n              // If input is cleared, reset to initial expanded state\n              setState((prevState) => ({\n                ...prevState,\n                expandedItems: initialExpandedItems,\n              }))\n              setFilteredItems([])\n            }\n          }}\" onblur=\"${(e) => {\n            // Prevent default blur behavior\n            e.preventDefault()\n\n            // Re-apply the search to ensure it stays active\n            if (searchValue && searchValue.length > 0) {\n              const searchProps = tree.getSearchInputElementProps()\n              if (searchProps.onChange) {\n                const syntheticEvent = {\n                  target: { value: searchValue },\n                } as React.ChangeEvent<HTMLInputElement>\n                searchProps.onChange(syntheticEvent)\n              }\n            }\n          }}\" type=\"search\" placeholder=\"Filter items...\" /><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\"><FilterIcon class=\"size-4\" aria-hidden=\"true\" /></div><!-- if searchValue -->\n<button class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\" aria-label=\"Clear search\" on-click=\"${handleClearSearch}\"><CircleXIcon class=\"size-4\" aria-hidden=\"true\" /></button>\n<!-- endif --></div><Tree indent=\"${indent}\" tree=\"${tree}\"><!-- if searchValue && filteredItems.length === 0 -->\n<p class=\"px-3 py-4 text-center text-sm\">No items found for \"${searchValue}\"</p>\n<!-- else -->\n${tree.getItems().map((item) => {\n            const isVisible = shouldShowItem(item.getId())\n\n            return (\n              <TreeItem\n                key={item.getId()}\n                item={item}\n                data-visible={isVisible || !searchValue}\n                className=\"data-[visible=false]:hidden\"\n              >\n                <TreeItemLabel>\n                  <span className=\"flex items-center gap-2\">\n                    {item.isFolder() &&\n                      (item.isExpanded() ? (\n                        <FolderOpenIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                      ) : (\n                        <FolderIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                      ))}\n                    {item.getItemName()}\n                  </span>\n                </TreeItemLabel>\n              </TreeItem>\n            )\n          })}\n<!-- endif --></Tree><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Tree with filtering ∙${' '}<a href=\"https://headless-tree.lukasbach.com\" class=\"hover:text-foreground underline\" target=\"_blank\" rel=\"noopener noreferrer\">API\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/tree/tree-08.wxml",
          "target": "components/ui/tree-08/tree-08.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex h-full flex-col gap-2 *:nth-2:grow\"><view class=\"relative\"><input ref=\"{{inputRef}}\" class=\"peer ps-9\" value=\"{{searchValue}}\" onchange=\"{{(e) => {\n            const value = e.target.value\n            setSearchValue(value)\n\n            // Apply the search to the tree's internal state as well\n            const searchProps = tree.getSearchInputElementProps()\n            if (searchProps.onChange) {\n              searchProps.onChange(e)\n            }\n\n            if (value.length > 0) {\n              // If input has at least one character, expand all items\n              tree.expandAll()\n            } else {\n              // If input is cleared, reset to initial expanded state\n              setState((prevState) => ({\n                ...prevState,\n                expandedItems: initialExpandedItems,\n              }))\n              setFilteredItems([])\n            }\n          }}}\" onblur=\"{{(e) => {\n            // Prevent default blur behavior\n            e.preventDefault()\n\n            // Re-apply the search to ensure it stays active\n            if (searchValue && searchValue.length > 0) {\n              const searchProps = tree.getSearchInputElementProps()\n              if (searchProps.onChange) {\n                const syntheticEvent = {\n                  target: { value: searchValue },\n                } as React.ChangeEvent<HTMLInputElement>\n                searchProps.onChange(syntheticEvent)\n              }\n            }\n          }}}\" type=\"search\" placeholder=\"Filter items...\" /><view class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\"><filtericon class=\"size-4\" aria-hidden=\"true\" /></view><button wx:if=\"{{searchValue}}\" class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\" aria-label=\"Clear search\" bindtap=\"handleClearSearch\"><circlexicon class=\"size-4\" aria-hidden=\"true\" /></button></view><tree indent=\"{{indent}}\" tree=\"{{tree}}\"><block wx:if=\"{{searchValue && filteredItems.length === 0}}\">\n<text class=\"px-3 py-4 text-center text-sm\">No items found for \"{{ searchValue }}\"</text>\n</block>\n<block wx:else>\n{{ tree.getItems().map((item) => {\n            const isVisible = shouldShowItem(item.getId())\n\n            return (\n              <TreeItem\n                key={item.getId()}\n                item={item}\n                data-visible={isVisible || !searchValue}\n                className=\"data-[visible=false]:hidden\"\n              >\n                <TreeItemLabel>\n                  <span className=\"flex items-center gap-2\">\n                    {item.isFolder() &&\n                      (item.isExpanded() ? (\n                        <FolderOpenIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                      ) : (\n                        <FolderIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                      ))}\n                    {item.getItemName()}\n                  </span>\n                </TreeItemLabel>\n              </TreeItem>\n            )\n          }) }}\n</block></tree><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Tree with filtering ∙{{ ' ' }}<a href=\"https://headless-tree.lukasbach.com\" class=\"hover:text-foreground underline\" target=\"_blank\" rel=\"noopener noreferrer\">API\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tree",
          "filter",
          "search"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tree-08",
          "group": "tree",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tree-08",
              "path": "registry/default/components/tree/tree-08.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tree-08",
              "path": "registry/default/components/tree/tree-08.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tree-08",
              "path": "registry/default/components/tree/tree-08.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tree-08",
              "path": "registry/default/components/tree/tree-08.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@headless-tree/core",
              "@headless-tree/react",
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {},
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tree",
        "title": "Tree · Clear search"
      },
      "dependencies": [
        "@headless-tree/core",
        "@headless-tree/react",
        "@timui/react"
      ],
      "categories": [
        "tree"
      ]
    },
    {
      "name": "tree-09",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/tree.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/tree/tree-09.tsx",
          "type": "registry:component",
          "target": "components/ui/tree-09.tsx",
          "content": "'use client'\n\nimport React from 'react'\nimport {\n  FeatureImplementation,\n  hotkeysCoreFeature,\n  selectionFeature,\n  syncDataLoaderFeature,\n} from '@headless-tree/core'\nimport { useTree } from '@headless-tree/react'\nimport { Tree, TreeItem, TreeItemLabel } from '@timui/react'\nimport { FolderIcon, FolderOpenIcon } from 'lucide-react'\n\ninterface Item {\n  name: string\n  children?: string[]\n}\n\nconst items: Record<string, Item> = {\n  company: {\n    name: 'Company',\n    children: ['engineering', 'marketing', 'operations'],\n  },\n  engineering: {\n    name: 'Engineering',\n    children: ['frontend', 'backend', 'platform-team'],\n  },\n  frontend: { name: 'Frontend', children: ['design-system', 'web-platform'] },\n  'design-system': {\n    name: 'Design System',\n    children: ['components', 'tokens', 'guidelines'],\n  },\n  components: { name: 'Components' },\n  tokens: { name: 'Tokens' },\n  guidelines: { name: 'Guidelines' },\n  'web-platform': { name: 'Web Platform' },\n  backend: { name: 'Backend', children: ['apis', 'infrastructure'] },\n  apis: { name: 'APIs' },\n  infrastructure: { name: 'Infrastructure' },\n  'platform-team': { name: 'Platform Team' },\n  marketing: { name: 'Marketing', children: ['content', 'seo'] },\n  content: { name: 'Content' },\n  seo: { name: 'SEO' },\n  operations: { name: 'Operations', children: ['hr', 'finance'] },\n  hr: { name: 'HR' },\n  finance: { name: 'Finance' },\n}\n\nconst indent = 20\n\nconst doubleClickExpandFeature: FeatureImplementation = {\n  itemInstance: {\n    getProps: ({ tree, item, prev }) => ({\n      ...prev?.(),\n      onDoubleClick: (e: React.MouseEvent) => {\n        item.primaryAction()\n\n        if (!item.isFolder()) {\n          return\n        }\n\n        if (item.isExpanded()) {\n          item.collapse()\n        } else {\n          item.expand()\n        }\n      },\n      onClick: (e: React.MouseEvent) => {\n        if (e.shiftKey) {\n          item.selectUpTo(e.ctrlKey || e.metaKey)\n        } else if (e.ctrlKey || e.metaKey) {\n          item.toggleSelect()\n        } else {\n          tree.setSelectedItems([item.getItemMeta().itemId])\n        }\n\n        item.setFocused()\n      },\n    }),\n  },\n}\n\nexport default function Component() {\n  const tree = useTree<Item>({\n    initialState: {\n      expandedItems: ['engineering', 'frontend', 'design-system'],\n      selectedItems: ['components'],\n    },\n    indent,\n    rootItemId: 'company',\n    getItemName: (item) => item.getItemData().name,\n    isItemFolder: (item) => (item.getItemData()?.children?.length ?? 0) > 0,\n    dataLoader: {\n      getItem: (itemId) => items[itemId],\n      getChildren: (itemId) => items[itemId].children ?? [],\n    },\n    features: [\n      syncDataLoaderFeature,\n      selectionFeature,\n      hotkeysCoreFeature,\n      doubleClickExpandFeature,\n    ],\n  })\n\n  return (\n    <div className=\"flex h-full flex-col gap-2 *:first:grow\">\n      <Tree indent={indent} tree={tree}>\n        {tree.getItems().map((item) => {\n          return (\n            <TreeItem key={item.getId()} item={item}>\n              <TreeItemLabel>\n                <span className=\"flex items-center gap-2\">\n                  {item.isFolder() &&\n                    (item.isExpanded() ? (\n                      <FolderOpenIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    ) : (\n                      <FolderIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    ))}\n                  {item.getItemName()}\n                </span>\n              </TreeItemLabel>\n            </TreeItem>\n          )\n        })}\n      </Tree>\n\n      <p aria-live=\"polite\" role=\"region\" className=\"text-muted-foreground mt-2 text-xs\">\n        Tree with items expandable on double click ∙{' '}\n        <a\n          href=\"https://headless-tree.lukasbach.com\"\n          className=\"hover:text-foreground underline\"\n          target=\"_blank\"\n          rel=\"noopener noreferrer\"\n        >\n          API\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tree/tree-09.vue",
          "target": "components/ui/tree-09.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport TreeDemoBase from './tree-demo-base.vue'\n</script>\n\n<template>\n  <TreeDemoBase variant=\"double-click\" description=\"Tree with items expandable on double click\" />\n</template>\n"
        },
        {
          "path": "registry/default/components/tree/tree-09.html",
          "target": "components/ui/tree-09.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex h-full flex-col gap-2 *:first:grow\"><Tree indent=\"${indent}\" tree=\"${tree}\">${tree.getItems().map((item) => {\n          return (\n            <TreeItem key={item.getId()} item={item}>\n              <TreeItemLabel>\n                <span className=\"flex items-center gap-2\">\n                  {item.isFolder() &&\n                    (item.isExpanded() ? (\n                      <FolderOpenIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    ) : (\n                      <FolderIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    ))}\n                  {item.getItemName()}\n                </span>\n              </TreeItemLabel>\n            </TreeItem>\n          )\n        })}</Tree><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Tree with items expandable on double click ∙${' '}<a href=\"https://headless-tree.lukasbach.com\" class=\"hover:text-foreground underline\" target=\"_blank\" rel=\"noopener noreferrer\">API\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/tree/tree-09.wxml",
          "target": "components/ui/tree-09/tree-09.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex h-full flex-col gap-2 *:first:grow\"><tree indent=\"{{indent}}\" tree=\"{{tree}}\">{{ tree.getItems().map((item) => {\n          return (\n            <TreeItem key={item.getId()} item={item}>\n              <TreeItemLabel>\n                <span className=\"flex items-center gap-2\">\n                  {item.isFolder() &&\n                    (item.isExpanded() ? (\n                      <FolderOpenIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    ) : (\n                      <FolderIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    ))}\n                  {item.getItemName()}\n                </span>\n              </TreeItemLabel>\n            </TreeItem>\n          )\n        }) }}</tree><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Tree with items expandable on double click ∙{{ ' ' }}<a href=\"https://headless-tree.lukasbach.com\" class=\"hover:text-foreground underline\" target=\"_blank\" rel=\"noopener noreferrer\">API\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tree"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tree-09",
          "group": "tree",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tree-09",
              "path": "registry/default/components/tree/tree-09.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tree-09",
              "path": "registry/default/components/tree/tree-09.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tree-09",
              "path": "registry/default/components/tree/tree-09.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tree-09",
              "path": "registry/default/components/tree/tree-09.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@headless-tree/core",
              "@headless-tree/react",
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {},
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tree",
        "title": "Tree · Interactive State"
      },
      "dependencies": [
        "@headless-tree/core",
        "@headless-tree/react",
        "@timui/react"
      ],
      "categories": [
        "tree"
      ]
    },
    {
      "name": "tree-10",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/tree.json",
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/tree/tree-10.tsx",
          "type": "registry:component",
          "target": "components/ui/tree-10.tsx",
          "content": "'use client'\n\nimport React from 'react'\nimport {\n  expandAllFeature,\n  hotkeysCoreFeature,\n  selectionFeature,\n  syncDataLoaderFeature,\n} from '@headless-tree/core'\nimport { useTree } from '@headless-tree/react'\nimport { Button, Tree, TreeItem, TreeItemLabel } from '@timui/react'\nimport { FolderIcon, FolderOpenIcon, ListCollapseIcon, ListTreeIcon } from 'lucide-react'\n\ninterface Item {\n  name: string\n  children?: string[]\n}\n\nconst items: Record<string, Item> = {\n  company: {\n    name: 'Company',\n    children: ['engineering', 'marketing', 'operations'],\n  },\n  engineering: {\n    name: 'Engineering',\n    children: ['frontend', 'backend', 'platform-team'],\n  },\n  frontend: { name: 'Frontend', children: ['design-system', 'web-platform'] },\n  'design-system': {\n    name: 'Design System',\n    children: ['components', 'tokens', 'guidelines'],\n  },\n  components: { name: 'Components' },\n  tokens: { name: 'Tokens' },\n  guidelines: { name: 'Guidelines' },\n  'web-platform': { name: 'Web Platform' },\n  backend: { name: 'Backend', children: ['apis', 'infrastructure'] },\n  apis: { name: 'APIs' },\n  infrastructure: { name: 'Infrastructure' },\n  'platform-team': { name: 'Platform Team' },\n  marketing: { name: 'Marketing', children: ['content', 'seo'] },\n  content: { name: 'Content' },\n  seo: { name: 'SEO' },\n  operations: { name: 'Operations', children: ['hr', 'finance'] },\n  hr: { name: 'HR' },\n  finance: { name: 'Finance' },\n}\n\nconst indent = 20\n\nexport default function Component() {\n  const tree = useTree<Item>({\n    initialState: {\n      expandedItems: ['engineering', 'frontend', 'design-system'],\n      selectedItems: ['components'],\n    },\n    indent,\n    rootItemId: 'company',\n    getItemName: (item) => item.getItemData().name,\n    isItemFolder: (item) => (item.getItemData()?.children?.length ?? 0) > 0,\n    dataLoader: {\n      getItem: (itemId) => items[itemId],\n      getChildren: (itemId) => items[itemId].children ?? [],\n    },\n    features: [syncDataLoaderFeature, selectionFeature, hotkeysCoreFeature, expandAllFeature],\n  })\n\n  return (\n    <div className=\"flex h-full flex-col gap-2 *:nth-2:grow\">\n      <div className=\"flex items-center gap-2\">\n        <Button size=\"sm\" variant=\"outline\" onClick={() => tree.expandAll()}>\n          <ListTreeIcon className=\"-ms-1 opacity-60\" size={16} aria-hidden=\"true\" />\n          Expand all\n        </Button>\n        <Button size=\"sm\" variant=\"outline\" onClick={tree.collapseAll}>\n          <ListCollapseIcon className=\"-ms-1 opacity-60\" size={16} aria-hidden=\"true\" />\n          Collapse all\n        </Button>\n      </div>\n\n      <Tree indent={indent} tree={tree}>\n        {tree.getItems().map((item) => {\n          return (\n            <TreeItem key={item.getId()} item={item}>\n              <TreeItemLabel>\n                <span className=\"flex items-center gap-2\">\n                  {item.isFolder() &&\n                    (item.isExpanded() ? (\n                      <FolderOpenIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    ) : (\n                      <FolderIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    ))}\n                  {item.getItemName()}\n                  {item.isFolder() && (\n                    <span className=\"text-muted-foreground -ms-1\">\n                      {`(${item.getChildren().length})`}\n                    </span>\n                  )}\n                </span>\n              </TreeItemLabel>\n            </TreeItem>\n          )\n        })}\n      </Tree>\n\n      <p aria-live=\"polite\" role=\"region\" className=\"text-muted-foreground mt-2 text-xs\">\n        Tree with expand/collapse all buttons ∙{' '}\n        <a\n          href=\"https://headless-tree.lukasbach.com/\"\n          className=\"hover:text-foreground underline\"\n          target=\"_blank\"\n          rel=\"noopener noreferrer\"\n        >\n          API\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tree/tree-10.vue",
          "target": "components/ui/tree-10.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport TreeDemoBase from './tree-demo-base.vue'\n</script>\n\n<template>\n  <TreeDemoBase variant=\"expand-collapse\" description=\"Tree with expand/collapse all buttons\" />\n</template>\n"
        },
        {
          "path": "registry/default/components/tree/tree-10.html",
          "target": "components/ui/tree-10.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex h-full flex-col gap-2 *:nth-2:grow\"><div class=\"flex items-center gap-2\"><Button size=\"sm\" variant=\"outline\" on-click=\"${() => tree.expandAll()}\"><ListTreeIcon class=\"-ms-1 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Expand all\n        </Button><Button size=\"sm\" variant=\"outline\" on-click=\"${tree.collapseAll}\"><ListCollapseIcon class=\"-ms-1 opacity-60\" size=\"${16}\" aria-hidden=\"true\" />Collapse all\n        </Button></div><Tree indent=\"${indent}\" tree=\"${tree}\">${tree.getItems().map((item) => {\n          return (\n            <TreeItem key={item.getId()} item={item}>\n              <TreeItemLabel>\n                <span className=\"flex items-center gap-2\">\n                  {item.isFolder() &&\n                    (item.isExpanded() ? (\n                      <FolderOpenIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    ) : (\n                      <FolderIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    ))}\n                  {item.getItemName()}\n                  {item.isFolder() && (\n                    <span className=\"text-muted-foreground -ms-1\">\n                      {`(${item.getChildren().length})`}\n                    </span>\n                  )}\n                </span>\n              </TreeItemLabel>\n            </TreeItem>\n          )\n        })}</Tree><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Tree with expand/collapse all buttons ∙${' '}<a href=\"https://headless-tree.lukasbach.com/\" class=\"hover:text-foreground underline\" target=\"_blank\" rel=\"noopener noreferrer\">API\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/tree/tree-10.wxml",
          "target": "components/ui/tree-10/tree-10.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex h-full flex-col gap-2 *:nth-2:grow\"><view class=\"flex items-center gap-2\"><button size=\"sm\" variant=\"outline\" bindtap=\"tree.expandAll()\"><listtreeicon class=\"-ms-1 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Expand all\n        </button><button size=\"sm\" variant=\"outline\" bindtap=\"tree.collapseAll\"><listcollapseicon class=\"-ms-1 opacity-60\" size=\"{{16}}\" aria-hidden=\"true\" />Collapse all\n        </button></view><tree indent=\"{{indent}}\" tree=\"{{tree}}\">{{ tree.getItems().map((item) => {\n          return (\n            <TreeItem key={item.getId()} item={item}>\n              <TreeItemLabel>\n                <span className=\"flex items-center gap-2\">\n                  {item.isFolder() &&\n                    (item.isExpanded() ? (\n                      <FolderOpenIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    ) : (\n                      <FolderIcon className=\"text-muted-foreground pointer-events-none size-4\" />\n                    ))}\n                  {item.getItemName()}\n                  {item.isFolder() && (\n                    <span className=\"text-muted-foreground -ms-1\">\n                      {`(${item.getChildren().length})`}\n                    </span>\n                  )}\n                </span>\n              </TreeItemLabel>\n            </TreeItem>\n          )\n        }) }}</tree><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Tree with expand/collapse all buttons ∙{{ ' ' }}<a href=\"https://headless-tree.lukasbach.com/\" class=\"hover:text-foreground underline\" target=\"_blank\" rel=\"noopener noreferrer\">API\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tree",
          "button"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tree-10",
          "group": "tree",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tree-10",
              "path": "registry/default/components/tree/tree-10.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tree-10",
              "path": "registry/default/components/tree/tree-10.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tree-10",
              "path": "registry/default/components/tree/tree-10.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tree-10",
              "path": "registry/default/components/tree/tree-10.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@headless-tree/core",
              "@headless-tree/react",
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {},
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tree",
        "title": "Tree · Interactive State"
      },
      "dependencies": [
        "@headless-tree/core",
        "@headless-tree/react",
        "@timui/react"
      ],
      "categories": [
        "tree"
      ]
    },
    {
      "name": "tree-11",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/tree.json"
      ],
      "files": [
        {
          "path": "registry/default/components/tree/tree-11.tsx",
          "type": "registry:component",
          "target": "components/ui/tree-11.tsx",
          "content": "'use client'\n\nimport React, { useState } from 'react'\nimport {\n  createOnDropHandler,\n  dragAndDropFeature,\n  hotkeysCoreFeature,\n  keyboardDragAndDropFeature,\n  selectionFeature,\n  syncDataLoaderFeature,\n} from '@headless-tree/core'\nimport { AssistiveTreeDescription, useTree } from '@headless-tree/react'\nimport {\n  RiBracesLine,\n  RiCodeSSlashLine,\n  RiFileLine,\n  RiFileTextLine,\n  RiImageLine,\n  RiReactjsLine,\n} from '@remixicon/react'\nimport { Tree, TreeItem, TreeItemLabel } from '@timui/react'\n\ninterface Item {\n  name: string\n  children?: string[]\n  fileExtension?: string\n}\n\nconst initialItems: Record<string, Item> = {\n  app: {\n    name: 'app',\n    children: ['app/layout.tsx', 'app/page.tsx', 'app/(dashboard)', 'app/api'],\n  },\n  'app/layout.tsx': { name: 'layout.tsx', fileExtension: 'tsx' },\n  'app/page.tsx': { name: 'page.tsx', fileExtension: 'tsx' },\n  'app/(dashboard)': {\n    name: '(dashboard)',\n    children: ['app/(dashboard)/dashboard'],\n  },\n  'app/(dashboard)/dashboard': {\n    name: 'dashboard',\n    children: ['app/(dashboard)/dashboard/page.tsx'],\n  },\n  'app/(dashboard)/dashboard/page.tsx': {\n    name: 'page.tsx',\n    fileExtension: 'tsx',\n  },\n  'app/api': { name: 'api', children: ['app/api/hello'] },\n  'app/api/hello': { name: 'hello', children: ['app/api/hello/route.ts'] },\n  'app/api/hello/route.ts': { name: 'route.ts', fileExtension: 'ts' },\n  components: {\n    name: 'components',\n    children: ['components/button.tsx', 'components/card.tsx'],\n  },\n  'components/button.tsx': { name: 'button.tsx', fileExtension: 'tsx' },\n  'components/card.tsx': { name: 'card.tsx', fileExtension: 'tsx' },\n  lib: { name: 'lib', children: ['lib/utils.ts'] },\n  'lib/utils.ts': { name: 'utils.ts', fileExtension: 'ts' },\n  public: {\n    name: 'public',\n    children: ['public/favicon.ico', 'public/vercel.svg'],\n  },\n  'public/favicon.ico': { name: 'favicon.ico', fileExtension: 'ico' },\n  'public/vercel.svg': { name: 'vercel.svg', fileExtension: 'svg' },\n  'package.json': { name: 'package.json', fileExtension: 'json' },\n  'tailwind.config.ts': { name: 'tailwind.config.ts', fileExtension: 'ts' },\n  'tsconfig.json': { name: 'tsconfig.json', fileExtension: 'json' },\n  'next.config.mjs': { name: 'next.config.mjs', fileExtension: 'mjs' },\n  'README.md': { name: 'README.md', fileExtension: 'md' },\n  root: {\n    name: 'Project Root',\n    children: [\n      'app',\n      'components',\n      'lib',\n      'public',\n      'package.json',\n      'tailwind.config.ts',\n      'tsconfig.json',\n      'next.config.mjs',\n      'README.md',\n    ],\n  },\n}\n\n// Helper function to get icon based on file extension\nfunction getFileIcon(extension: string | undefined, className: string) {\n  switch (extension) {\n    case 'tsx':\n    case 'jsx':\n      return <RiReactjsLine className={className} />\n    case 'ts':\n    case 'js':\n    case 'mjs':\n      return <RiCodeSSlashLine className={className} />\n    case 'json':\n      return <RiBracesLine className={className} />\n    case 'svg':\n    case 'ico':\n    case 'png':\n    case 'jpg':\n      return <RiImageLine className={className} />\n    case 'md':\n      return <RiFileTextLine className={className} />\n    default:\n      return <RiFileLine className={className} />\n  }\n}\n\nconst indent = 20\n\nexport default function Component() {\n  const [items, setItems] = useState(initialItems)\n\n  const tree = useTree<Item>({\n    initialState: {\n      expandedItems: ['app', 'app/(dashboard)', 'app/(dashboard)/dashboard'],\n      selectedItems: ['components'],\n    },\n    indent,\n    rootItemId: 'root',\n    getItemName: (item) => item.getItemData()?.name ?? 'Unknown',\n    isItemFolder: (item) => (item.getItemData()?.children?.length ?? 0) > 0,\n    canReorder: false,\n    onDrop: createOnDropHandler((parentItem, newChildrenIds) => {\n      setItems((prevItems) => {\n        // Sort the children alphabetically\n        const sortedChildren = [...newChildrenIds].sort((a, b) => {\n          const itemA = prevItems[a]\n          const itemB = prevItems[b]\n\n          // First sort folders before files\n          const isAFolder = (itemA?.children?.length ?? 0) > 0\n          const isBFolder = (itemB?.children?.length ?? 0) > 0\n\n          if (isAFolder && !isBFolder) return -1\n          if (!isAFolder && isBFolder) return 1\n\n          // Then sort alphabetically by name\n          return (itemA?.name ?? '').localeCompare(itemB?.name ?? '')\n        })\n\n        return {\n          ...prevItems,\n          [parentItem.getId()]: {\n            ...prevItems[parentItem.getId()],\n            children: sortedChildren,\n          },\n        }\n      })\n    }),\n    dataLoader: {\n      getItem: (itemId) => items[itemId],\n      getChildren: (itemId) => items[itemId]?.children ?? [],\n    },\n    features: [\n      syncDataLoaderFeature,\n      selectionFeature,\n      hotkeysCoreFeature,\n      dragAndDropFeature,\n      keyboardDragAndDropFeature,\n    ],\n  })\n\n  return (\n    <div className=\"flex h-full flex-col gap-2 *:first:grow\">\n      <div>\n        <Tree\n          className=\"relative before:absolute before:inset-0 before:-ms-1 before:bg-[repeating-linear-gradient(to_right,transparent_0,transparent_calc(var(--tree-indent)-1px),var(--border)_calc(var(--tree-indent)-1px),var(--border)_calc(var(--tree-indent)))]\"\n          indent={indent}\n          tree={tree}\n        >\n          <AssistiveTreeDescription tree={tree} />\n          {tree.getItems().map((item) => {\n            return (\n              <TreeItem key={item.getId()} item={item} className=\"pb-0!\">\n                <TreeItemLabel className=\"rounded-none py-1\">\n                  <span className=\"flex items-center gap-2\">\n                    {!item.isFolder() &&\n                      getFileIcon(\n                        item.getItemData()?.fileExtension,\n                        'text-muted-foreground pointer-events-none size-4'\n                      )}\n                    {item.getItemName()}\n                  </span>\n                </TreeItemLabel>\n              </TreeItem>\n            )\n          })}\n        </Tree>\n      </div>\n\n      <p aria-live=\"polite\" role=\"region\" className=\"text-muted-foreground mt-2 text-xs\">\n        File editor with drag and drop ∙{' '}\n        <a\n          href=\"https://headless-tree.lukasbach.com\"\n          className=\"hover:text-foreground underline\"\n          target=\"_blank\"\n          rel=\"noopener noreferrer\"\n        >\n          API\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tree/tree-11.vue",
          "target": "components/ui/tree-11.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport TreeDemoBase from './tree-demo-base.vue'\n</script>\n\n<template>\n  <TreeDemoBase variant=\"file-editor\" description=\"File editor with drag and drop\" />\n</template>\n"
        },
        {
          "path": "registry/default/components/tree/tree-11.html",
          "target": "components/ui/tree-11.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex h-full flex-col gap-2 *:first:grow\"><div><Tree class=\"relative before:absolute before:inset-0 before:-ms-1 before:bg-[repeating-linear-gradient(to_right,transparent_0,transparent_calc(var(--tree-indent)-1px),var(--border)_calc(var(--tree-indent)-1px),var(--border)_calc(var(--tree-indent)))]\" indent=\"${indent}\" tree=\"${tree}\"><AssistiveTreeDescription tree=\"${tree}\" />${tree.getItems().map((item) => {\n            return (\n              <TreeItem key={item.getId()} item={item} className=\"pb-0!\">\n                <TreeItemLabel className=\"rounded-none py-1\">\n                  <span className=\"flex items-center gap-2\">\n                    {!item.isFolder() &&\n                      getFileIcon(\n                        item.getItemData()?.fileExtension,\n                        'text-muted-foreground pointer-events-none size-4'\n                      )}\n                    {item.getItemName()}\n                  </span>\n                </TreeItemLabel>\n              </TreeItem>\n            )\n          })}</Tree></div><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">File editor with drag and drop ∙${' '}<a href=\"https://headless-tree.lukasbach.com\" class=\"hover:text-foreground underline\" target=\"_blank\" rel=\"noopener noreferrer\">API\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/tree/tree-11.wxml",
          "target": "components/ui/tree-11/tree-11.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex h-full flex-col gap-2 *:first:grow\"><view><tree class=\"relative before:absolute before:inset-0 before:-ms-1 before:bg-[repeating-linear-gradient(to_right,transparent_0,transparent_calc(var(--tree-indent)-1px),var(--border)_calc(var(--tree-indent)-1px),var(--border)_calc(var(--tree-indent)))]\" indent=\"{{indent}}\" tree=\"{{tree}}\"><assistivetreedescription tree=\"{{tree}}\" />{{ tree.getItems().map((item) => {\n            return (\n              <TreeItem key={item.getId()} item={item} className=\"pb-0!\">\n                <TreeItemLabel className=\"rounded-none py-1\">\n                  <span className=\"flex items-center gap-2\">\n                    {!item.isFolder() &&\n                      getFileIcon(\n                        item.getItemData()?.fileExtension,\n                        'text-muted-foreground pointer-events-none size-4'\n                      )}\n                    {item.getItemName()}\n                  </span>\n                </TreeItemLabel>\n              </TreeItem>\n            )\n          }) }}</tree></view><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">File editor with drag and drop ∙{{ ' ' }}<a href=\"https://headless-tree.lukasbach.com\" class=\"hover:text-foreground underline\" target=\"_blank\" rel=\"noopener noreferrer\">API\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tree"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tree-11",
          "group": "tree",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tree-11",
              "path": "registry/default/components/tree/tree-11.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tree-11",
              "path": "registry/default/components/tree/tree-11.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tree-11",
              "path": "registry/default/components/tree/tree-11.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tree-11",
              "path": "registry/default/components/tree/tree-11.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@headless-tree/core",
              "@headless-tree/react",
              "@remixicon/react",
              "@timui/react"
            ]
          },
          "vue": {},
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tree",
        "title": "Tree · Interactive State"
      },
      "dependencies": [
        "@headless-tree/core",
        "@headless-tree/react",
        "@remixicon/react",
        "@timui/react"
      ],
      "categories": [
        "tree"
      ]
    },
    {
      "name": "tree-12",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/tree.json"
      ],
      "files": [
        {
          "path": "registry/default/components/tree/tree-12.tsx",
          "type": "registry:component",
          "target": "components/ui/tree-12.tsx",
          "content": "'use client'\n\nimport React from 'react'\nimport { hotkeysCoreFeature, syncDataLoaderFeature } from '@headless-tree/core'\nimport { useTree } from '@headless-tree/react'\nimport { Tree, TreeItem, TreeItemLabel } from '@timui/react'\n\ninterface Item {\n  name: string\n  href?: string\n  children?: string[]\n  current?: boolean\n}\n\nconst items: Record<string, Item> = {\n  main: { name: 'Documentation', children: ['guides', 'api', 'resources'] },\n  guides: { name: 'User Guides', children: ['getting-started', 'advanced'] },\n  'getting-started': {\n    name: 'Getting Started',\n    children: ['installation', 'setup'],\n  },\n  installation: { name: 'Installation', href: '#', current: true },\n  setup: { name: 'Configuration', href: '#' },\n  advanced: { name: 'Advanced Usage', href: '#' },\n  api: { name: 'API Reference', children: ['endpoints', 'models'] },\n  endpoints: { name: 'Endpoints', href: '#' },\n  models: { name: 'Data Models', href: '#' },\n  resources: { name: 'Resources', children: ['examples', 'faq'] },\n  examples: { name: 'Code Examples', href: '#' },\n  faq: { name: 'FAQ', href: '#' },\n}\n\nconst indent = 20\n\n// Find the path from root to the current item\nfunction findPathToCurrent(items: Record<string, Item>, rootId: string): string[] {\n  const path: string[] = []\n\n  function findPath(itemId: string): boolean {\n    const item = items[itemId]\n    if (!item) return false\n\n    // If this is the current item, we found the path\n    if (item.current) {\n      path.unshift(itemId)\n      return true\n    }\n\n    // If this item has children, search them\n    if (item.children?.length) {\n      for (const childId of item.children) {\n        if (findPath(childId)) {\n          // If we found the path in this branch, add this item to the path\n          path.unshift(itemId)\n          return true\n        }\n      }\n    }\n\n    return false\n  }\n\n  findPath(rootId)\n  return path\n}\n\n// Get all parent IDs that need to be expanded\nconst pathToCurrent = findPathToCurrent(items, 'main')\n// Remove the current item from the path if it's a leaf node\nconst expandedItems = pathToCurrent.filter((id) => items[id].children?.length)\n\nexport default function Component() {\n  const tree = useTree<Item>({\n    initialState: {\n      expandedItems,\n    },\n    indent,\n    rootItemId: 'main',\n    getItemName: (item) => item.getItemData().name,\n    isItemFolder: (item) => (item.getItemData()?.children?.length ?? 0) > 0,\n    dataLoader: {\n      getItem: (itemId) => items[itemId],\n      getChildren: (itemId) => items[itemId].children ?? [],\n    },\n    features: [syncDataLoaderFeature, hotkeysCoreFeature],\n  })\n\n  return (\n    <div className=\"flex h-full flex-col gap-2 *:first:grow\">\n      <Tree indent={indent} tree={tree}>\n        {tree.getItems().map((item) => {\n          return (\n            <TreeItem key={item.getId()} item={item} asChild={!!item.getItemData()?.href}>\n              {item.getItemData()?.href ? (\n                <a href={item.getItemData().href} data-current={item.getItemData().current}>\n                  <TreeItemLabel className=\"in-data-[current=true]:bg-accent in-data-[current=true]:text-accent-foreground\" />\n                </a>\n              ) : (\n                <TreeItemLabel />\n              )}\n            </TreeItem>\n          )\n        })}\n      </Tree>\n\n      <p aria-live=\"polite\" role=\"region\" className=\"text-muted-foreground mt-2 text-xs\">\n        Menu navigation tree ∙{' '}\n        <a\n          href=\"https://headless-tree.lukasbach.com\"\n          className=\"hover:text-foreground underline\"\n          target=\"_blank\"\n          rel=\"noopener noreferrer\"\n        >\n          API\n        </a>\n      </p>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/logo.tsx",
          "type": "registry:component",
          "target": "components/ui/logo.tsx",
          "content": "export default function Logo() {\n  return (\n    <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"33\" height=\"33\" fill=\"currentColor\">\n      <path d=\"M20.46 1.766 17.303.923l-2.66 9.896-2.403-8.934-3.157.843 2.595 9.652-6.464-6.442-2.311 2.304 7.09 7.066-8.83-2.358-.846 3.146 9.648 2.577a6.516 6.516 0 0 1-.169-1.478c0-3.598 2.927-6.515 6.537-6.515s6.537 2.917 6.537 6.515c0 .505-.057.997-.167 1.468l8.768 2.342.846-3.147-9.686-2.586 8.83-2.358-.845-3.147-9.686 2.587 6.464-6.442-2.311-2.304-6.992 6.969 2.369-8.81Z\" />\n      <path d=\"M22.695 18.7a6.495 6.495 0 0 1-1.626 2.986l6.352 6.33 2.31-2.303-7.036-7.013ZM21.005 21.752a6.538 6.538 0 0 1-2.922 1.722l2.312 8.596 3.157-.843-2.547-9.475ZM17.965 23.505a6.569 6.569 0 0 1-1.632.205 6.566 6.566 0 0 1-1.743-.235l-2.314 8.605 3.157.843 2.532-9.418ZM14.478 23.444a6.54 6.54 0 0 1-2.87-1.747l-6.367 6.346 2.31 2.303 6.927-6.902ZM11.555 21.64a6.492 6.492 0 0 1-1.585-2.948L1.173 21.04l.846 3.146 9.536-2.546Z\" />\n    </svg>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/tree/tree-12.vue",
          "target": "components/ui/tree-12.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport TreeDemoBase from './tree-demo-base.vue'\n</script>\n\n<template>\n  <TreeDemoBase variant=\"menu\" description=\"Menu navigation tree\" />\n</template>\n"
        },
        {
          "path": "registry/default/components/tree/tree-12.html",
          "target": "components/ui/tree-12.html",
          "type": "registry:component",
          "content": "<template>\n  <div class=\"flex h-full flex-col gap-2 *:first:grow\"><Tree indent=\"${indent}\" tree=\"${tree}\">${tree.getItems().map((item) => {\n          return (\n            <TreeItem key={item.getId()} item={item} asChild={!!item.getItemData()?.href}>\n              {item.getItemData()?.href ? (\n                <a href={item.getItemData().href} data-current={item.getItemData().current}>\n                  <TreeItemLabel className=\"in-data-[current=true]:bg-accent in-data-[current=true]:text-accent-foreground\" />\n                </a>\n              ) : (\n                <TreeItemLabel />\n              )}\n            </TreeItem>\n          )\n        })}</Tree><p aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Menu navigation tree ∙${' '}<a href=\"https://headless-tree.lukasbach.com\" class=\"hover:text-foreground underline\" target=\"_blank\" rel=\"noopener noreferrer\">API\n        </a></p></div>\n</template>"
        },
        {
          "path": "registry/default/components/tree/tree-12.wxml",
          "target": "components/ui/tree-12/tree-12.wxml",
          "type": "registry:component",
          "content": "<view>\n  <view class=\"flex h-full flex-col gap-2 *:first:grow\"><tree indent=\"{{indent}}\" tree=\"{{tree}}\">{{ tree.getItems().map((item) => {\n          return (\n            <TreeItem key={item.getId()} item={item} asChild={!!item.getItemData()?.href}>\n              {item.getItemData()?.href ? (\n                <a href={item.getItemData().href} data-current={item.getItemData().current}>\n                  <TreeItemLabel className=\"in-data-[current=true]:bg-accent in-data-[current=true]:text-accent-foreground\" />\n                </a>\n              ) : (\n                <TreeItemLabel />\n              )}\n            </TreeItem>\n          )\n        }) }}</tree><text aria-live=\"polite\" role=\"region\" class=\"text-muted-foreground mt-2 text-xs\">Menu navigation tree ∙{{ ' ' }}<a href=\"https://headless-tree.lukasbach.com\" class=\"hover:text-foreground underline\" target=\"_blank\" rel=\"noopener noreferrer\">API\n        </a></text></view>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "tree",
          "menu"
        ],
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "tree-12",
          "group": "tree",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "tree-12",
              "path": "registry/default/components/tree/tree-12.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "tree-12",
              "path": "registry/default/components/tree/tree-12.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "tree-12",
              "path": "registry/default/components/tree/tree-12.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "tree-12",
              "path": "registry/default/components/tree/tree-12.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@headless-tree/core",
              "@headless-tree/react",
              "@timui/react"
            ]
          },
          "vue": {},
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "tree",
        "title": "Tree · Interactive State"
      },
      "dependencies": [
        "@headless-tree/core",
        "@headless-tree/react",
        "@timui/react"
      ],
      "categories": [
        "tree"
      ]
    },
    {
      "name": "navbar-01",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/navigation-menu.json",
        "https://ui.timkit.cn/r/popover.json"
      ],
      "files": [
        {
          "path": "registry/default/components/navbar/navbar-01.tsx",
          "type": "registry:component",
          "target": "components/ui/navbar-01.tsx",
          "content": "import {\n  Button,\n  NavigationMenu,\n  NavigationMenuItem,\n  NavigationMenuLink,\n  NavigationMenuList,\n  Popover,\n  PopoverContent,\n  PopoverTrigger,\n} from '@timui/react'\n\nimport Logo from '@/registry/default/components/navbar-components/logo'\n\n// Navigation links array to be used in both desktop and mobile menus\nconst navigationLinks = [\n  { href: '#', label: 'Home', active: true },\n  { href: '#', label: 'Features' },\n  { href: '#', label: 'Pricing' },\n  { href: '#', label: 'About' },\n]\n\nexport default function Component() {\n  return (\n    <header className=\"border-b px-4 md:px-6\">\n      <div className=\"flex h-16 items-center justify-between gap-4\">\n        {/* Left side */}\n        <div className=\"flex items-center gap-2\">\n          {/* Mobile menu trigger */}\n          <Popover>\n            <PopoverTrigger asChild>\n              <Button className=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\">\n                <svg\n                  className=\"pointer-events-none\"\n                  width={16}\n                  height={16}\n                  viewBox=\"0 0 24 24\"\n                  fill=\"none\"\n                  stroke=\"currentColor\"\n                  strokeWidth=\"2\"\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  xmlns=\"http://www.w3.org/2000/svg\"\n                >\n                  <path\n                    d=\"M4 12L20 12\"\n                    className=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\"\n                  />\n                  <path\n                    d=\"M4 12H20\"\n                    className=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\"\n                  />\n                  <path\n                    d=\"M4 12H20\"\n                    className=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\"\n                  />\n                </svg>\n              </Button>\n            </PopoverTrigger>\n            <PopoverContent align=\"start\" className=\"w-36 p-1 md:hidden\">\n              <NavigationMenu className=\"max-w-none *:w-full\">\n                <NavigationMenuList className=\"flex-col items-start gap-0 md:gap-2\">\n                  {navigationLinks.map((link, index) => (\n                    <NavigationMenuItem key={index} className=\"w-full\">\n                      <NavigationMenuLink href={link.href} className=\"py-1.5\" active={link.active}>\n                        {link.label}\n                      </NavigationMenuLink>\n                    </NavigationMenuItem>\n                  ))}\n                </NavigationMenuList>\n              </NavigationMenu>\n            </PopoverContent>\n          </Popover>\n          {/* Main nav */}\n          <div className=\"flex items-center gap-6\">\n            <a href=\"#\" className=\"text-primary hover:text-primary/90\">\n              <Logo />\n            </a>\n            {/* Navigation menu */}\n            <NavigationMenu className=\"max-md:hidden\">\n              <NavigationMenuList className=\"gap-2\">\n                {navigationLinks.map((link, index) => (\n                  <NavigationMenuItem key={index}>\n                    <NavigationMenuLink\n                      active={link.active}\n                      href={link.href}\n                      className=\"text-muted-foreground hover:text-primary py-1.5 font-medium\"\n                    >\n                      {link.label}\n                    </NavigationMenuLink>\n                  </NavigationMenuItem>\n                ))}\n              </NavigationMenuList>\n            </NavigationMenu>\n          </div>\n        </div>\n        {/* Right side */}\n        <div className=\"flex items-center gap-2\">\n          <Button asChild variant=\"ghost\" size=\"sm\" className=\"text-sm\">\n            <a href=\"#\">Sign In</a>\n          </Button>\n          <Button asChild size=\"sm\" className=\"text-sm\">\n            <a href=\"#\">Get Started</a>\n          </Button>\n        </div>\n      </div>\n    </header>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-01.vue",
          "target": "components/ui/navbar-01.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\nimport { NavigationMenu, NavigationMenuItem, NavigationMenuLink, NavigationMenuList } from '@timui/vue';\nimport { Popover, PopoverContent, PopoverTrigger } from '@timui/vue';\nimport Logo from '@/registry/default/components/navbar-components/logo.vue';\n\nconst navigationLinks = [\n  { href: '#', label: 'Home', active: true },\n  { href: '#', label: 'Features' },\n  { href: '#', label: 'Pricing' },\n  { href: '#', label: 'About' },\n];\n\n</script>\n\n<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 items-center justify-between gap-4\"><div class=\"flex items-center gap-2\"><Popover><PopoverTrigger as-child><Button class=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\"><svg class=\"pointer-events-none\" :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></Button></PopoverTrigger><PopoverContent align=\"start\" class=\"w-36 p-1 md:hidden\"><NavigationMenu class=\"max-w-none *:w-full\"><NavigationMenuList class=\"flex-col items-start gap-0 md:gap-2\"><NavigationMenuItem v-for=\"(link, index) in navigationLinks\" :key=\"index\" class=\"w-full\"><NavigationMenuLink :href=\"link.href\" class=\"py-1.5\" :active=\"link.active\">{{ link.label }}</NavigationMenuLink></NavigationMenuItem></NavigationMenuList></NavigationMenu></PopoverContent></Popover><div class=\"flex items-center gap-6\"><a href=\"#\" class=\"text-primary hover:text-primary/90\"><Logo /></a><NavigationMenu class=\"max-md:hidden\"><NavigationMenuList class=\"gap-2\"><NavigationMenuItem v-for=\"(link, index) in navigationLinks\" :key=\"index\"><NavigationMenuLink :active=\"link.active\" :href=\"link.href\" class=\"text-muted-foreground hover:text-primary py-1.5 font-medium\">{{ link.label }}</NavigationMenuLink></NavigationMenuItem></NavigationMenuList></NavigationMenu></div></div><div class=\"flex items-center gap-2\"><Button as-child variant=\"ghost\" size=\"sm\" class=\"text-sm\"><a href=\"#\">Sign In</a></Button><Button as-child size=\"sm\" class=\"text-sm\"><a href=\"#\">Get Started</a></Button></div></div></header>\n</template>\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-01.html",
          "target": "components/ui/navbar-01.html",
          "type": "registry:component",
          "content": "<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 items-center justify-between gap-4\"><div class=\"flex items-center gap-2\"><Popover><PopoverTrigger aschild><Button class=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\"><svg class=\"pointer-events-none\" width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></Button></PopoverTrigger><PopoverContent align=\"start\" class=\"w-36 p-1 md:hidden\"><NavigationMenu class=\"max-w-none *:w-full\"><NavigationMenuList class=\"flex-col items-start gap-0 md:gap-2\"><!-- Loop navigationLinks -->\n<NavigationMenuItem key=\"${index}\" class=\"w-full\"><NavigationMenuLink href=\"${link.href}\" class=\"py-1.5\" active=\"${link.active}\">${link.label}</NavigationMenuLink></NavigationMenuItem>\n<!-- End Loop --></NavigationMenuList></NavigationMenu></PopoverContent></Popover><div class=\"flex items-center gap-6\"><a href=\"#\" class=\"text-primary hover:text-primary/90\"><Logo /></a><NavigationMenu class=\"max-md:hidden\"><NavigationMenuList class=\"gap-2\"><!-- Loop navigationLinks -->\n<NavigationMenuItem key=\"${index}\"><NavigationMenuLink active=\"${link.active}\" href=\"${link.href}\" class=\"text-muted-foreground hover:text-primary py-1.5 font-medium\">${link.label}</NavigationMenuLink></NavigationMenuItem>\n<!-- End Loop --></NavigationMenuList></NavigationMenu></div></div><div class=\"flex items-center gap-2\"><Button aschild variant=\"ghost\" size=\"sm\" class=\"text-sm\"><a href=\"#\">Sign In</a></Button><Button aschild size=\"sm\" class=\"text-sm\"><a href=\"#\">Get Started</a></Button></div></div></header>\n</template>"
        },
        {
          "path": "registry/default/components/navbar/navbar-01.wxml",
          "target": "components/ui/navbar-01/navbar-01.wxml",
          "type": "registry:component",
          "content": "<view>\n  <header class=\"border-b px-4 md:px-6\"><view class=\"flex h-16 items-center justify-between gap-4\"><view class=\"flex items-center gap-2\"><popover><popovertrigger aschild><button class=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\"><svg class=\"pointer-events-none\" width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></button></popovertrigger><popovercontent align=\"start\" class=\"w-36 p-1 md:hidden\"><navigationmenu class=\"max-w-none *:w-full\"><navigationmenulist class=\"flex-col items-start gap-0 md:gap-2\"><navigationmenuitem wx:for=\"{{navigationLinks}}\" wx:for-item=\"link\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{index}}\" class=\"w-full\"><navigationmenulink href=\"{{link.href}}\" class=\"py-1.5\" active=\"{{link.active}}\">{{ link.label }}</navigationmenulink></navigationmenuitem></navigationmenulist></navigationmenu></popovercontent></popover><view class=\"flex items-center gap-6\"><a href=\"#\" class=\"text-primary hover:text-primary/90\"><logo /></a><navigationmenu class=\"max-md:hidden\"><navigationmenulist class=\"gap-2\"><navigationmenuitem wx:for=\"{{navigationLinks}}\" wx:for-item=\"link\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{index}}\"><navigationmenulink active=\"{{link.active}}\" href=\"{{link.href}}\" class=\"text-muted-foreground hover:text-primary py-1.5 font-medium\">{{ link.label }}</navigationmenulink></navigationmenuitem></navigationmenulist></navigationmenu></view></view><view class=\"flex items-center gap-2\"><button aschild variant=\"ghost\" size=\"sm\" class=\"text-sm\"><a href=\"#\">Sign In</a></button><button aschild size=\"sm\" class=\"text-sm\"><a href=\"#\">Get Started</a></button></view></view></header>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "navbar, navigation"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "navbar-01",
          "group": "navbar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "navbar-01",
              "path": "registry/default/components/navbar/navbar-01.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "navbar-01",
              "path": "registry/default/components/navbar/navbar-01.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "navbar-01",
              "path": "registry/default/components/navbar/navbar-01.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "navbar-01",
              "path": "registry/default/components/navbar/navbar-01.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "navbars",
        "title": "Navbar · Interactive State"
      },
      "categories": [
        "navbars",
        "navbar",
        "tree"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "navbar-02",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/navigation-menu.json",
        "https://ui.timkit.cn/r/popover.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/navbar/navbar-02.tsx",
          "type": "registry:component",
          "target": "components/ui/navbar-02.tsx",
          "content": "import { cn } from '@timui/core'\nimport {\n  Button,\n  NavigationMenu,\n  NavigationMenuContent,\n  NavigationMenuItem,\n  NavigationMenuLink,\n  NavigationMenuList,\n  NavigationMenuTrigger,\n  Popover,\n  PopoverContent,\n  PopoverTrigger,\n} from '@timui/react'\nimport { BookOpenIcon, InfoIcon, LifeBuoyIcon } from 'lucide-react'\n\nimport Logo from '@/registry/default/components/navbar-components/logo'\n\n// Navigation links array to be used in both desktop and mobile menus\nconst navigationLinks = [\n  { href: '#', label: 'Home' },\n  {\n    label: 'Features',\n    submenu: true,\n    type: 'description',\n    items: [\n      {\n        href: '#',\n        label: 'Components',\n        description: 'Browse all components in the library.',\n      },\n      {\n        href: '#',\n        label: 'Documentation',\n        description: 'Learn how to use the library.',\n      },\n      {\n        href: '#',\n        label: 'Templates',\n        description: 'Pre-built layouts for common use cases.',\n      },\n    ],\n  },\n  {\n    label: 'Pricing',\n    submenu: true,\n    type: 'simple',\n    items: [\n      { href: '#', label: 'Product A' },\n      { href: '#', label: 'Product B' },\n      { href: '#', label: 'Product C' },\n      { href: '#', label: 'Product D' },\n    ],\n  },\n  {\n    label: 'About',\n    submenu: true,\n    type: 'icon',\n    items: [\n      { href: '#', label: 'Getting Started', icon: 'BookOpenIcon' },\n      { href: '#', label: 'Tutorials', icon: 'LifeBuoyIcon' },\n      { href: '#', label: 'About Us', icon: 'InfoIcon' },\n    ],\n  },\n]\n\nexport default function Component() {\n  return (\n    <header className=\"border-b px-4 md:px-6\">\n      <div className=\"flex h-16 items-center justify-between gap-4\">\n        {/* Left side */}\n        <div className=\"flex items-center gap-2\">\n          {/* Mobile menu trigger */}\n          <Popover>\n            <PopoverTrigger asChild>\n              <Button className=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\">\n                <svg\n                  className=\"pointer-events-none\"\n                  width={16}\n                  height={16}\n                  viewBox=\"0 0 24 24\"\n                  fill=\"none\"\n                  stroke=\"currentColor\"\n                  strokeWidth=\"2\"\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  xmlns=\"http://www.w3.org/2000/svg\"\n                >\n                  <path\n                    d=\"M4 12L20 12\"\n                    className=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\"\n                  />\n                  <path\n                    d=\"M4 12H20\"\n                    className=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\"\n                  />\n                  <path\n                    d=\"M4 12H20\"\n                    className=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\"\n                  />\n                </svg>\n              </Button>\n            </PopoverTrigger>\n            <PopoverContent align=\"start\" className=\"w-64 p-1 md:hidden\">\n              <NavigationMenu className=\"max-w-none *:w-full\">\n                <NavigationMenuList className=\"flex-col items-start gap-0 md:gap-2\">\n                  {navigationLinks.map((link, index) => (\n                    <NavigationMenuItem key={index} className=\"w-full\">\n                      {link.submenu ? (\n                        <>\n                          <div className=\"text-muted-foreground px-2 py-1.5 text-xs font-medium\">\n                            {link.label}\n                          </div>\n                          <ul>\n                            {link.items.map((item, itemIndex) => (\n                              <li key={itemIndex}>\n                                <NavigationMenuLink href={item.href} className=\"py-1.5\">\n                                  {item.label}\n                                </NavigationMenuLink>\n                              </li>\n                            ))}\n                          </ul>\n                        </>\n                      ) : (\n                        <NavigationMenuLink href={link.href} className=\"py-1.5\">\n                          {link.label}\n                        </NavigationMenuLink>\n                      )}\n                      {/* Add separator between different types of items */}\n                      {index < navigationLinks.length - 1 &&\n                        // Show separator if:\n                        // 1. One is submenu and one is simple link OR\n                        // 2. Both are submenus but with different types\n                        ((!link.submenu && navigationLinks[index + 1].submenu) ||\n                          (link.submenu && !navigationLinks[index + 1].submenu) ||\n                          (link.submenu &&\n                            navigationLinks[index + 1].submenu &&\n                            link.type !== navigationLinks[index + 1].type)) && (\n                          <div\n                            role=\"separator\"\n                            aria-orientation=\"horizontal\"\n                            className=\"bg-border -mx-1 my-1 h-px w-full\"\n                          />\n                        )}\n                    </NavigationMenuItem>\n                  ))}\n                </NavigationMenuList>\n              </NavigationMenu>\n            </PopoverContent>\n          </Popover>\n          {/* Main nav */}\n          <div className=\"flex items-center gap-6\">\n            <a href=\"#\" className=\"text-primary hover:text-primary/90\">\n              <Logo />\n            </a>\n            {/* Navigation menu */}\n            <NavigationMenu viewport={false} className=\"max-md:hidden\">\n              <NavigationMenuList className=\"gap-2\">\n                {navigationLinks.map((link, index) => (\n                  <NavigationMenuItem key={index}>\n                    {link.submenu ? (\n                      <>\n                        <NavigationMenuTrigger className=\"text-muted-foreground hover:text-primary bg-transparent px-2 py-1.5 font-medium *:[svg]:-me-0.5 *:[svg]:size-3.5\">\n                          {link.label}\n                        </NavigationMenuTrigger>\n                        <NavigationMenuContent className=\"data-[motion=from-end]:slide-in-from-right-16! data-[motion=from-start]:slide-in-from-left-16! data-[motion=to-end]:slide-out-to-right-16! data-[motion=to-start]:slide-out-to-left-16! z-50 p-1\">\n                          <ul className={cn(link.type === 'description' ? 'min-w-64' : 'min-w-48')}>\n                            {link.items.map((item, itemIndex) => (\n                              <li key={itemIndex}>\n                                <NavigationMenuLink\n                                  href={item.href}\n                                  className={cn(\n                                    'py-1.5',\n                                    link.type === 'icon' &&\n                                      'icon' in item &&\n                                      'inline-flex items-center gap-2'\n                                  )}\n                                >\n                                  {/* Display icon if present */}\n                                  {link.type === 'icon' && 'icon' in item && (\n                                    <>\n                                      {item.icon === 'BookOpenIcon' && (\n                                        <BookOpenIcon\n                                          size={16}\n                                          className=\"text-foreground opacity-60\"\n                                          aria-hidden=\"true\"\n                                        />\n                                      )}\n                                      {item.icon === 'LifeBuoyIcon' && (\n                                        <LifeBuoyIcon\n                                          size={16}\n                                          className=\"text-foreground opacity-60\"\n                                          aria-hidden=\"true\"\n                                        />\n                                      )}\n                                      {item.icon === 'InfoIcon' && (\n                                        <InfoIcon\n                                          size={16}\n                                          className=\"text-foreground opacity-60\"\n                                          aria-hidden=\"true\"\n                                        />\n                                      )}\n                                      <span className=\"leading-none\">{item.label}</span>\n                                    </>\n                                  )}\n\n                                  {/* Display label with description if present */}\n                                  {link.type === 'description' && 'description' in item ? (\n                                    <div className=\"space-y-1\">\n                                      <div className=\"font-medium\">{item.label}</div>\n                                      <p className=\"text-muted-foreground line-clamp-2 text-xs\">\n                                        {item.description}\n                                      </p>\n                                    </div>\n                                  ) : (\n                                    // Display simple label if not icon or description type\n                                    !link.type ||\n                                    (link.type !== 'icon' && link.type !== 'description' && (\n                                      <span>{item.label}</span>\n                                    ))\n                                  )}\n                                </NavigationMenuLink>\n                              </li>\n                            ))}\n                          </ul>\n                        </NavigationMenuContent>\n                      </>\n                    ) : (\n                      <NavigationMenuLink\n                        href={link.href}\n                        className=\"text-muted-foreground hover:text-primary py-1.5 font-medium\"\n                      >\n                        {link.label}\n                      </NavigationMenuLink>\n                    )}\n                  </NavigationMenuItem>\n                ))}\n              </NavigationMenuList>\n            </NavigationMenu>\n          </div>\n        </div>\n        {/* Right side */}\n        <div className=\"flex items-center gap-2\">\n          <Button asChild variant=\"ghost\" size=\"sm\" className=\"text-sm\">\n            <a href=\"#\">Sign In</a>\n          </Button>\n          <Button asChild size=\"sm\" className=\"text-sm\">\n            <a href=\"#\">Get Started</a>\n          </Button>\n        </div>\n      </div>\n    </header>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/logo.tsx",
          "type": "registry:component",
          "target": "components/ui/logo.tsx",
          "content": "export default function Logo() {\n  return (\n    <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"33\" height=\"33\" fill=\"currentColor\">\n      <path d=\"M20.46 1.766 17.303.923l-2.66 9.896-2.403-8.934-3.157.843 2.595 9.652-6.464-6.442-2.311 2.304 7.09 7.066-8.83-2.358-.846 3.146 9.648 2.577a6.516 6.516 0 0 1-.169-1.478c0-3.598 2.927-6.515 6.537-6.515s6.537 2.917 6.537 6.515c0 .505-.057.997-.167 1.468l8.768 2.342.846-3.147-9.686-2.586 8.83-2.358-.845-3.147-9.686 2.587 6.464-6.442-2.311-2.304-6.992 6.969 2.369-8.81Z\" />\n      <path d=\"M22.695 18.7a6.495 6.495 0 0 1-1.626 2.986l6.352 6.33 2.31-2.303-7.036-7.013ZM21.005 21.752a6.538 6.538 0 0 1-2.922 1.722l2.312 8.596 3.157-.843-2.547-9.475ZM17.965 23.505a6.569 6.569 0 0 1-1.632.205 6.566 6.566 0 0 1-1.743-.235l-2.314 8.605 3.157.843 2.532-9.418ZM14.478 23.444a6.54 6.54 0 0 1-2.87-1.747l-6.367 6.346 2.31 2.303 6.927-6.902ZM11.555 21.64a6.492 6.492 0 0 1-1.585-2.948L1.173 21.04l.846 3.146 9.536-2.546Z\" />\n    </svg>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-02.vue",
          "target": "components/ui/navbar-02.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn } from '@timui/core'\nimport { BookOpenIcon, InfoIcon, LifeBuoyIcon } from 'lucide-vue-next'\nimport { Button } from '@timui/vue'\nimport {\n  NavigationMenu,\n  NavigationMenuContent,\n  NavigationMenuItem,\n  NavigationMenuLink,\n  NavigationMenuList,\n  NavigationMenuTrigger,\n} from '@timui/vue'\nimport { Popover, PopoverContent, PopoverTrigger } from '@timui/vue'\nimport Logo from '@/registry/default/components/navbar-components/logo.vue'\n\ntype NavItem = {\n  href: string\n  label: string\n  description?: string\n  icon?: 'BookOpenIcon' | 'LifeBuoyIcon' | 'InfoIcon'\n}\n\ntype NavLink = {\n  href?: string\n  label: string\n  submenu?: boolean\n  type?: 'description' | 'simple' | 'icon'\n  items?: NavItem[]\n}\n\nconst navigationLinks: NavLink[] = [\n  { href: '#', label: 'Home' },\n  {\n    label: 'Features',\n    submenu: true,\n    type: 'description',\n    items: [\n      {\n        href: '#',\n        label: 'Components',\n        description: 'Browse all components in the library.',\n      },\n      {\n        href: '#',\n        label: 'Documentation',\n        description: 'Learn how to use the library.',\n      },\n      {\n        href: '#',\n        label: 'Templates',\n        description: 'Pre-built layouts for common use cases.',\n      },\n    ],\n  },\n  {\n    label: 'Pricing',\n    submenu: true,\n    type: 'simple',\n    items: [\n      { href: '#', label: 'Product A' },\n      { href: '#', label: 'Product B' },\n      { href: '#', label: 'Product C' },\n      { href: '#', label: 'Product D' },\n    ],\n  },\n  {\n    label: 'About',\n    submenu: true,\n    type: 'icon',\n    items: [\n      { href: '#', label: 'Getting Started', icon: 'BookOpenIcon' },\n      { href: '#', label: 'Tutorials', icon: 'LifeBuoyIcon' },\n      { href: '#', label: 'About Us', icon: 'InfoIcon' },\n    ],\n  },\n]\n\nconst iconMap = {\n  BookOpenIcon,\n  LifeBuoyIcon,\n  InfoIcon,\n} as const\n\nconst needsSeparator = (index: number) => {\n  if (index >= navigationLinks.length - 1) return false\n  const current = navigationLinks[index]\n  const next = navigationLinks[index + 1]\n  return (\n    (!!current.submenu && !next.submenu) ||\n    (!current.submenu && !!next.submenu) ||\n    (!!current.submenu && !!next.submenu && current.type !== next.type)\n  )\n}\n\nconst listMinWidth = (type?: NavLink['type']) => (type === 'description' ? 'min-w-64' : 'min-w-48')\n</script>\n\n<template>\n  <header class=\"border-b px-4 md:px-6\">\n    <div class=\"flex h-16 items-center justify-between gap-4\">\n      <div class=\"flex items-center gap-2\">\n        <Popover>\n          <PopoverTrigger as-child>\n            <Button class=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\">\n              <svg\n                class=\"pointer-events-none\"\n                :width=\"16\"\n                :height=\"16\"\n                viewBox=\"0 0 24 24\"\n                fill=\"none\"\n                stroke=\"currentColor\"\n                stroke-width=\"2\"\n                stroke-linecap=\"round\"\n                stroke-linejoin=\"round\"\n                xmlns=\"http://www.w3.org/2000/svg\"\n              >\n                <path\n                  d=\"M4 12L20 12\"\n                  class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\"\n                />\n                <path\n                  d=\"M4 12H20\"\n                  class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\"\n                />\n                <path\n                  d=\"M4 12H20\"\n                  class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\"\n                />\n              </svg>\n            </Button>\n          </PopoverTrigger>\n          <PopoverContent align=\"start\" class=\"w-64 p-1 md:hidden\">\n            <NavigationMenu class=\"max-w-none *:w-full\">\n              <NavigationMenuList class=\"flex-col items-start gap-0 md:gap-2\">\n                <NavigationMenuItem v-for=\"(link, index) in navigationLinks\" :key=\"index\" class=\"w-full\">\n                  <template v-if=\"link.submenu\">\n                    <div class=\"text-muted-foreground px-2 py-1.5 text-xs font-medium\">{{ link.label }}</div>\n                    <ul>\n                      <li v-for=\"(item, itemIndex) in link.items\" :key=\"itemIndex\">\n                        <NavigationMenuLink :href=\"item.href\" class=\"py-1.5\">{{ item.label }}</NavigationMenuLink>\n                      </li>\n                    </ul>\n                  </template>\n                  <NavigationMenuLink v-else :href=\"link.href\" class=\"py-1.5\">{{ link.label }}</NavigationMenuLink>\n\n                  <div\n                    v-if=\"needsSeparator(index)\"\n                    role=\"separator\"\n                    aria-orientation=\"horizontal\"\n                    class=\"bg-border -mx-1 my-1 h-px w-full\"\n                  />\n                </NavigationMenuItem>\n              </NavigationMenuList>\n            </NavigationMenu>\n          </PopoverContent>\n        </Popover>\n\n        <div class=\"flex items-center gap-6\">\n          <a href=\"#\" class=\"text-primary hover:text-primary/90\">\n            <Logo />\n          </a>\n\n          <NavigationMenu :viewport=\"false\" class=\"max-md:hidden\">\n            <NavigationMenuList class=\"gap-2\">\n              <NavigationMenuItem v-for=\"(link, index) in navigationLinks\" :key=\"index\">\n                <template v-if=\"link.submenu\">\n                  <NavigationMenuTrigger class=\"text-muted-foreground hover:text-primary bg-transparent px-2 py-1.5 font-medium *:[svg]:-me-0.5 *:[svg]:size-3.5\">\n                    {{ link.label }}\n                  </NavigationMenuTrigger>\n                  <NavigationMenuContent class=\"data-[motion=from-end]:slide-in-from-right-16! data-[motion=from-start]:slide-in-from-left-16! data-[motion=to-end]:slide-out-to-right-16! data-[motion=to-start]:slide-out-to-left-16! z-50 p-1\">\n                    <ul :class=\"cn(listMinWidth(link.type))\">\n                      <li v-for=\"(item, itemIndex) in link.items\" :key=\"itemIndex\">\n                        <NavigationMenuLink\n                          :href=\"item.href\"\n                          :class=\"cn('py-1.5', link.type === 'icon' && item.icon && 'inline-flex items-center gap-2')\"\n                        >\n                          <template v-if=\"link.type === 'icon' && item.icon\">\n                            <component\n                              :is=\"iconMap[item.icon]\"\n                              :size=\"16\"\n                              class=\"text-foreground opacity-60\"\n                              aria-hidden=\"true\"\n                            />\n                            <span class=\"leading-none\">{{ item.label }}</span>\n                          </template>\n\n                          <template v-else-if=\"link.type === 'description' && item.description\">\n                            <div class=\"space-y-1\">\n                              <div class=\"font-medium\">{{ item.label }}</div>\n                              <p class=\"text-muted-foreground line-clamp-2 text-xs\">{{ item.description }}</p>\n                            </div>\n                          </template>\n\n                          <template v-else>\n                            <span>{{ item.label }}</span>\n                          </template>\n                        </NavigationMenuLink>\n                      </li>\n                    </ul>\n                  </NavigationMenuContent>\n                </template>\n\n                <NavigationMenuLink\n                  v-else\n                  :href=\"link.href\"\n                  class=\"text-muted-foreground hover:text-primary py-1.5 font-medium\"\n                >\n                  {{ link.label }}\n                </NavigationMenuLink>\n              </NavigationMenuItem>\n            </NavigationMenuList>\n          </NavigationMenu>\n        </div>\n      </div>\n\n      <div class=\"flex items-center gap-2\">\n        <Button as-child variant=\"ghost\" size=\"sm\" class=\"text-sm\"><a href=\"#\">Sign In</a></Button>\n        <Button as-child size=\"sm\" class=\"text-sm\"><a href=\"#\">Get Started</a></Button>\n      </div>\n    </div>\n  </header>\n</template>\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-02.html",
          "target": "components/ui/navbar-02.html",
          "type": "registry:component",
          "content": "<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 items-center justify-between gap-4\"><div class=\"flex items-center gap-2\"><Popover><PopoverTrigger aschild><Button class=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\"><svg class=\"pointer-events-none\" width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></Button></PopoverTrigger><PopoverContent align=\"start\" class=\"w-64 p-1 md:hidden\"><NavigationMenu class=\"max-w-none *:w-full\"><NavigationMenuList class=\"flex-col items-start gap-0 md:gap-2\"><!-- Loop navigationLinks -->\n<NavigationMenuItem key=\"${index}\" class=\"w-full\"><!-- if link.submenu -->\n<div class=\"text-muted-foreground px-2 py-1.5 text-xs font-medium\">${link.label}</div><ul><!-- Loop link.items -->\n<li key=\"${itemIndex}\"><NavigationMenuLink href=\"${item.href}\" class=\"py-1.5\">${item.label}</NavigationMenuLink></li>\n<!-- End Loop --></ul>\n<!-- else -->\n<NavigationMenuLink href=\"${link.href}\" class=\"py-1.5\">${link.label}</NavigationMenuLink>\n<!-- endif --><!-- if index < navigationLinks.length - 1 &&\n                        // Show separator if:\n                        // 1. One is submenu and one is simple link OR\n                        // 2. Both are submenus but with different types\n                        ((!link.submenu && navigationLinks[index + 1].submenu) ||\n                          (link.submenu && !navigationLinks[index + 1].submenu) ||\n                          (link.submenu &&\n                            navigationLinks[index + 1].submenu &&\n                            link.type !== navigationLinks[index + 1].type)) -->\n<div role=\"separator\" aria-orientation=\"horizontal\" class=\"bg-border -mx-1 my-1 h-px w-full\" />\n<!-- endif --></NavigationMenuItem>\n<!-- End Loop --></NavigationMenuList></NavigationMenu></PopoverContent></Popover><div class=\"flex items-center gap-6\"><a href=\"#\" class=\"text-primary hover:text-primary/90\"><Logo /></a><NavigationMenu viewport=\"${false}\" class=\"max-md:hidden\"><NavigationMenuList class=\"gap-2\"><!-- Loop navigationLinks -->\n<NavigationMenuItem key=\"${index}\"><!-- if link.submenu -->\n<NavigationMenuTrigger class=\"text-muted-foreground hover:text-primary bg-transparent px-2 py-1.5 font-medium *:[svg]:-me-0.5 *:[svg]:size-3.5\">${link.label}</NavigationMenuTrigger><NavigationMenuContent class=\"data-[motion=from-end]:slide-in-from-right-16! data-[motion=from-start]:slide-in-from-left-16! data-[motion=to-end]:slide-out-to-right-16! data-[motion=to-start]:slide-out-to-left-16! z-50 p-1\"><ul class=\"${cn(link.type === 'description' ? 'min-w-64' : 'min-w-48')}\"><!-- Loop link.items -->\n<li key=\"${itemIndex}\"><NavigationMenuLink href=\"${item.href}\" class=\"py-1.5\"><!-- if link.type === 'icon' && 'icon' in item -->\n<div class=\"flex items-center gap-2\"><!-- if item.icon === 'BookOpenIcon' -->\n<BookOpenIcon size=\"${16}\" class=\"text-foreground opacity-60\" aria-hidden=\"true\" />\n<!-- endif --><!-- if item.icon === 'LifeBuoyIcon' -->\n<LifeBuoyIcon size=\"${16}\" class=\"text-foreground opacity-60\" aria-hidden=\"true\" />\n<!-- endif --><!-- if item.icon === 'InfoIcon' -->\n<InfoIcon size=\"${16}\" class=\"text-foreground opacity-60\" aria-hidden=\"true\" />\n<!-- endif --><span>${item.label}</span></div>\n<!-- endif --><!-- if link.type === 'description' && 'description' in item -->\n<div class=\"space-y-1\"><div class=\"font-medium\">${item.label}</div><p class=\"text-muted-foreground line-clamp-2 text-xs\">${item.description}</p></div>\n<!-- else -->\n${!link.type ||\n                                    (link.type !== 'icon' && link.type !== 'description' && (\n                                      <span>{item.label}</span>\n                                    ))}\n<!-- endif --></NavigationMenuLink></li>\n<!-- End Loop --></ul></NavigationMenuContent>\n<!-- else -->\n<NavigationMenuLink href=\"${link.href}\" class=\"text-muted-foreground hover:text-primary py-1.5 font-medium\">${link.label}</NavigationMenuLink>\n<!-- endif --></NavigationMenuItem>\n<!-- End Loop --></NavigationMenuList></NavigationMenu></div></div><div class=\"flex items-center gap-2\"><Button aschild variant=\"ghost\" size=\"sm\" class=\"text-sm\"><a href=\"#\">Sign In</a></Button><Button aschild size=\"sm\" class=\"text-sm\"><a href=\"#\">Get Started</a></Button></div></div></header>\n</template>"
        },
        {
          "path": "registry/default/components/navbar/navbar-02.wxml",
          "target": "components/ui/navbar-02/navbar-02.wxml",
          "type": "registry:component",
          "content": "<view>\n  <header class=\"border-b px-4 md:px-6\"><view class=\"flex h-16 items-center justify-between gap-4\"><view class=\"flex items-center gap-2\"><popover><popovertrigger aschild><button class=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\"><svg class=\"pointer-events-none\" width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></button></popovertrigger><popovercontent align=\"start\" class=\"w-64 p-1 md:hidden\"><navigationmenu class=\"max-w-none *:w-full\"><navigationmenulist class=\"flex-col items-start gap-0 md:gap-2\"><navigationmenuitem wx:for=\"{{navigationLinks}}\" wx:for-item=\"link\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{index}}\" class=\"w-full\"><block wx:if=\"{{link.submenu}}\">\n<view class=\"text-muted-foreground px-2 py-1.5 text-xs font-medium\">{{ link.label }}</view><ul><li wx:for=\"{{link.items}}\" wx:for-item=\"item\" wx:for-index=\"itemIndex\" wx:key=\"itemIndex\" key=\"{{itemIndex}}\"><navigationmenulink href=\"{{item.href}}\" class=\"py-1.5\">{{ item.label }}</navigationmenulink></li></ul>\n</block>\n<block wx:else>\n<navigationmenulink href=\"{{link.href}}\" class=\"py-1.5\">{{ link.label }}</navigationmenulink>\n</block><div wx:if=\"{{index < navigationLinks.length - 1 &&\n                        // Show separator if:\n                        // 1. One is submenu and one is simple link OR\n                        // 2. Both are submenus but with different types\n                        ((!link.submenu && navigationLinks[index + 1].submenu) ||\n                          (link.submenu && !navigationLinks[index + 1].submenu) ||\n                          (link.submenu &&\n                            navigationLinks[index + 1].submenu &&\n                            link.type !== navigationLinks[index + 1].type))}}\" role=\"separator\" aria-orientation=\"horizontal\" class=\"bg-border -mx-1 my-1 h-px w-full\" /></navigationmenuitem></navigationmenulist></navigationmenu></popovercontent></popover><view class=\"flex items-center gap-6\"><a href=\"#\" class=\"text-primary hover:text-primary/90\"><logo /></a><navigationmenu viewport=\"{{false}}\" class=\"max-md:hidden\"><navigationmenulist class=\"gap-2\"><navigationmenuitem wx:for=\"{{navigationLinks}}\" wx:for-item=\"link\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{index}}\"><block wx:if=\"{{link.submenu}}\">\n<navigationmenutrigger class=\"text-muted-foreground hover:text-primary bg-transparent px-2 py-1.5 font-medium *:[svg]:-me-0.5 *:[svg]:size-3.5\">{{ link.label }}</navigationmenutrigger><navigationmenucontent class=\"data-[motion=from-end]:slide-in-from-right-16! data-[motion=from-start]:slide-in-from-left-16! data-[motion=to-end]:slide-out-to-right-16! data-[motion=to-start]:slide-out-to-left-16! z-50 p-1\"><ul class=\"{{cn(link.type === 'description' ? 'min-w-64' : 'min-w-48')}}\"><li wx:for=\"{{link.items}}\" wx:for-item=\"item\" wx:for-index=\"itemIndex\" wx:key=\"itemIndex\" key=\"{{itemIndex}}\"><navigationmenulink href=\"{{item.href}}\" class=\"py-1.5\"><view wx:if=\"{{link.type === 'icon' && 'icon' in item}}\" class=\"flex items-center gap-2\"><bookopenicon wx:if=\"{{item.icon === 'BookOpenIcon'}}\" size=\"{{16}}\" class=\"text-foreground opacity-60\" aria-hidden=\"true\" /><lifebuoyicon wx:if=\"{{item.icon === 'LifeBuoyIcon'}}\" size=\"{{16}}\" class=\"text-foreground opacity-60\" aria-hidden=\"true\" /><infoicon wx:if=\"{{item.icon === 'InfoIcon'}}\" size=\"{{16}}\" class=\"text-foreground opacity-60\" aria-hidden=\"true\" /><text>{{ item.label }}</text></view><block wx:if=\"{{link.type === 'description' && 'description' in item}}\">\n<view class=\"space-y-1\"><view class=\"font-medium\">{{ item.label }}</view><text class=\"text-muted-foreground line-clamp-2 text-xs\">{{ item.description }}</text></view>\n</block>\n<block wx:else>\n{{ !link.type ||\n                                    (link.type !== 'icon' && link.type !== 'description' && (\n                                      <span>{item.label}</span>\n                                    )) }}\n</block></navigationmenulink></li></ul></navigationmenucontent>\n</block>\n<block wx:else>\n<navigationmenulink href=\"{{link.href}}\" class=\"text-muted-foreground hover:text-primary py-1.5 font-medium\">{{ link.label }}</navigationmenulink>\n</block></navigationmenuitem></navigationmenulist></navigationmenu></view></view><view class=\"flex items-center gap-2\"><button aschild variant=\"ghost\" size=\"sm\" class=\"text-sm\"><a href=\"#\">Sign In</a></button><button aschild size=\"sm\" class=\"text-sm\"><a href=\"#\">Get Started</a></button></view></view></header>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "navbar, navigation"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "navbar-02",
          "group": "navbar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "navbar-02",
              "path": "registry/default/components/navbar/navbar-02.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "navbar-02",
              "path": "registry/default/components/navbar/navbar-02.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "navbar-02",
              "path": "registry/default/components/navbar/navbar-02.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "navbar-02",
              "path": "registry/default/components/navbar/navbar-02.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "navbars",
        "title": "Navbar · Interactive State"
      },
      "categories": [
        "navbars",
        "navbar"
      ],
      "dependencies": [
        "@timui/core",
        "@timui/react"
      ]
    },
    {
      "name": "navbar-03",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/navigation-menu.json",
        "https://ui.timkit.cn/r/popover.json"
      ],
      "files": [
        {
          "path": "registry/default/components/navbar/navbar-03.tsx",
          "type": "registry:component",
          "target": "components/ui/navbar-03.tsx",
          "content": "import {\n  Button,\n  NavigationMenu,\n  NavigationMenuItem,\n  NavigationMenuLink,\n  NavigationMenuList,\n  Popover,\n  PopoverContent,\n  PopoverTrigger,\n} from '@timui/react'\n\nimport Logo from '@/registry/default/components/navbar-components/logo'\n\n// Navigation links array to be used in both desktop and mobile menus\nconst navigationLinks = [\n  { href: '#', label: 'Home', active: true },\n  { href: '#', label: 'Features' },\n  { href: '#', label: 'Pricing' },\n  { href: '#', label: 'About' },\n]\n\nexport default function Component() {\n  return (\n    <header className=\"border-b px-4 md:px-6\">\n      <div className=\"flex h-16 justify-between gap-4\">\n        {/* Left side */}\n        <div className=\"flex gap-2\">\n          <div className=\"flex items-center md:hidden\">\n            {/* Mobile menu trigger */}\n            <Popover>\n              <PopoverTrigger asChild>\n                <Button className=\"group size-8\" variant=\"ghost\" size=\"icon\">\n                  <svg\n                    className=\"pointer-events-none\"\n                    width={16}\n                    height={16}\n                    viewBox=\"0 0 24 24\"\n                    fill=\"none\"\n                    stroke=\"currentColor\"\n                    strokeWidth=\"2\"\n                    strokeLinecap=\"round\"\n                    strokeLinejoin=\"round\"\n                    xmlns=\"http://www.w3.org/2000/svg\"\n                  >\n                    <path\n                      d=\"M4 12L20 12\"\n                      className=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\"\n                    />\n                    <path\n                      d=\"M4 12H20\"\n                      className=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\"\n                    />\n                    <path\n                      d=\"M4 12H20\"\n                      className=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\"\n                    />\n                  </svg>\n                </Button>\n              </PopoverTrigger>\n              <PopoverContent align=\"start\" className=\"w-36 p-1 md:hidden\">\n                <NavigationMenu className=\"max-w-none *:w-full\">\n                  <NavigationMenuList className=\"flex-col items-start gap-0 md:gap-2\">\n                    {navigationLinks.map((link, index) => (\n                      <NavigationMenuItem key={index} className=\"w-full\">\n                        <NavigationMenuLink\n                          href={link.href}\n                          className=\"py-1.5\"\n                          active={link.active}\n                        >\n                          {link.label}\n                        </NavigationMenuLink>\n                      </NavigationMenuItem>\n                    ))}\n                  </NavigationMenuList>\n                </NavigationMenu>\n              </PopoverContent>\n            </Popover>\n          </div>\n          {/* Main nav */}\n          <div className=\"flex items-center gap-6\">\n            <a href=\"#\" className=\"text-primary hover:text-primary/90\">\n              <Logo />\n            </a>\n            {/* Navigation menu */}\n            <NavigationMenu className=\"h-full *:h-full max-md:hidden\">\n              <NavigationMenuList className=\"h-full gap-2\">\n                {navigationLinks.map((link, index) => (\n                  <NavigationMenuItem key={index} className=\"h-full\">\n                    <NavigationMenuLink\n                      active={link.active}\n                      href={link.href}\n                      className=\"text-muted-foreground hover:text-primary border-b-primary hover:border-b-primary data-[active]:border-b-primary h-full justify-center rounded-none border-y-2 border-transparent py-1.5 font-medium hover:bg-transparent data-[active]:bg-transparent!\"\n                    >\n                      {link.label}\n                    </NavigationMenuLink>\n                  </NavigationMenuItem>\n                ))}\n              </NavigationMenuList>\n            </NavigationMenu>\n          </div>\n        </div>\n        {/* Right side */}\n        <div className=\"flex items-center gap-2\">\n          <Button asChild variant=\"ghost\" size=\"sm\" className=\"text-sm\">\n            <a href=\"#\">Sign In</a>\n          </Button>\n          <Button asChild size=\"sm\" className=\"text-sm\">\n            <a href=\"#\">Get Started</a>\n          </Button>\n        </div>\n      </div>\n    </header>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/logo.tsx",
          "type": "registry:component",
          "target": "components/ui/logo.tsx",
          "content": "export default function Logo() {\n  return (\n    <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"33\" height=\"33\" fill=\"currentColor\">\n      <path d=\"M20.46 1.766 17.303.923l-2.66 9.896-2.403-8.934-3.157.843 2.595 9.652-6.464-6.442-2.311 2.304 7.09 7.066-8.83-2.358-.846 3.146 9.648 2.577a6.516 6.516 0 0 1-.169-1.478c0-3.598 2.927-6.515 6.537-6.515s6.537 2.917 6.537 6.515c0 .505-.057.997-.167 1.468l8.768 2.342.846-3.147-9.686-2.586 8.83-2.358-.845-3.147-9.686 2.587 6.464-6.442-2.311-2.304-6.992 6.969 2.369-8.81Z\" />\n      <path d=\"M22.695 18.7a6.495 6.495 0 0 1-1.626 2.986l6.352 6.33 2.31-2.303-7.036-7.013ZM21.005 21.752a6.538 6.538 0 0 1-2.922 1.722l2.312 8.596 3.157-.843-2.547-9.475ZM17.965 23.505a6.569 6.569 0 0 1-1.632.205 6.566 6.566 0 0 1-1.743-.235l-2.314 8.605 3.157.843 2.532-9.418ZM14.478 23.444a6.54 6.54 0 0 1-2.87-1.747l-6.367 6.346 2.31 2.303 6.927-6.902ZM11.555 21.64a6.492 6.492 0 0 1-1.585-2.948L1.173 21.04l.846 3.146 9.536-2.546Z\" />\n    </svg>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-03.vue",
          "target": "components/ui/navbar-03.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\nimport { NavigationMenu, NavigationMenuItem, NavigationMenuLink, NavigationMenuList } from '@timui/vue';\nimport { Popover, PopoverContent, PopoverTrigger } from '@timui/vue';\nimport Logo from '@/registry/default/components/navbar-components/logo.vue';\n\nconst navigationLinks = [\n  { href: '#', label: 'Home', active: true },\n  { href: '#', label: 'Features' },\n  { href: '#', label: 'Pricing' },\n  { href: '#', label: 'About' },\n];\n\n</script>\n\n<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 justify-between gap-4\"><div class=\"flex gap-2\"><div class=\"flex items-center md:hidden\"><Popover><PopoverTrigger as-child><Button class=\"group size-8\" variant=\"ghost\" size=\"icon\"><svg class=\"pointer-events-none\" :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></Button></PopoverTrigger><PopoverContent align=\"start\" class=\"w-36 p-1 md:hidden\"><NavigationMenu class=\"max-w-none *:w-full\"><NavigationMenuList class=\"flex-col items-start gap-0 md:gap-2\"><NavigationMenuItem v-for=\"(link, index) in navigationLinks\" :key=\"index\" class=\"w-full\"><NavigationMenuLink :href=\"link.href\" class=\"py-1.5\" :active=\"link.active\">{{ link.label }}</NavigationMenuLink></NavigationMenuItem></NavigationMenuList></NavigationMenu></PopoverContent></Popover></div><div class=\"flex items-center gap-6\"><a href=\"#\" class=\"text-primary hover:text-primary/90\"><Logo /></a><NavigationMenu class=\"h-full *:h-full max-md:hidden\"><NavigationMenuList class=\"h-full gap-2\"><NavigationMenuItem v-for=\"(link, index) in navigationLinks\" :key=\"index\" class=\"h-full\"><NavigationMenuLink :active=\"link.active\" :href=\"link.href\" class=\"text-muted-foreground hover:text-primary border-b-primary hover:border-b-primary data-[active]:border-b-primary h-full justify-center rounded-none border-y-2 border-transparent py-1.5 font-medium hover:bg-transparent data-[active]:bg-transparent!\">{{ link.label }}</NavigationMenuLink></NavigationMenuItem></NavigationMenuList></NavigationMenu></div></div><div class=\"flex items-center gap-2\"><Button as-child variant=\"ghost\" size=\"sm\" class=\"text-sm\"><a href=\"#\">Sign In</a></Button><Button as-child size=\"sm\" class=\"text-sm\"><a href=\"#\">Get Started</a></Button></div></div></header>\n</template>\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-03.html",
          "target": "components/ui/navbar-03.html",
          "type": "registry:component",
          "content": "<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 justify-between gap-4\"><div class=\"flex gap-2\"><div class=\"flex items-center md:hidden\"><Popover><PopoverTrigger aschild><Button class=\"group size-8\" variant=\"ghost\" size=\"icon\"><svg class=\"pointer-events-none\" width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></Button></PopoverTrigger><PopoverContent align=\"start\" class=\"w-36 p-1 md:hidden\"><NavigationMenu class=\"max-w-none *:w-full\"><NavigationMenuList class=\"flex-col items-start gap-0 md:gap-2\"><!-- Loop navigationLinks -->\n<NavigationMenuItem key=\"${index}\" class=\"w-full\"><NavigationMenuLink href=\"${link.href}\" class=\"py-1.5\" active=\"${link.active}\">${link.label}</NavigationMenuLink></NavigationMenuItem>\n<!-- End Loop --></NavigationMenuList></NavigationMenu></PopoverContent></Popover></div><div class=\"flex items-center gap-6\"><a href=\"#\" class=\"text-primary hover:text-primary/90\"><Logo /></a><NavigationMenu class=\"h-full *:h-full max-md:hidden\"><NavigationMenuList class=\"h-full gap-2\"><!-- Loop navigationLinks -->\n<NavigationMenuItem key=\"${index}\" class=\"h-full\"><NavigationMenuLink active=\"${link.active}\" href=\"${link.href}\" class=\"text-muted-foreground hover:text-primary border-b-primary hover:border-b-primary data-[active]:border-b-primary h-full justify-center rounded-none border-y-2 border-transparent py-1.5 font-medium hover:bg-transparent data-[active]:bg-transparent!\">${link.label}</NavigationMenuLink></NavigationMenuItem>\n<!-- End Loop --></NavigationMenuList></NavigationMenu></div></div><div class=\"flex items-center gap-2\"><Button aschild variant=\"ghost\" size=\"sm\" class=\"text-sm\"><a href=\"#\">Sign In</a></Button><Button aschild size=\"sm\" class=\"text-sm\"><a href=\"#\">Get Started</a></Button></div></div></header>\n</template>"
        },
        {
          "path": "registry/default/components/navbar/navbar-03.wxml",
          "target": "components/ui/navbar-03/navbar-03.wxml",
          "type": "registry:component",
          "content": "<view>\n  <header class=\"border-b px-4 md:px-6\"><view class=\"flex h-16 justify-between gap-4\"><view class=\"flex gap-2\"><view class=\"flex items-center md:hidden\"><popover><popovertrigger aschild><button class=\"group size-8\" variant=\"ghost\" size=\"icon\"><svg class=\"pointer-events-none\" width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></button></popovertrigger><popovercontent align=\"start\" class=\"w-36 p-1 md:hidden\"><navigationmenu class=\"max-w-none *:w-full\"><navigationmenulist class=\"flex-col items-start gap-0 md:gap-2\"><navigationmenuitem wx:for=\"{{navigationLinks}}\" wx:for-item=\"link\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{index}}\" class=\"w-full\"><navigationmenulink href=\"{{link.href}}\" class=\"py-1.5\" active=\"{{link.active}}\">{{ link.label }}</navigationmenulink></navigationmenuitem></navigationmenulist></navigationmenu></popovercontent></popover></view><view class=\"flex items-center gap-6\"><a href=\"#\" class=\"text-primary hover:text-primary/90\"><logo /></a><navigationmenu class=\"h-full *:h-full max-md:hidden\"><navigationmenulist class=\"h-full gap-2\"><navigationmenuitem wx:for=\"{{navigationLinks}}\" wx:for-item=\"link\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{index}}\" class=\"h-full\"><navigationmenulink active=\"{{link.active}}\" href=\"{{link.href}}\" class=\"text-muted-foreground hover:text-primary border-b-primary hover:border-b-primary data-[active]:border-b-primary h-full justify-center rounded-none border-y-2 border-transparent py-1.5 font-medium hover:bg-transparent data-[active]:bg-transparent!\">{{ link.label }}</navigationmenulink></navigationmenuitem></navigationmenulist></navigationmenu></view></view><view class=\"flex items-center gap-2\"><button aschild variant=\"ghost\" size=\"sm\" class=\"text-sm\"><a href=\"#\">Sign In</a></button><button aschild size=\"sm\" class=\"text-sm\"><a href=\"#\">Get Started</a></button></view></view></header>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "navbar, navigation"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "navbar-03",
          "group": "navbar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "navbar-03",
              "path": "registry/default/components/navbar/navbar-03.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "navbar-03",
              "path": "registry/default/components/navbar/navbar-03.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "navbar-03",
              "path": "registry/default/components/navbar/navbar-03.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "navbar-03",
              "path": "registry/default/components/navbar/navbar-03.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "navbars",
        "title": "Navbar · Interactive State"
      },
      "categories": [
        "navbars",
        "navbar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "navbar-04",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/navigation-menu.json",
        "https://ui.timkit.cn/r/popover.json",
        "https://ui.timkit.cn/r/input.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/navbar/navbar-04.tsx",
          "type": "registry:component",
          "target": "components/ui/navbar-04.tsx",
          "content": "import { useId } from 'react'\nimport {\n  Button,\n  Input,\n  NavigationMenu,\n  NavigationMenuItem,\n  NavigationMenuLink,\n  NavigationMenuList,\n  Popover,\n  PopoverContent,\n  PopoverTrigger,\n} from '@timui/react'\nimport { SearchIcon } from 'lucide-react'\n\nimport Logo from '@/registry/default/components/navbar-components/logo'\n\n// Navigation links array to be used in both desktop and mobile menus\nconst navigationLinks = [\n  { href: '#', label: 'Products' },\n  { href: '#', label: 'Categories' },\n  { href: '#', label: 'Deals' },\n]\n\nexport default function Component() {\n  const id = useId()\n\n  return (\n    <header className=\"border-b px-4 md:px-6\">\n      <div className=\"flex h-16 items-center justify-between gap-4\">\n        {/* Left side */}\n        <div className=\"flex flex-1 items-center gap-2\">\n          {/* Mobile menu trigger */}\n          <Popover>\n            <PopoverTrigger asChild>\n              <Button className=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\">\n                <svg\n                  className=\"pointer-events-none\"\n                  width={16}\n                  height={16}\n                  viewBox=\"0 0 24 24\"\n                  fill=\"none\"\n                  stroke=\"currentColor\"\n                  strokeWidth=\"2\"\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  xmlns=\"http://www.w3.org/2000/svg\"\n                >\n                  <path\n                    d=\"M4 12L20 12\"\n                    className=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\"\n                  />\n                  <path\n                    d=\"M4 12H20\"\n                    className=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\"\n                  />\n                  <path\n                    d=\"M4 12H20\"\n                    className=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\"\n                  />\n                </svg>\n              </Button>\n            </PopoverTrigger>\n            <PopoverContent align=\"start\" className=\"w-36 p-1 md:hidden\">\n              <NavigationMenu className=\"max-w-none *:w-full\">\n                <NavigationMenuList className=\"flex-col items-start gap-0 md:gap-2\">\n                  {navigationLinks.map((link, index) => (\n                    <NavigationMenuItem key={index} className=\"w-full\">\n                      <NavigationMenuLink href={link.href} className=\"py-1.5\">\n                        {link.label}\n                      </NavigationMenuLink>\n                    </NavigationMenuItem>\n                  ))}\n                  <NavigationMenuItem className=\"w-full\" role=\"presentation\" aria-hidden=\"true\">\n                    <div\n                      role=\"separator\"\n                      aria-orientation=\"horizontal\"\n                      className=\"bg-border -mx-1 my-1 h-px\"\n                    ></div>\n                  </NavigationMenuItem>\n                  <NavigationMenuItem className=\"w-full\">\n                    <NavigationMenuLink href=\"#\" className=\"py-1.5\">\n                      Sign In\n                    </NavigationMenuLink>\n                  </NavigationMenuItem>\n                  <NavigationMenuItem className=\"w-full\">\n                    <Button asChild size=\"sm\" className=\"mt-0.5 w-full text-left text-sm\">\n                      <span className=\"flex items-baseline gap-2\">\n                        Cart\n                        <span className=\"text-primary-foreground/60 text-xs\">2</span>\n                      </span>\n                    </Button>\n                  </NavigationMenuItem>\n                </NavigationMenuList>\n              </NavigationMenu>\n            </PopoverContent>\n          </Popover>\n          {/* Main nav */}\n          <div className=\"flex flex-1 items-center gap-6 max-md:justify-between\">\n            <a href=\"#\" className=\"text-primary hover:text-primary/90\">\n              <Logo />\n            </a>\n            {/* Navigation menu */}\n            <NavigationMenu className=\"max-md:hidden\">\n              <NavigationMenuList className=\"gap-2\">\n                {navigationLinks.map((link, index) => (\n                  <NavigationMenuItem key={index}>\n                    <NavigationMenuLink\n                      href={link.href}\n                      className=\"text-muted-foreground hover:text-primary py-1.5 font-medium\"\n                    >\n                      {link.label}\n                    </NavigationMenuLink>\n                  </NavigationMenuItem>\n                ))}\n              </NavigationMenuList>\n            </NavigationMenu>\n            {/* Search form */}\n            <div className=\"relative\">\n              <Input id={id} className=\"peer h-8 ps-8 pe-2\" placeholder=\"Search...\" type=\"search\" />\n              <div className=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-2 peer-disabled:opacity-50\">\n                <SearchIcon size={16} />\n              </div>\n            </div>\n          </div>\n        </div>\n        {/* Right side */}\n        <div className=\"flex items-center gap-2 max-md:hidden\">\n          <Button asChild variant=\"ghost\" size=\"sm\" className=\"text-sm\">\n            <a href=\"#\">Sign In</a>\n          </Button>\n          <Button asChild size=\"sm\" className=\"text-sm\">\n            <a href=\"#\">\n              <span className=\"flex items-baseline gap-2\">\n                Cart\n                <span className=\"text-primary-foreground/60 text-xs\">2</span>\n              </span>\n            </a>\n          </Button>\n        </div>\n      </div>\n    </header>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/logo.tsx",
          "type": "registry:component",
          "target": "components/ui/logo.tsx",
          "content": "export default function Logo() {\n  return (\n    <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"33\" height=\"33\" fill=\"currentColor\">\n      <path d=\"M20.46 1.766 17.303.923l-2.66 9.896-2.403-8.934-3.157.843 2.595 9.652-6.464-6.442-2.311 2.304 7.09 7.066-8.83-2.358-.846 3.146 9.648 2.577a6.516 6.516 0 0 1-.169-1.478c0-3.598 2.927-6.515 6.537-6.515s6.537 2.917 6.537 6.515c0 .505-.057.997-.167 1.468l8.768 2.342.846-3.147-9.686-2.586 8.83-2.358-.845-3.147-9.686 2.587 6.464-6.442-2.311-2.304-6.992 6.969 2.369-8.81Z\" />\n      <path d=\"M22.695 18.7a6.495 6.495 0 0 1-1.626 2.986l6.352 6.33 2.31-2.303-7.036-7.013ZM21.005 21.752a6.538 6.538 0 0 1-2.922 1.722l2.312 8.596 3.157-.843-2.547-9.475ZM17.965 23.505a6.569 6.569 0 0 1-1.632.205 6.566 6.566 0 0 1-1.743-.235l-2.314 8.605 3.157.843 2.532-9.418ZM14.478 23.444a6.54 6.54 0 0 1-2.87-1.747l-6.367 6.346 2.31 2.303 6.927-6.902ZM11.555 21.64a6.492 6.492 0 0 1-1.585-2.948L1.173 21.04l.846 3.146 9.536-2.546Z\" />\n    </svg>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-04.vue",
          "target": "components/ui/navbar-04.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { SearchIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { Input } from '@timui/vue';\nimport { NavigationMenu, NavigationMenuItem, NavigationMenuLink, NavigationMenuList } from '@timui/vue';\nimport { Popover, PopoverContent, PopoverTrigger } from '@timui/vue';\nimport Logo from '@/registry/default/components/navbar-components/logo.vue';\n\nconst navigationLinks = [\n  { href: '#', label: 'Products' },\n  { href: '#', label: 'Categories' },\n  { href: '#', label: 'Deals' },\n];\n\n\nconst id = 'navbar-04';\n\n</script>\n\n<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 items-center justify-between gap-4\"><div class=\"flex flex-1 items-center gap-2\"><Popover><PopoverTrigger as-child><Button class=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\"><svg class=\"pointer-events-none\" :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></Button></PopoverTrigger><PopoverContent align=\"start\" class=\"w-36 p-1 md:hidden\"><NavigationMenu class=\"max-w-none *:w-full\"><NavigationMenuList class=\"flex-col items-start gap-0 md:gap-2\"><NavigationMenuItem v-for=\"(link, index) in navigationLinks\" :key=\"index\" class=\"w-full\"><NavigationMenuLink :href=\"link.href\" class=\"py-1.5\">{{ link.label }}</NavigationMenuLink></NavigationMenuItem><NavigationMenuItem class=\"w-full\" role=\"presentation\" aria-hidden=\"true\"><div role=\"separator\" aria-orientation=\"horizontal\" class=\"bg-border -mx-1 my-1 h-px\"></div></NavigationMenuItem><NavigationMenuItem class=\"w-full\"><NavigationMenuLink href=\"#\" class=\"py-1.5\">Sign In\n                    </NavigationMenuLink></NavigationMenuItem><NavigationMenuItem class=\"w-full\"><Button as-child size=\"sm\" class=\"mt-0.5 w-full text-left text-sm\"><span class=\"flex items-baseline gap-2\">Cart\n                        <span class=\"text-primary-foreground/60 text-xs\">2</span></span></Button></NavigationMenuItem></NavigationMenuList></NavigationMenu></PopoverContent></Popover><div class=\"flex flex-1 items-center gap-6 max-md:justify-between\"><a href=\"#\" class=\"text-primary hover:text-primary/90\"><Logo /></a><NavigationMenu class=\"max-md:hidden\"><NavigationMenuList class=\"gap-2\"><NavigationMenuItem v-for=\"(link, index) in navigationLinks\" :key=\"index\"><NavigationMenuLink :href=\"link.href\" class=\"text-muted-foreground hover:text-primary py-1.5 font-medium\">{{ link.label }}</NavigationMenuLink></NavigationMenuItem></NavigationMenuList></NavigationMenu><div class=\"relative\"><Input :id=\"id\" class=\"peer h-8 ps-8 pe-2\" placeholder=\"Search...\" type=\"search\" /><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-2 peer-disabled:opacity-50\"><SearchIcon :size=\"16\" /></div></div></div></div><div class=\"flex items-center gap-2 max-md:hidden\"><Button as-child variant=\"ghost\" size=\"sm\" class=\"text-sm\"><a href=\"#\">Sign In</a></Button><Button as-child size=\"sm\" class=\"text-sm\"><a href=\"#\"><span class=\"flex items-baseline gap-2\">Cart\n                <span class=\"text-primary-foreground/60 text-xs\">2</span></span></a></Button></div></div></header>\n</template>\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-04.html",
          "target": "components/ui/navbar-04.html",
          "type": "registry:component",
          "content": "<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 items-center justify-between gap-4\"><div class=\"flex flex-1 items-center gap-2\"><Popover><PopoverTrigger aschild><Button class=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\"><svg class=\"pointer-events-none\" width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></Button></PopoverTrigger><PopoverContent align=\"start\" class=\"w-36 p-1 md:hidden\"><NavigationMenu class=\"max-w-none *:w-full\"><NavigationMenuList class=\"flex-col items-start gap-0 md:gap-2\"><!-- Loop navigationLinks -->\n<NavigationMenuItem key=\"${index}\" class=\"w-full\"><NavigationMenuLink href=\"${link.href}\" class=\"py-1.5\">${link.label}</NavigationMenuLink></NavigationMenuItem>\n<!-- End Loop --><NavigationMenuItem class=\"w-full\" role=\"presentation\" aria-hidden=\"true\"><div role=\"separator\" aria-orientation=\"horizontal\" class=\"bg-border -mx-1 my-1 h-px\"></div></NavigationMenuItem><NavigationMenuItem class=\"w-full\"><NavigationMenuLink href=\"#\" class=\"py-1.5\">Sign In\n                    </NavigationMenuLink></NavigationMenuItem><NavigationMenuItem class=\"w-full\"><Button aschild size=\"sm\" class=\"mt-0.5 w-full text-left text-sm\"><span class=\"flex items-baseline gap-2\">Cart\n                        <span class=\"text-primary-foreground/60 text-xs\">2</span></span></Button></NavigationMenuItem></NavigationMenuList></NavigationMenu></PopoverContent></Popover><div class=\"flex flex-1 items-center gap-6 max-md:justify-between\"><a href=\"#\" class=\"text-primary hover:text-primary/90\"><Logo /></a><NavigationMenu class=\"max-md:hidden\"><NavigationMenuList class=\"gap-2\"><!-- Loop navigationLinks -->\n<NavigationMenuItem key=\"${index}\"><NavigationMenuLink href=\"${link.href}\" class=\"text-muted-foreground hover:text-primary py-1.5 font-medium\">${link.label}</NavigationMenuLink></NavigationMenuItem>\n<!-- End Loop --></NavigationMenuList></NavigationMenu><div class=\"relative\"><Input id=\"${id}\" class=\"peer h-8 ps-8 pe-2\" placeholder=\"Search...\" type=\"search\" /><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-2 peer-disabled:opacity-50\"><SearchIcon size=\"${16}\" /></div></div></div></div><div class=\"flex items-center gap-2 max-md:hidden\"><Button aschild variant=\"ghost\" size=\"sm\" class=\"text-sm\"><a href=\"#\">Sign In</a></Button><Button aschild size=\"sm\" class=\"text-sm\"><a href=\"#\"><span class=\"flex items-baseline gap-2\">Cart\n                <span class=\"text-primary-foreground/60 text-xs\">2</span></span></a></Button></div></div></header>\n</template>"
        },
        {
          "path": "registry/default/components/navbar/navbar-04.wxml",
          "target": "components/ui/navbar-04/navbar-04.wxml",
          "type": "registry:component",
          "content": "<view>\n  <header class=\"border-b px-4 md:px-6\"><view class=\"flex h-16 items-center justify-between gap-4\"><view class=\"flex flex-1 items-center gap-2\"><popover><popovertrigger aschild><button class=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\"><svg class=\"pointer-events-none\" width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></button></popovertrigger><popovercontent align=\"start\" class=\"w-36 p-1 md:hidden\"><navigationmenu class=\"max-w-none *:w-full\"><navigationmenulist class=\"flex-col items-start gap-0 md:gap-2\"><navigationmenuitem wx:for=\"{{navigationLinks}}\" wx:for-item=\"link\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{index}}\" class=\"w-full\"><navigationmenulink href=\"{{link.href}}\" class=\"py-1.5\">{{ link.label }}</navigationmenulink></navigationmenuitem><navigationmenuitem class=\"w-full\" role=\"presentation\" aria-hidden=\"true\"><view role=\"separator\" aria-orientation=\"horizontal\" class=\"bg-border -mx-1 my-1 h-px\"></view></navigationmenuitem><navigationmenuitem class=\"w-full\"><navigationmenulink href=\"#\" class=\"py-1.5\">Sign In\n                    </navigationmenulink></navigationmenuitem><navigationmenuitem class=\"w-full\"><button aschild size=\"sm\" class=\"mt-0.5 w-full text-left text-sm\"><text class=\"flex items-baseline gap-2\">Cart\n                        <text class=\"text-primary-foreground/60 text-xs\">2</text></text></button></navigationmenuitem></navigationmenulist></navigationmenu></popovercontent></popover><view class=\"flex flex-1 items-center gap-6 max-md:justify-between\"><a href=\"#\" class=\"text-primary hover:text-primary/90\"><logo /></a><navigationmenu class=\"max-md:hidden\"><navigationmenulist class=\"gap-2\"><navigationmenuitem wx:for=\"{{navigationLinks}}\" wx:for-item=\"link\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{index}}\"><navigationmenulink href=\"{{link.href}}\" class=\"text-muted-foreground hover:text-primary py-1.5 font-medium\">{{ link.label }}</navigationmenulink></navigationmenuitem></navigationmenulist></navigationmenu><view class=\"relative\"><input id=\"{{id}}\" class=\"peer h-8 ps-8 pe-2\" placeholder=\"Search...\" type=\"search\" /><view class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-2 peer-disabled:opacity-50\"><searchicon size=\"{{16}}\" /></view></view></view></view><view class=\"flex items-center gap-2 max-md:hidden\"><button aschild variant=\"ghost\" size=\"sm\" class=\"text-sm\"><a href=\"#\">Sign In</a></button><button aschild size=\"sm\" class=\"text-sm\"><a href=\"#\"><text class=\"flex items-baseline gap-2\">Cart\n                <text class=\"text-primary-foreground/60 text-xs\">2</text></text></a></button></view></view></header>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "navbar, navigation"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "navbar-04",
          "group": "navbar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "navbar-04",
              "path": "registry/default/components/navbar/navbar-04.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "navbar-04",
              "path": "registry/default/components/navbar/navbar-04.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "navbar-04",
              "path": "registry/default/components/navbar/navbar-04.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "navbar-04",
              "path": "registry/default/components/navbar/navbar-04.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "navbars",
        "title": "Navbar · Disabled State"
      },
      "categories": [
        "navbars",
        "navbar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "navbar-05",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/avatar.json",
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dropdown-menu.json",
        "https://ui.timkit.cn/r/navigation-menu.json",
        "https://ui.timkit.cn/r/popover.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/navbar/navbar-05.tsx",
          "type": "registry:component",
          "target": "components/ui/navbar-05.tsx",
          "content": "import {\n  Button,\n  NavigationMenu,\n  NavigationMenuItem,\n  NavigationMenuLink,\n  NavigationMenuList,\n  Popover,\n  PopoverContent,\n  PopoverTrigger,\n} from '@timui/react'\n\nimport InfoMenu from '@/registry/default/components/navbar-components/info-menu'\nimport Logo from '@/registry/default/components/navbar-components/logo'\nimport NotificationMenu from '@/registry/default/components/navbar-components/notification-menu'\nimport UserMenu from '@/registry/default/components/navbar-components/user-menu'\n\n// Navigation links array to be used in both desktop and mobile menus\nconst navigationLinks = [\n  { href: '#', label: 'Home' },\n  { href: '#', label: 'Features' },\n  { href: '#', label: 'Pricing' },\n  { href: '#', label: 'About' },\n]\n\nexport default function Component() {\n  return (\n    <header className=\"border-b px-4 md:px-6\">\n      <div className=\"flex h-16 items-center justify-between gap-4\">\n        {/* Left side */}\n        <div className=\"flex items-center gap-2\">\n          {/* Mobile menu trigger */}\n          <Popover>\n            <PopoverTrigger asChild>\n              <Button className=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\">\n                <svg\n                  className=\"pointer-events-none\"\n                  width={16}\n                  height={16}\n                  viewBox=\"0 0 24 24\"\n                  fill=\"none\"\n                  stroke=\"currentColor\"\n                  strokeWidth=\"2\"\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  xmlns=\"http://www.w3.org/2000/svg\"\n                >\n                  <path\n                    d=\"M4 12L20 12\"\n                    className=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\"\n                  />\n                  <path\n                    d=\"M4 12H20\"\n                    className=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\"\n                  />\n                  <path\n                    d=\"M4 12H20\"\n                    className=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\"\n                  />\n                </svg>\n              </Button>\n            </PopoverTrigger>\n            <PopoverContent align=\"start\" className=\"w-36 p-1 md:hidden\">\n              <NavigationMenu className=\"max-w-none *:w-full\">\n                <NavigationMenuList className=\"flex-col items-start gap-0 md:gap-2\">\n                  {navigationLinks.map((link, index) => (\n                    <NavigationMenuItem key={index} className=\"w-full\">\n                      <NavigationMenuLink href={link.href} className=\"py-1.5\">\n                        {link.label}\n                      </NavigationMenuLink>\n                    </NavigationMenuItem>\n                  ))}\n                </NavigationMenuList>\n              </NavigationMenu>\n            </PopoverContent>\n          </Popover>\n          {/* Main nav */}\n          <div className=\"flex items-center gap-6\">\n            <a href=\"#\" className=\"text-primary hover:text-primary/90\">\n              <Logo />\n            </a>\n            {/* Navigation menu */}\n            <NavigationMenu className=\"max-md:hidden\">\n              <NavigationMenuList className=\"gap-2\">\n                {navigationLinks.map((link, index) => (\n                  <NavigationMenuItem key={index}>\n                    <NavigationMenuLink\n                      href={link.href}\n                      className=\"text-muted-foreground hover:text-primary py-1.5 font-medium\"\n                    >\n                      {link.label}\n                    </NavigationMenuLink>\n                  </NavigationMenuItem>\n                ))}\n              </NavigationMenuList>\n            </NavigationMenu>\n          </div>\n        </div>\n        {/* Right side */}\n        <div className=\"flex items-center gap-4\">\n          <div className=\"flex items-center gap-2\">\n            {/* Info menu */}\n            <InfoMenu />\n            {/* Notification */}\n            <NotificationMenu />\n          </div>\n          {/* User menu */}\n          <UserMenu />\n        </div>\n      </div>\n    </header>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/info-menu.tsx",
          "type": "registry:component",
          "target": "components/ui/info-menu.tsx",
          "content": "import {\n  Button,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuTrigger,\n} from '@timui/react'\nimport { BookIcon, InfoIcon, LifeBuoyIcon, MessageCircleMoreIcon } from 'lucide-react'\n\nexport default function InfoMenu() {\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button\n          size=\"icon\"\n          variant=\"ghost\"\n          className=\"size-8 rounded-full shadow-none\"\n          aria-label=\"Open edit menu\"\n        >\n          <InfoIcon className=\"text-muted-foreground\" size={16} aria-hidden=\"true\" />\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent className=\"pb-2\">\n        <DropdownMenuLabel>Need help?</DropdownMenuLabel>\n        <DropdownMenuItem\n          className=\"cursor-pointer py-1 data-[highlighted]:bg-transparent data-[highlighted]:underline\"\n          asChild\n        >\n          <a href=\"#\">\n            <BookIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            Documentation\n          </a>\n        </DropdownMenuItem>\n        <DropdownMenuItem\n          className=\"cursor-pointer py-1 data-[highlighted]:bg-transparent data-[highlighted]:underline\"\n          asChild\n        >\n          <a href=\"#\">\n            <LifeBuoyIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            Support\n          </a>\n        </DropdownMenuItem>\n        <DropdownMenuItem\n          className=\"cursor-pointer py-1 data-[highlighted]:bg-transparent data-[highlighted]:underline\"\n          asChild\n        >\n          <a href=\"#\">\n            <MessageCircleMoreIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            Contact us\n          </a>\n        </DropdownMenuItem>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/logo.tsx",
          "type": "registry:component",
          "target": "components/ui/logo.tsx",
          "content": "export default function Logo() {\n  return (\n    <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"33\" height=\"33\" fill=\"currentColor\">\n      <path d=\"M20.46 1.766 17.303.923l-2.66 9.896-2.403-8.934-3.157.843 2.595 9.652-6.464-6.442-2.311 2.304 7.09 7.066-8.83-2.358-.846 3.146 9.648 2.577a6.516 6.516 0 0 1-.169-1.478c0-3.598 2.927-6.515 6.537-6.515s6.537 2.917 6.537 6.515c0 .505-.057.997-.167 1.468l8.768 2.342.846-3.147-9.686-2.586 8.83-2.358-.845-3.147-9.686 2.587 6.464-6.442-2.311-2.304-6.992 6.969 2.369-8.81Z\" />\n      <path d=\"M22.695 18.7a6.495 6.495 0 0 1-1.626 2.986l6.352 6.33 2.31-2.303-7.036-7.013ZM21.005 21.752a6.538 6.538 0 0 1-2.922 1.722l2.312 8.596 3.157-.843-2.547-9.475ZM17.965 23.505a6.569 6.569 0 0 1-1.632.205 6.566 6.566 0 0 1-1.743-.235l-2.314 8.605 3.157.843 2.532-9.418ZM14.478 23.444a6.54 6.54 0 0 1-2.87-1.747l-6.367 6.346 2.31 2.303 6.927-6.902ZM11.555 21.64a6.492 6.492 0 0 1-1.585-2.948L1.173 21.04l.846 3.146 9.536-2.546Z\" />\n    </svg>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/notification-menu.tsx",
          "type": "registry:component",
          "target": "components/ui/notification-menu.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Button, Popover, PopoverContent, PopoverTrigger } from '@timui/react'\nimport { BellIcon } from 'lucide-react'\n\nconst initialNotifications = [\n  {\n    id: 1,\n    user: 'Chris Tompson',\n    action: 'requested review on',\n    target: 'PR #42: Feature implementation',\n    timestamp: '15 minutes ago',\n    unread: true,\n  },\n  {\n    id: 2,\n    user: 'Emma Davis',\n    action: 'shared',\n    target: 'New component library',\n    timestamp: '45 minutes ago',\n    unread: true,\n  },\n  {\n    id: 3,\n    user: 'James Wilson',\n    action: 'assigned you to',\n    target: 'API integration task',\n    timestamp: '4 hours ago',\n    unread: false,\n  },\n  {\n    id: 4,\n    user: 'Alex Morgan',\n    action: 'replied to your comment in',\n    target: 'Authentication flow',\n    timestamp: '12 hours ago',\n    unread: false,\n  },\n  {\n    id: 5,\n    user: 'Sarah Chen',\n    action: 'commented on',\n    target: 'Dashboard redesign',\n    timestamp: '2 days ago',\n    unread: false,\n  },\n  {\n    id: 6,\n    user: 'Miky Derya',\n    action: 'mentioned you in',\n    target: 'Timkit UI open graph image',\n    timestamp: '2 weeks ago',\n    unread: false,\n  },\n]\n\nfunction Dot({ className }: { className?: string }) {\n  return (\n    <svg\n      width=\"6\"\n      height=\"6\"\n      fill=\"currentColor\"\n      viewBox=\"0 0 6 6\"\n      xmlns=\"http://www.w3.org/2000/svg\"\n      className={className}\n      aria-hidden=\"true\"\n    >\n      <circle cx=\"3\" cy=\"3\" r=\"3\" />\n    </svg>\n  )\n}\n\nexport default function NotificationMenu() {\n  const [notifications, setNotifications] = useState(initialNotifications)\n  const unreadCount = notifications.filter((n) => n.unread).length\n\n  const handleMarkAllAsRead = () => {\n    setNotifications(\n      notifications.map((notification) => ({\n        ...notification,\n        unread: false,\n      }))\n    )\n  }\n\n  const handleNotificationClick = (id: number) => {\n    setNotifications(\n      notifications.map((notification) =>\n        notification.id === id ? { ...notification, unread: false } : notification\n      )\n    )\n  }\n\n  return (\n    <Popover>\n      <PopoverTrigger asChild>\n        <Button\n          size=\"icon\"\n          variant=\"ghost\"\n          className=\"text-muted-foreground relative size-8 rounded-full shadow-none\"\n          aria-label=\"Open notifications\"\n        >\n          <BellIcon size={16} aria-hidden=\"true\" />\n          {unreadCount > 0 && (\n            <div\n              aria-hidden=\"true\"\n              className=\"bg-primary absolute top-0.5 right-0.5 size-1 rounded-full\"\n            />\n          )}\n        </Button>\n      </PopoverTrigger>\n      <PopoverContent className=\"w-80 p-1\">\n        <div className=\"flex items-baseline justify-between gap-4 px-3 py-2\">\n          <div className=\"text-sm font-semibold\">Notifications</div>\n          {unreadCount > 0 && (\n            <button className=\"text-xs font-medium hover:underline\" onClick={handleMarkAllAsRead}>\n              Mark all as read\n            </button>\n          )}\n        </div>\n        <div\n          role=\"separator\"\n          aria-orientation=\"horizontal\"\n          className=\"bg-border -mx-1 my-1 h-px\"\n        ></div>\n        {notifications.map((notification) => (\n          <div\n            key={notification.id}\n            className=\"hover:bg-accent rounded-md px-3 py-2 text-sm transition-colors\"\n          >\n            <div className=\"relative flex items-start pe-3\">\n              <div className=\"flex-1 space-y-1\">\n                <button\n                  className=\"text-foreground/80 text-left after:absolute after:inset-0\"\n                  onClick={() => handleNotificationClick(notification.id)}\n                >\n                  <span className=\"text-foreground font-medium hover:underline\">\n                    {notification.user}\n                  </span>{' '}\n                  {notification.action}{' '}\n                  <span className=\"text-foreground font-medium hover:underline\">\n                    {notification.target}\n                  </span>\n                  .\n                </button>\n                <div className=\"text-muted-foreground text-xs\">{notification.timestamp}</div>\n              </div>\n              {notification.unread && (\n                <div className=\"absolute end-0 self-center\">\n                  <span className=\"sr-only\">Unread</span>\n                  <Dot />\n                </div>\n              )}\n            </div>\n          </div>\n        ))}\n      </PopoverContent>\n    </Popover>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/user-menu.tsx",
          "type": "registry:component",
          "target": "components/ui/user-menu.tsx",
          "content": "import {\n  Avatar,\n  AvatarFallback,\n  AvatarImage,\n  Button,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from '@timui/react'\nimport { BoltIcon, BookOpenIcon, Layers2Icon, LogOutIcon, PinIcon, UserPenIcon } from 'lucide-react'\n\nexport default function UserMenu() {\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button variant=\"ghost\" className=\"h-auto p-0 hover:bg-transparent\">\n          <Avatar>\n            <AvatarImage src=\"./avatar.jpg\" alt=\"Profile image\" />\n            <AvatarFallback>KK</AvatarFallback>\n          </Avatar>\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent className=\"max-w-64\" align=\"end\">\n        <DropdownMenuLabel className=\"flex min-w-0 flex-col\">\n          <span className=\"text-foreground truncate text-sm font-medium\">Keith Kennedy</span>\n          <span className=\"text-muted-foreground truncate text-xs font-normal\">\n            k.kennedy@ui.timkit.cn\n          </span>\n        </DropdownMenuLabel>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <BoltIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 1</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <Layers2Icon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 2</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <BookOpenIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 3</span>\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <PinIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 4</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <UserPenIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 5</span>\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuItem>\n          <LogOutIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n          <span>Logout</span>\n        </DropdownMenuItem>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-05.vue",
          "target": "components/ui/navbar-05.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { Button } from '@timui/vue';\nimport { NavigationMenu, NavigationMenuItem, NavigationMenuLink, NavigationMenuList } from '@timui/vue';\nimport { Popover, PopoverContent, PopoverTrigger } from '@timui/vue';\nimport InfoMenu from '@/registry/default/components/navbar-components/info-menu.vue';\nimport Logo from '@/registry/default/components/navbar-components/logo.vue';\nimport NotificationMenu from '@/registry/default/components/navbar-components/notification-menu.vue';\nimport UserMenu from '@/registry/default/components/navbar-components/user-menu.vue';\n\nconst navigationLinks = [\n  { href: '#', label: 'Home' },\n  { href: '#', label: 'Features' },\n  { href: '#', label: 'Pricing' },\n  { href: '#', label: 'About' },\n];\n\n</script>\n\n<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 items-center justify-between gap-4\"><div class=\"flex items-center gap-2\"><Popover><PopoverTrigger as-child><Button class=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\"><svg class=\"pointer-events-none\" :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></Button></PopoverTrigger><PopoverContent align=\"start\" class=\"w-36 p-1 md:hidden\"><NavigationMenu class=\"max-w-none *:w-full\"><NavigationMenuList class=\"flex-col items-start gap-0 md:gap-2\"><NavigationMenuItem v-for=\"(link, index) in navigationLinks\" :key=\"index\" class=\"w-full\"><NavigationMenuLink :href=\"link.href\" class=\"py-1.5\">{{ link.label }}</NavigationMenuLink></NavigationMenuItem></NavigationMenuList></NavigationMenu></PopoverContent></Popover><div class=\"flex items-center gap-6\"><a href=\"#\" class=\"text-primary hover:text-primary/90\"><Logo /></a><NavigationMenu class=\"max-md:hidden\"><NavigationMenuList class=\"gap-2\"><NavigationMenuItem v-for=\"(link, index) in navigationLinks\" :key=\"index\"><NavigationMenuLink :href=\"link.href\" class=\"text-muted-foreground hover:text-primary py-1.5 font-medium\">{{ link.label }}</NavigationMenuLink></NavigationMenuItem></NavigationMenuList></NavigationMenu></div></div><div class=\"flex items-center gap-4\"><div class=\"flex items-center gap-2\"><InfoMenu /><NotificationMenu /></div><UserMenu /></div></div></header>\n</template>\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-05.html",
          "target": "components/ui/navbar-05.html",
          "type": "registry:component",
          "content": "<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 items-center justify-between gap-4\"><div class=\"flex items-center gap-2\"><Popover><PopoverTrigger aschild><Button class=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\"><svg class=\"pointer-events-none\" width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></Button></PopoverTrigger><PopoverContent align=\"start\" class=\"w-36 p-1 md:hidden\"><NavigationMenu class=\"max-w-none *:w-full\"><NavigationMenuList class=\"flex-col items-start gap-0 md:gap-2\"><!-- Loop navigationLinks -->\n<NavigationMenuItem key=\"${index}\" class=\"w-full\"><NavigationMenuLink href=\"${link.href}\" class=\"py-1.5\">${link.label}</NavigationMenuLink></NavigationMenuItem>\n<!-- End Loop --></NavigationMenuList></NavigationMenu></PopoverContent></Popover><div class=\"flex items-center gap-6\"><a href=\"#\" class=\"text-primary hover:text-primary/90\"><Logo /></a><NavigationMenu class=\"max-md:hidden\"><NavigationMenuList class=\"gap-2\"><!-- Loop navigationLinks -->\n<NavigationMenuItem key=\"${index}\"><NavigationMenuLink href=\"${link.href}\" class=\"text-muted-foreground hover:text-primary py-1.5 font-medium\">${link.label}</NavigationMenuLink></NavigationMenuItem>\n<!-- End Loop --></NavigationMenuList></NavigationMenu></div></div><div class=\"flex items-center gap-4\"><div class=\"flex items-center gap-2\"><InfoMenu /><NotificationMenu /></div><UserMenu /></div></div></header>\n</template>"
        },
        {
          "path": "registry/default/components/navbar/navbar-05.wxml",
          "target": "components/ui/navbar-05/navbar-05.wxml",
          "type": "registry:component",
          "content": "<view>\n  <header class=\"border-b px-4 md:px-6\"><view class=\"flex h-16 items-center justify-between gap-4\"><view class=\"flex items-center gap-2\"><popover><popovertrigger aschild><button class=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\"><svg class=\"pointer-events-none\" width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></button></popovertrigger><popovercontent align=\"start\" class=\"w-36 p-1 md:hidden\"><navigationmenu class=\"max-w-none *:w-full\"><navigationmenulist class=\"flex-col items-start gap-0 md:gap-2\"><navigationmenuitem wx:for=\"{{navigationLinks}}\" wx:for-item=\"link\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{index}}\" class=\"w-full\"><navigationmenulink href=\"{{link.href}}\" class=\"py-1.5\">{{ link.label }}</navigationmenulink></navigationmenuitem></navigationmenulist></navigationmenu></popovercontent></popover><view class=\"flex items-center gap-6\"><a href=\"#\" class=\"text-primary hover:text-primary/90\"><logo /></a><navigationmenu class=\"max-md:hidden\"><navigationmenulist class=\"gap-2\"><navigationmenuitem wx:for=\"{{navigationLinks}}\" wx:for-item=\"link\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{index}}\"><navigationmenulink href=\"{{link.href}}\" class=\"text-muted-foreground hover:text-primary py-1.5 font-medium\">{{ link.label }}</navigationmenulink></navigationmenuitem></navigationmenulist></navigationmenu></view></view><view class=\"flex items-center gap-4\"><view class=\"flex items-center gap-2\"><infomenu /><notificationmenu /></view><usermenu /></view></view></header>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "navbar, navigation"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "navbar-05",
          "group": "navbar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "navbar-05",
              "path": "registry/default/components/navbar/navbar-05.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "navbar-05",
              "path": "registry/default/components/navbar/navbar-05.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "navbar-05",
              "path": "registry/default/components/navbar/navbar-05.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "navbar-05",
              "path": "registry/default/components/navbar/navbar-05.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "navbars",
        "title": "Navbar · Interactive State"
      },
      "categories": [
        "navbars",
        "navbar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "navbar-06",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/avatar.json",
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dropdown-menu.json",
        "https://ui.timkit.cn/r/navigation-menu.json",
        "https://ui.timkit.cn/r/popover.json",
        "https://ui.timkit.cn/r/select.json",
        "https://ui.timkit.cn/r/tooltip.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/navbar/navbar-06.tsx",
          "type": "registry:component",
          "target": "components/ui/navbar-06.tsx",
          "content": "import { useId } from 'react'\nimport {\n  Button,\n  NavigationMenu,\n  NavigationMenuItem,\n  NavigationMenuLink,\n  NavigationMenuList,\n  Popover,\n  PopoverContent,\n  PopoverTrigger,\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n  Tooltip,\n  TooltipContent,\n  TooltipProvider,\n  TooltipTrigger,\n} from '@timui/react'\nimport { FileTextIcon, GlobeIcon, HomeIcon, LayersIcon, UsersIcon } from 'lucide-react'\n\nimport Logo from '@/registry/default/components/navbar-components/logo'\nimport ThemeToggle from '@/registry/default/components/navbar-components/theme-toggle'\nimport UserMenu from '@/registry/default/components/navbar-components/user-menu'\n\n// Navigation links with icons for desktop icon-only navigation\nconst navigationLinks = [\n  { href: '#', label: 'Dashboard', icon: HomeIcon, active: true },\n  { href: '#', label: 'Projects', icon: LayersIcon },\n  { href: '#', label: 'Documentation', icon: FileTextIcon },\n  { href: '#', label: 'Team', icon: UsersIcon },\n]\n\n// Language options\nconst languages = [\n  { value: 'en', label: 'En' },\n  { value: 'es', label: 'Es' },\n  { value: 'fr', label: 'Fr' },\n  { value: 'de', label: 'De' },\n  { value: 'ja', label: 'Ja' },\n]\n\nexport default function Component() {\n  const id = useId()\n\n  return (\n    <header className=\"border-b px-4 md:px-6\">\n      <div className=\"flex h-16 items-center justify-between gap-4\">\n        {/* Left side */}\n        <div className=\"flex flex-1 items-center gap-2\">\n          {/* Mobile menu trigger */}\n          <Popover>\n            <PopoverTrigger asChild>\n              <Button className=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\">\n                <svg\n                  className=\"pointer-events-none\"\n                  width={16}\n                  height={16}\n                  viewBox=\"0 0 24 24\"\n                  fill=\"none\"\n                  stroke=\"currentColor\"\n                  strokeWidth=\"2\"\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  xmlns=\"http://www.w3.org/2000/svg\"\n                >\n                  <path\n                    d=\"M4 12L20 12\"\n                    className=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\"\n                  />\n                  <path\n                    d=\"M4 12H20\"\n                    className=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\"\n                  />\n                  <path\n                    d=\"M4 12H20\"\n                    className=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\"\n                  />\n                </svg>\n              </Button>\n            </PopoverTrigger>\n            <PopoverContent align=\"start\" className=\"w-36 p-1 md:hidden\">\n              <NavigationMenu className=\"max-w-none *:w-full\">\n                <NavigationMenuList className=\"flex-col items-start gap-0 md:gap-2\">\n                  {navigationLinks.map((link, index) => {\n                    const Icon = link.icon\n                    return (\n                      <NavigationMenuItem key={index} className=\"w-full\">\n                        <NavigationMenuLink\n                          href={link.href}\n                          className=\"flex-row items-center gap-2 py-1.5\"\n                          active={link.active}\n                        >\n                          <Icon size={16} className=\"text-muted-foreground\" aria-hidden=\"true\" />\n                          <span>{link.label}</span>\n                        </NavigationMenuLink>\n                      </NavigationMenuItem>\n                    )\n                  })}\n                </NavigationMenuList>\n              </NavigationMenu>\n            </PopoverContent>\n          </Popover>\n          <div className=\"flex items-center gap-6\">\n            {/* Logo */}\n            <a href=\"#\" className=\"text-primary hover:text-primary/90\">\n              <Logo />\n            </a>\n            {/* Desktop navigation - icon only */}\n            <NavigationMenu className=\"hidden md:flex\">\n              <NavigationMenuList className=\"gap-2\">\n                <TooltipProvider>\n                  {navigationLinks.map((link) => (\n                    <NavigationMenuItem key={link.label}>\n                      <Tooltip>\n                        <TooltipTrigger asChild>\n                          <NavigationMenuLink\n                            href={link.href}\n                            className=\"flex size-8 items-center justify-center p-1.5\"\n                          >\n                            <link.icon size={20} aria-hidden=\"true\" />\n                            <span className=\"sr-only\">{link.label}</span>\n                          </NavigationMenuLink>\n                        </TooltipTrigger>\n                        <TooltipContent side=\"bottom\" className=\"px-2 py-1 text-xs\">\n                          <p>{link.label}</p>\n                        </TooltipContent>\n                      </Tooltip>\n                    </NavigationMenuItem>\n                  ))}\n                </TooltipProvider>\n              </NavigationMenuList>\n            </NavigationMenu>\n          </div>\n        </div>\n        {/* Right side */}\n        <div className=\"flex items-center gap-2\">\n          {/* Theme toggle */}\n          <ThemeToggle />\n          {/* Language selector */}\n          <Select defaultValue=\"en\">\n            <SelectTrigger\n              id={`language-${id}`}\n              className=\"[&>svg]:text-muted-foreground/80 hover:bg-accent hover:text-accent-foreground h-8 border-none px-2 shadow-none [&>svg]:shrink-0\"\n              aria-label=\"Select language\"\n            >\n              <GlobeIcon size={16} aria-hidden=\"true\" />\n              <SelectValue className=\"hidden sm:inline-flex\" />\n            </SelectTrigger>\n            <SelectContent className=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2 [&_*[role=option]>span]:flex [&_*[role=option]>span]:items-center [&_*[role=option]>span]:gap-2\">\n              {languages.map((lang) => (\n                <SelectItem key={lang.value} value={lang.value}>\n                  <span className=\"flex items-center gap-2\">\n                    <span className=\"truncate\">{lang.label}</span>\n                  </span>\n                </SelectItem>\n              ))}\n            </SelectContent>\n          </Select>\n          {/* User menu */}\n          <UserMenu />\n        </div>\n      </div>\n    </header>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/logo.tsx",
          "type": "registry:component",
          "target": "components/ui/logo.tsx",
          "content": "export default function Logo() {\n  return (\n    <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"33\" height=\"33\" fill=\"currentColor\">\n      <path d=\"M20.46 1.766 17.303.923l-2.66 9.896-2.403-8.934-3.157.843 2.595 9.652-6.464-6.442-2.311 2.304 7.09 7.066-8.83-2.358-.846 3.146 9.648 2.577a6.516 6.516 0 0 1-.169-1.478c0-3.598 2.927-6.515 6.537-6.515s6.537 2.917 6.537 6.515c0 .505-.057.997-.167 1.468l8.768 2.342.846-3.147-9.686-2.586 8.83-2.358-.845-3.147-9.686 2.587 6.464-6.442-2.311-2.304-6.992 6.969 2.369-8.81Z\" />\n      <path d=\"M22.695 18.7a6.495 6.495 0 0 1-1.626 2.986l6.352 6.33 2.31-2.303-7.036-7.013ZM21.005 21.752a6.538 6.538 0 0 1-2.922 1.722l2.312 8.596 3.157-.843-2.547-9.475ZM17.965 23.505a6.569 6.569 0 0 1-1.632.205 6.566 6.566 0 0 1-1.743-.235l-2.314 8.605 3.157.843 2.532-9.418ZM14.478 23.444a6.54 6.54 0 0 1-2.87-1.747l-6.367 6.346 2.31 2.303 6.927-6.902ZM11.555 21.64a6.492 6.492 0 0 1-1.585-2.948L1.173 21.04l.846 3.146 9.536-2.546Z\" />\n    </svg>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/theme-toggle.tsx",
          "type": "registry:component",
          "target": "components/ui/theme-toggle.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Toggle } from '@timui/react'\nimport { MoonIcon, SunIcon } from 'lucide-react'\n\nexport default function ThemeToggle() {\n  const [theme, setTheme] = useState<string>('light')\n\n  return (\n    <div>\n      <Toggle\n        variant=\"outline\"\n        className=\"group data-[state=on]:hover:bg-muted text-muted-foreground data-[state=on]:text-muted-foreground data-[state=on]:hover:text-foreground size-8 rounded-full border-none shadow-none data-[state=on]:bg-transparent\"\n        pressed={theme === 'dark'}\n        onPressedChange={() => setTheme((prev) => (prev === 'dark' ? 'light' : 'dark'))}\n        aria-label={`Switch to ${theme === 'dark' ? 'light' : 'dark'} mode`}\n      >\n        {/* Note: After dark mode implementation, rely on dark: prefix rather than group-data-[state=on]: */}\n        <MoonIcon\n          size={16}\n          className=\"shrink-0 scale-0 opacity-0 transition-all group-data-[state=on]:scale-100 group-data-[state=on]:opacity-100\"\n          aria-hidden=\"true\"\n        />\n        <SunIcon\n          size={16}\n          className=\"absolute shrink-0 scale-100 opacity-100 transition-all group-data-[state=on]:scale-0 group-data-[state=on]:opacity-0\"\n          aria-hidden=\"true\"\n        />\n      </Toggle>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/user-menu.tsx",
          "type": "registry:component",
          "target": "components/ui/user-menu.tsx",
          "content": "import {\n  Avatar,\n  AvatarFallback,\n  AvatarImage,\n  Button,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from '@timui/react'\nimport { BoltIcon, BookOpenIcon, Layers2Icon, LogOutIcon, PinIcon, UserPenIcon } from 'lucide-react'\n\nexport default function UserMenu() {\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button variant=\"ghost\" className=\"h-auto p-0 hover:bg-transparent\">\n          <Avatar>\n            <AvatarImage src=\"./avatar.jpg\" alt=\"Profile image\" />\n            <AvatarFallback>KK</AvatarFallback>\n          </Avatar>\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent className=\"max-w-64\" align=\"end\">\n        <DropdownMenuLabel className=\"flex min-w-0 flex-col\">\n          <span className=\"text-foreground truncate text-sm font-medium\">Keith Kennedy</span>\n          <span className=\"text-muted-foreground truncate text-xs font-normal\">\n            k.kennedy@ui.timkit.cn\n          </span>\n        </DropdownMenuLabel>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <BoltIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 1</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <Layers2Icon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 2</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <BookOpenIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 3</span>\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <PinIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 4</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <UserPenIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 5</span>\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuItem>\n          <LogOutIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n          <span>Logout</span>\n        </DropdownMenuItem>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-06.vue",
          "target": "components/ui/navbar-06.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { FileTextIcon, GlobeIcon, HomeIcon, LayersIcon, UsersIcon } from 'lucide-vue-next'\nimport { Button } from '@timui/vue'\nimport {\n  NavigationMenu,\n  NavigationMenuItem,\n  NavigationMenuLink,\n  NavigationMenuList,\n} from '@timui/vue'\nimport { Popover, PopoverContent, PopoverTrigger } from '@timui/vue'\nimport {\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from '@timui/vue'\nimport { Tooltip } from '@timui/vue'\nimport { TooltipContent } from '@timui/vue'\nimport { TooltipProvider } from '@timui/vue'\nimport { TooltipTrigger } from '@timui/vue'\nimport Logo from '@/registry/default/components/navbar-components/logo.vue'\nimport ThemeToggle from '@/registry/default/components/navbar-components/theme-toggle.vue'\nimport UserMenu from '@/registry/default/components/navbar-components/user-menu.vue'\n\nconst navigationLinks = [\n  { href: '#', label: 'Dashboard', icon: HomeIcon, active: true },\n  { href: '#', label: 'Projects', icon: LayersIcon },\n  { href: '#', label: 'Documentation', icon: FileTextIcon },\n  { href: '#', label: 'Team', icon: UsersIcon },\n]\n\nconst languages = [\n  { value: 'en', label: 'En' },\n  { value: 'es', label: 'Es' },\n  { value: 'fr', label: 'Fr' },\n  { value: 'de', label: 'De' },\n  { value: 'ja', label: 'Ja' },\n]\n\nconst id = 'navbar-06'\n</script>\n\n<template>\n  <header class=\"border-b px-4 md:px-6\">\n    <div class=\"flex h-16 items-center justify-between gap-4\">\n      <div class=\"flex flex-1 items-center gap-2\">\n        <Popover>\n          <PopoverTrigger as-child>\n            <Button class=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\">\n              <svg\n                class=\"pointer-events-none\"\n                :width=\"16\"\n                :height=\"16\"\n                viewBox=\"0 0 24 24\"\n                fill=\"none\"\n                stroke=\"currentColor\"\n                stroke-width=\"2\"\n                stroke-linecap=\"round\"\n                stroke-linejoin=\"round\"\n                xmlns=\"http://www.w3.org/2000/svg\"\n              >\n                <path\n                  d=\"M4 12L20 12\"\n                  class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\"\n                />\n                <path\n                  d=\"M4 12H20\"\n                  class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\"\n                />\n                <path\n                  d=\"M4 12H20\"\n                  class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\"\n                />\n              </svg>\n            </Button>\n          </PopoverTrigger>\n          <PopoverContent align=\"start\" class=\"w-36 p-1 md:hidden\">\n            <NavigationMenu class=\"max-w-none *:w-full\">\n              <NavigationMenuList class=\"flex-col items-start gap-0 md:gap-2\">\n                <NavigationMenuItem v-for=\"(link, index) in navigationLinks\" :key=\"index\" class=\"w-full\">\n                  <NavigationMenuLink\n                    :href=\"link.href\"\n                    class=\"flex-row items-center gap-2 py-1.5\"\n                    :active=\"link.active\"\n                  >\n                    <component :is=\"link.icon\" :size=\"16\" class=\"text-muted-foreground\" aria-hidden=\"true\" />\n                    <span>{{ link.label }}</span>\n                  </NavigationMenuLink>\n                </NavigationMenuItem>\n              </NavigationMenuList>\n            </NavigationMenu>\n          </PopoverContent>\n        </Popover>\n\n        <div class=\"flex items-center gap-6\">\n          <a href=\"#\" class=\"text-primary hover:text-primary/90\">\n            <Logo />\n          </a>\n\n          <NavigationMenu class=\"hidden md:flex\">\n            <NavigationMenuList class=\"gap-2\">\n              <TooltipProvider>\n                <NavigationMenuItem v-for=\"link in navigationLinks\" :key=\"link.label\">\n                  <Tooltip>\n                    <TooltipTrigger as-child>\n                      <NavigationMenuLink :href=\"link.href\" class=\"flex size-8 items-center justify-center p-1.5\">\n                        <component :is=\"link.icon\" :size=\"20\" aria-hidden=\"true\" />\n                        <span class=\"sr-only\">{{ link.label }}</span>\n                      </NavigationMenuLink>\n                    </TooltipTrigger>\n                    <TooltipContent side=\"bottom\" class=\"px-2 py-1 text-xs\">\n                      <p>{{ link.label }}</p>\n                    </TooltipContent>\n                  </Tooltip>\n                </NavigationMenuItem>\n              </TooltipProvider>\n            </NavigationMenuList>\n          </NavigationMenu>\n        </div>\n      </div>\n\n      <div class=\"flex items-center gap-2\">\n        <ThemeToggle />\n\n        <Select default-value=\"en\">\n          <SelectTrigger\n            :id=\"`language-${id}`\"\n            class=\"[&>svg]:text-muted-foreground/80 hover:bg-accent hover:text-accent-foreground h-8 border-none px-2 shadow-none [&>svg]:shrink-0\"\n            aria-label=\"Select language\"\n          >\n            <GlobeIcon :size=\"16\" aria-hidden=\"true\" />\n            <SelectValue class=\"hidden sm:inline-flex\" />\n          </SelectTrigger>\n          <SelectContent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2 [&_*[role=option]>span]:flex [&_*[role=option]>span]:items-center [&_*[role=option]>span]:gap-2\">\n            <SelectItem v-for=\"lang in languages\" :key=\"lang.value\" :value=\"lang.value\">\n              <span class=\"flex items-center gap-2\">\n                <span class=\"truncate\">{{ lang.label }}</span>\n              </span>\n            </SelectItem>\n          </SelectContent>\n        </Select>\n\n        <UserMenu />\n      </div>\n    </div>\n  </header>\n</template>\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-06.html",
          "target": "components/ui/navbar-06.html",
          "type": "registry:component",
          "content": "<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 items-center justify-between gap-4\"><div class=\"flex flex-1 items-center gap-2\"><Popover><PopoverTrigger aschild><Button class=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\"><svg class=\"pointer-events-none\" width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></Button></PopoverTrigger><PopoverContent align=\"start\" class=\"w-36 p-1 md:hidden\"><NavigationMenu class=\"max-w-none *:w-full\"><NavigationMenuList class=\"flex-col items-start gap-0 md:gap-2\">${navigationLinks.map((link, index) => {\n                    const Icon = link.icon\n                    return (\n                      <NavigationMenuItem key={index} className=\"w-full\">\n                        <NavigationMenuLink\n                          href={link.href}\n                          className=\"flex-row items-center gap-2 py-1.5\"\n                          active={link.active}\n                        >\n                          <Icon size={16} className=\"text-muted-foreground\" aria-hidden=\"true\" />\n                          <span>{link.label}</span>\n                        </NavigationMenuLink>\n                      </NavigationMenuItem>\n                    )\n                  })}</NavigationMenuList></NavigationMenu></PopoverContent></Popover><div class=\"flex items-center gap-6\"><a href=\"#\" class=\"text-primary hover:text-primary/90\"><Logo /></a><NavigationMenu class=\"hidden md:flex\"><NavigationMenuList class=\"gap-2\"><TooltipProvider><!-- Loop navigationLinks -->\n<NavigationMenuItem key=\"${link.label}\"><Tooltip><TooltipTrigger aschild><NavigationMenuLink href=\"${link.href}\" class=\"flex size-8 items-center justify-center p-1.5\"><link.icon size=\"${20}\" aria-hidden=\"true\" /><span class=\"sr-only\">${link.label}</span></NavigationMenuLink></TooltipTrigger><TooltipContent side=\"bottom\" class=\"px-2 py-1 text-xs\"><p>${link.label}</p></TooltipContent></Tooltip></NavigationMenuItem>\n<!-- End Loop --></TooltipProvider></NavigationMenuList></NavigationMenu></div></div><div class=\"flex items-center gap-2\"><ThemeToggle /><Select default-value=\"en\"><SelectTrigger id=\"${`language-${id}`}\" class=\"[&>svg]:text-muted-foreground/80 hover:bg-accent hover:text-accent-foreground h-8 border-none px-2 shadow-none [&>svg]:shrink-0\" aria-label=\"Select language\"><GlobeIcon size=\"${16}\" aria-hidden=\"true\" /><SelectValue class=\"hidden sm:inline-flex\" /></SelectTrigger><SelectContent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2 [&_*[role=option]>span]:flex [&_*[role=option]>span]:items-center [&_*[role=option]>span]:gap-2\"><!-- Loop languages -->\n<SelectItem key=\"${lang.value}\" value=\"${lang.value}\"><span class=\"flex items-center gap-2\"><span class=\"truncate\">${lang.label}</span></span></SelectItem>\n<!-- End Loop --></SelectContent></Select><UserMenu /></div></div></header>\n</template>"
        },
        {
          "path": "registry/default/components/navbar/navbar-06.wxml",
          "target": "components/ui/navbar-06/navbar-06.wxml",
          "type": "registry:component",
          "content": "<view>\n  <header class=\"border-b px-4 md:px-6\"><view class=\"flex h-16 items-center justify-between gap-4\"><view class=\"flex flex-1 items-center gap-2\"><popover><popovertrigger aschild><button class=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\"><svg class=\"pointer-events-none\" width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></button></popovertrigger><popovercontent align=\"start\" class=\"w-36 p-1 md:hidden\"><navigationmenu class=\"max-w-none *:w-full\"><navigationmenulist class=\"flex-col items-start gap-0 md:gap-2\">{{ navigationLinks.map((link, index) => {\n                    const Icon = link.icon\n                    return (\n                      <NavigationMenuItem key={index} className=\"w-full\">\n                        <NavigationMenuLink\n                          href={link.href}\n                          className=\"flex-row items-center gap-2 py-1.5\"\n                          active={link.active}\n                        >\n                          <Icon size={16} className=\"text-muted-foreground\" aria-hidden=\"true\" />\n                          <span>{link.label}</span>\n                        </NavigationMenuLink>\n                      </NavigationMenuItem>\n                    )\n                  }) }}</navigationmenulist></navigationmenu></popovercontent></popover><view class=\"flex items-center gap-6\"><a href=\"#\" class=\"text-primary hover:text-primary/90\"><logo /></a><navigationmenu class=\"hidden md:flex\"><navigationmenulist class=\"gap-2\"><tooltipprovider><navigationmenuitem wx:for=\"{{navigationLinks}}\" wx:for-item=\"link\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{link.label}}\"><tooltip><tooltiptrigger aschild><navigationmenulink href=\"{{link.href}}\" class=\"flex size-8 items-center justify-center p-1.5\"><link.icon size=\"{{20}}\" aria-hidden=\"true\" /><text class=\"sr-only\">{{ link.label }}</text></navigationmenulink></tooltiptrigger><tooltipcontent side=\"bottom\" class=\"px-2 py-1 text-xs\"><text>{{ link.label }}</text></tooltipcontent></tooltip></navigationmenuitem></tooltipprovider></navigationmenulist></navigationmenu></view></view><view class=\"flex items-center gap-2\"><themetoggle /><select default-value=\"en\"><selecttrigger id=\"{{`language-${id}`}}\" class=\"[&>svg]:text-muted-foreground/80 hover:bg-accent hover:text-accent-foreground h-8 border-none px-2 shadow-none [&>svg]:shrink-0\" aria-label=\"Select language\"><globeicon size=\"{{16}}\" aria-hidden=\"true\" /><selectvalue class=\"hidden sm:inline-flex\" /></selecttrigger><selectcontent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2 [&_*[role=option]>span]:flex [&_*[role=option]>span]:items-center [&_*[role=option]>span]:gap-2\"><selectitem wx:for=\"{{languages}}\" wx:for-item=\"lang\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{lang.value}}\" value=\"{{lang.value}}\"><text class=\"flex items-center gap-2\"><text class=\"truncate\">{{ lang.label }}</text></text></selectitem></selectcontent></select><usermenu /></view></view></header>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "navbar, navigation"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "navbar-06",
          "group": "navbar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "navbar-06",
              "path": "registry/default/components/navbar/navbar-06.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "navbar-06",
              "path": "registry/default/components/navbar/navbar-06.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "navbar-06",
              "path": "registry/default/components/navbar/navbar-06.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "navbar-06",
              "path": "registry/default/components/navbar/navbar-06.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "navbars",
        "title": "Navbar · Select language"
      },
      "categories": [
        "navbars",
        "navbar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "navbar-07",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/avatar.json",
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/breadcrumb.json",
        "https://ui.timkit.cn/r/dropdown-menu.json",
        "https://ui.timkit.cn/r/popover.json",
        "https://ui.timkit.cn/r/select.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/navbar/navbar-07.tsx",
          "type": "registry:component",
          "target": "components/ui/navbar-07.tsx",
          "content": "import { useState } from 'react'\nimport {\n  Breadcrumb,\n  BreadcrumbEllipsis,\n  BreadcrumbItem,\n  BreadcrumbLink,\n  BreadcrumbList,\n  BreadcrumbSeparator,\n  Button,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuTrigger,\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from '@timui/react'\nimport { ChevronsUpDown } from 'lucide-react'\n\nimport Logo from '@/registry/default/components/navbar-components/logo'\nimport NotificationMenu from '@/registry/default/components/navbar-components/notification-menu'\nimport UserMenu from '@/registry/default/components/navbar-components/user-menu'\n\nexport default function Component() {\n  const [projectValue, setProjectValue] = useState('1')\n\n  return (\n    <header className=\"border-b px-4 md:px-6\">\n      <div className=\"flex h-16 items-center justify-between gap-4\">\n        {/* Left side */}\n        <div className=\"flex items-center gap-2\">\n          <Breadcrumb>\n            <BreadcrumbList>\n              <BreadcrumbItem>\n                <BreadcrumbLink href=\"#\" className=\"text-foreground\">\n                  <Logo />\n                </BreadcrumbLink>\n              </BreadcrumbItem>\n              <BreadcrumbSeparator> / </BreadcrumbSeparator>\n              <BreadcrumbItem className=\"md:hidden\">\n                <DropdownMenu>\n                  <DropdownMenuTrigger className=\"hover:text-foreground\">\n                    <BreadcrumbEllipsis />\n                    <span className=\"sr-only\">Toggle menu</span>\n                  </DropdownMenuTrigger>\n                  <DropdownMenuContent align=\"start\">\n                    <DropdownMenuItem asChild>\n                      <a href=\"#\">Personal Account</a>\n                    </DropdownMenuItem>\n                    <DropdownMenuItem asChild>\n                      <a href=\"#\">Projects</a>\n                    </DropdownMenuItem>\n                  </DropdownMenuContent>\n                </DropdownMenu>\n              </BreadcrumbItem>\n              <BreadcrumbItem className=\"max-md:hidden\">\n                <BreadcrumbLink href=\"#\">Personal Account</BreadcrumbLink>\n              </BreadcrumbItem>\n              <BreadcrumbSeparator className=\"max-md:hidden\"> / </BreadcrumbSeparator>\n              <BreadcrumbItem className=\"max-md:hidden\">\n                <BreadcrumbLink href=\"#\">Projects</BreadcrumbLink>\n              </BreadcrumbItem>\n              <BreadcrumbSeparator> / </BreadcrumbSeparator>\n              <BreadcrumbItem>\n                <Select value={projectValue} onValueChange={(value) => setProjectValue(value)}>\n                  <SelectTrigger aria-label=\"Select project\" asChild>\n                    <Button\n                      variant=\"ghost\"\n                      className=\"focus-visible:bg-accent text-foreground h-8 px-1.5 focus-visible:ring-0\"\n                    >\n                      <SelectValue placeholder=\"Select project\" />\n                      <ChevronsUpDown size={14} className=\"text-muted-foreground/80\" />\n                    </Button>\n                  </SelectTrigger>\n                  <SelectContent className=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\">\n                    <SelectItem value=\"1\">Main project</SelectItem>\n                    <SelectItem value=\"2\">Origin project</SelectItem>\n                  </SelectContent>\n                </Select>\n              </BreadcrumbItem>\n            </BreadcrumbList>\n          </Breadcrumb>\n        </div>\n        {/* Right side */}\n        <div className=\"flex items-center gap-4\">\n          {/* Notification */}\n          <NotificationMenu />\n          {/* User menu */}\n          <UserMenu />\n        </div>\n      </div>\n    </header>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/logo.tsx",
          "type": "registry:component",
          "target": "components/ui/logo.tsx",
          "content": "export default function Logo() {\n  return (\n    <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"33\" height=\"33\" fill=\"currentColor\">\n      <path d=\"M20.46 1.766 17.303.923l-2.66 9.896-2.403-8.934-3.157.843 2.595 9.652-6.464-6.442-2.311 2.304 7.09 7.066-8.83-2.358-.846 3.146 9.648 2.577a6.516 6.516 0 0 1-.169-1.478c0-3.598 2.927-6.515 6.537-6.515s6.537 2.917 6.537 6.515c0 .505-.057.997-.167 1.468l8.768 2.342.846-3.147-9.686-2.586 8.83-2.358-.845-3.147-9.686 2.587 6.464-6.442-2.311-2.304-6.992 6.969 2.369-8.81Z\" />\n      <path d=\"M22.695 18.7a6.495 6.495 0 0 1-1.626 2.986l6.352 6.33 2.31-2.303-7.036-7.013ZM21.005 21.752a6.538 6.538 0 0 1-2.922 1.722l2.312 8.596 3.157-.843-2.547-9.475ZM17.965 23.505a6.569 6.569 0 0 1-1.632.205 6.566 6.566 0 0 1-1.743-.235l-2.314 8.605 3.157.843 2.532-9.418ZM14.478 23.444a6.54 6.54 0 0 1-2.87-1.747l-6.367 6.346 2.31 2.303 6.927-6.902ZM11.555 21.64a6.492 6.492 0 0 1-1.585-2.948L1.173 21.04l.846 3.146 9.536-2.546Z\" />\n    </svg>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/notification-menu.tsx",
          "type": "registry:component",
          "target": "components/ui/notification-menu.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Button, Popover, PopoverContent, PopoverTrigger } from '@timui/react'\nimport { BellIcon } from 'lucide-react'\n\nconst initialNotifications = [\n  {\n    id: 1,\n    user: 'Chris Tompson',\n    action: 'requested review on',\n    target: 'PR #42: Feature implementation',\n    timestamp: '15 minutes ago',\n    unread: true,\n  },\n  {\n    id: 2,\n    user: 'Emma Davis',\n    action: 'shared',\n    target: 'New component library',\n    timestamp: '45 minutes ago',\n    unread: true,\n  },\n  {\n    id: 3,\n    user: 'James Wilson',\n    action: 'assigned you to',\n    target: 'API integration task',\n    timestamp: '4 hours ago',\n    unread: false,\n  },\n  {\n    id: 4,\n    user: 'Alex Morgan',\n    action: 'replied to your comment in',\n    target: 'Authentication flow',\n    timestamp: '12 hours ago',\n    unread: false,\n  },\n  {\n    id: 5,\n    user: 'Sarah Chen',\n    action: 'commented on',\n    target: 'Dashboard redesign',\n    timestamp: '2 days ago',\n    unread: false,\n  },\n  {\n    id: 6,\n    user: 'Miky Derya',\n    action: 'mentioned you in',\n    target: 'Timkit UI open graph image',\n    timestamp: '2 weeks ago',\n    unread: false,\n  },\n]\n\nfunction Dot({ className }: { className?: string }) {\n  return (\n    <svg\n      width=\"6\"\n      height=\"6\"\n      fill=\"currentColor\"\n      viewBox=\"0 0 6 6\"\n      xmlns=\"http://www.w3.org/2000/svg\"\n      className={className}\n      aria-hidden=\"true\"\n    >\n      <circle cx=\"3\" cy=\"3\" r=\"3\" />\n    </svg>\n  )\n}\n\nexport default function NotificationMenu() {\n  const [notifications, setNotifications] = useState(initialNotifications)\n  const unreadCount = notifications.filter((n) => n.unread).length\n\n  const handleMarkAllAsRead = () => {\n    setNotifications(\n      notifications.map((notification) => ({\n        ...notification,\n        unread: false,\n      }))\n    )\n  }\n\n  const handleNotificationClick = (id: number) => {\n    setNotifications(\n      notifications.map((notification) =>\n        notification.id === id ? { ...notification, unread: false } : notification\n      )\n    )\n  }\n\n  return (\n    <Popover>\n      <PopoverTrigger asChild>\n        <Button\n          size=\"icon\"\n          variant=\"ghost\"\n          className=\"text-muted-foreground relative size-8 rounded-full shadow-none\"\n          aria-label=\"Open notifications\"\n        >\n          <BellIcon size={16} aria-hidden=\"true\" />\n          {unreadCount > 0 && (\n            <div\n              aria-hidden=\"true\"\n              className=\"bg-primary absolute top-0.5 right-0.5 size-1 rounded-full\"\n            />\n          )}\n        </Button>\n      </PopoverTrigger>\n      <PopoverContent className=\"w-80 p-1\">\n        <div className=\"flex items-baseline justify-between gap-4 px-3 py-2\">\n          <div className=\"text-sm font-semibold\">Notifications</div>\n          {unreadCount > 0 && (\n            <button className=\"text-xs font-medium hover:underline\" onClick={handleMarkAllAsRead}>\n              Mark all as read\n            </button>\n          )}\n        </div>\n        <div\n          role=\"separator\"\n          aria-orientation=\"horizontal\"\n          className=\"bg-border -mx-1 my-1 h-px\"\n        ></div>\n        {notifications.map((notification) => (\n          <div\n            key={notification.id}\n            className=\"hover:bg-accent rounded-md px-3 py-2 text-sm transition-colors\"\n          >\n            <div className=\"relative flex items-start pe-3\">\n              <div className=\"flex-1 space-y-1\">\n                <button\n                  className=\"text-foreground/80 text-left after:absolute after:inset-0\"\n                  onClick={() => handleNotificationClick(notification.id)}\n                >\n                  <span className=\"text-foreground font-medium hover:underline\">\n                    {notification.user}\n                  </span>{' '}\n                  {notification.action}{' '}\n                  <span className=\"text-foreground font-medium hover:underline\">\n                    {notification.target}\n                  </span>\n                  .\n                </button>\n                <div className=\"text-muted-foreground text-xs\">{notification.timestamp}</div>\n              </div>\n              {notification.unread && (\n                <div className=\"absolute end-0 self-center\">\n                  <span className=\"sr-only\">Unread</span>\n                  <Dot />\n                </div>\n              )}\n            </div>\n          </div>\n        ))}\n      </PopoverContent>\n    </Popover>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/user-menu.tsx",
          "type": "registry:component",
          "target": "components/ui/user-menu.tsx",
          "content": "import {\n  Avatar,\n  AvatarFallback,\n  AvatarImage,\n  Button,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from '@timui/react'\nimport { BoltIcon, BookOpenIcon, Layers2Icon, LogOutIcon, PinIcon, UserPenIcon } from 'lucide-react'\n\nexport default function UserMenu() {\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button variant=\"ghost\" className=\"h-auto p-0 hover:bg-transparent\">\n          <Avatar>\n            <AvatarImage src=\"./avatar.jpg\" alt=\"Profile image\" />\n            <AvatarFallback>KK</AvatarFallback>\n          </Avatar>\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent className=\"max-w-64\" align=\"end\">\n        <DropdownMenuLabel className=\"flex min-w-0 flex-col\">\n          <span className=\"text-foreground truncate text-sm font-medium\">Keith Kennedy</span>\n          <span className=\"text-muted-foreground truncate text-xs font-normal\">\n            k.kennedy@ui.timkit.cn\n          </span>\n        </DropdownMenuLabel>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <BoltIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 1</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <Layers2Icon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 2</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <BookOpenIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 3</span>\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <PinIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 4</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <UserPenIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 5</span>\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuItem>\n          <LogOutIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n          <span>Logout</span>\n        </DropdownMenuItem>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-07.vue",
          "target": "components/ui/navbar-07.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { ChevronsUpDown } from 'lucide-vue-next';\nimport { Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbSeparator } from '@timui/vue';\nimport { Button } from '@timui/vue';\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@timui/vue';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/vue';\nimport Logo from '@/registry/default/components/navbar-components/logo.vue';\nimport NotificationMenu from '@/registry/default/components/navbar-components/notification-menu.vue';\nimport UserMenu from '@/registry/default/components/navbar-components/user-menu.vue';\n\nconst projectValue = ref('1');\n\n</script>\n\n<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 items-center justify-between gap-4\"><div class=\"flex items-center gap-2\"><Breadcrumb><BreadcrumbList><BreadcrumbItem><BreadcrumbLink href=\"#\" class=\"text-foreground\"><Logo /></BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator>/ </BreadcrumbSeparator><BreadcrumbItem class=\"md:hidden\"><DropdownMenu><DropdownMenuTrigger class=\"hover:text-foreground\"><BreadcrumbEllipsis /><span class=\"sr-only\">Toggle menu</span></DropdownMenuTrigger><DropdownMenuContent align=\"start\"><DropdownMenuItem as-child><a href=\"#\">Personal Account</a></DropdownMenuItem><DropdownMenuItem as-child><a href=\"#\">Projects</a></DropdownMenuItem></DropdownMenuContent></DropdownMenu></BreadcrumbItem><BreadcrumbItem class=\"max-md:hidden\"><BreadcrumbLink href=\"#\">Personal Account</BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator class=\"max-md:hidden\">/ </BreadcrumbSeparator><BreadcrumbItem class=\"max-md:hidden\"><BreadcrumbLink href=\"#\">Projects</BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator>/ </BreadcrumbSeparator><BreadcrumbItem><Select v-model=\"projectValue\"><SelectTrigger aria-label=\"Select project\" as-child><Button variant=\"ghost\" class=\"focus-visible:bg-accent text-foreground h-8 px-1.5 focus-visible:ring-0\"><SelectValue placeholder=\"Select project\" /><ChevronsUpDown :size=\"14\" class=\"text-muted-foreground/80\" /></Button></SelectTrigger><SelectContent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\"><SelectItem value=\"1\">Main project</SelectItem><SelectItem value=\"2\">Origin project</SelectItem></SelectContent></Select></BreadcrumbItem></BreadcrumbList></Breadcrumb></div><div class=\"flex items-center gap-4\"><NotificationMenu /><UserMenu /></div></div></header>\n</template>\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-07.html",
          "target": "components/ui/navbar-07.html",
          "type": "registry:component",
          "content": "<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 items-center justify-between gap-4\"><div class=\"flex items-center gap-2\"><Breadcrumb><BreadcrumbList><BreadcrumbItem><BreadcrumbLink href=\"#\" class=\"text-foreground\"><Logo /></BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator>/ </BreadcrumbSeparator><BreadcrumbItem class=\"md:hidden\"><DropdownMenu><DropdownMenuTrigger class=\"hover:text-foreground\"><BreadcrumbEllipsis /><span class=\"sr-only\">Toggle menu</span></DropdownMenuTrigger><DropdownMenuContent align=\"start\"><DropdownMenuItem aschild><a href=\"#\">Personal Account</a></DropdownMenuItem><DropdownMenuItem aschild><a href=\"#\">Projects</a></DropdownMenuItem></DropdownMenuContent></DropdownMenu></BreadcrumbItem><BreadcrumbItem class=\"max-md:hidden\"><BreadcrumbLink href=\"#\">Personal Account</BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator class=\"max-md:hidden\">/ </BreadcrumbSeparator><BreadcrumbItem class=\"max-md:hidden\"><BreadcrumbLink href=\"#\">Projects</BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator>/ </BreadcrumbSeparator><BreadcrumbItem><Select default-value=\"1\"><SelectTrigger aria-label=\"Select project\" aschild><Button variant=\"ghost\" class=\"focus-visible:bg-accent text-foreground h-8 px-1.5 focus-visible:ring-0\"><SelectValue placeholder=\"Select project\" /><ChevronsUpDown size=\"${14}\" class=\"text-muted-foreground/80\" /></Button></SelectTrigger><SelectContent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\"><SelectItem value=\"1\">Main project</SelectItem><SelectItem value=\"2\">Origin project</SelectItem></SelectContent></Select></BreadcrumbItem></BreadcrumbList></Breadcrumb></div><div class=\"flex items-center gap-4\"><NotificationMenu /><UserMenu /></div></div></header>\n</template>"
        },
        {
          "path": "registry/default/components/navbar/navbar-07.wxml",
          "target": "components/ui/navbar-07/navbar-07.wxml",
          "type": "registry:component",
          "content": "<view>\n  <header class=\"border-b px-4 md:px-6\"><view class=\"flex h-16 items-center justify-between gap-4\"><view class=\"flex items-center gap-2\"><breadcrumb><breadcrumblist><breadcrumbitem><breadcrumblink href=\"#\" class=\"text-foreground\"><logo /></breadcrumblink></breadcrumbitem><breadcrumbseparator>/ </breadcrumbseparator><breadcrumbitem class=\"md:hidden\"><dropdownmenu><dropdownmenutrigger class=\"hover:text-foreground\"><breadcrumbellipsis /><text class=\"sr-only\">Toggle menu</text></dropdownmenutrigger><dropdownmenucontent align=\"start\"><dropdownmenuitem aschild><a href=\"#\">Personal Account</a></dropdownmenuitem><dropdownmenuitem aschild><a href=\"#\">Projects</a></dropdownmenuitem></dropdownmenucontent></dropdownmenu></breadcrumbitem><breadcrumbitem class=\"max-md:hidden\"><breadcrumblink href=\"#\">Personal Account</breadcrumblink></breadcrumbitem><breadcrumbseparator class=\"max-md:hidden\">/ </breadcrumbseparator><breadcrumbitem class=\"max-md:hidden\"><breadcrumblink href=\"#\">Projects</breadcrumblink></breadcrumbitem><breadcrumbseparator>/ </breadcrumbseparator><breadcrumbitem><select default-value=\"1\"><selecttrigger aria-label=\"Select project\" aschild><button variant=\"ghost\" class=\"focus-visible:bg-accent text-foreground h-8 px-1.5 focus-visible:ring-0\"><selectvalue placeholder=\"Select project\" /><chevronsupdown size=\"{{14}}\" class=\"text-muted-foreground/80\" /></button></selecttrigger><selectcontent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\"><selectitem value=\"1\">Main project</selectitem><selectitem value=\"2\">Origin project</selectitem></selectcontent></select></breadcrumbitem></breadcrumblist></breadcrumb></view><view class=\"flex items-center gap-4\"><notificationmenu /><usermenu /></view></view></header>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "navbar, navigation"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "navbar-07",
          "group": "navbar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "navbar-07",
              "path": "registry/default/components/navbar/navbar-07.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "navbar-07",
              "path": "registry/default/components/navbar/navbar-07.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "navbar-07",
              "path": "registry/default/components/navbar/navbar-07.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "navbar-07",
              "path": "registry/default/components/navbar/navbar-07.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "navbars",
        "title": "Navbar · Select project"
      },
      "categories": [
        "navbars",
        "navbar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "navbar-08",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/avatar.json",
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dropdown-menu.json",
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/navigation-menu.json",
        "https://ui.timkit.cn/r/popover.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/navbar/navbar-08.tsx",
          "type": "registry:component",
          "target": "components/ui/navbar-08.tsx",
          "content": "import { useId } from 'react'\nimport {\n  Button,\n  Input,\n  NavigationMenu,\n  NavigationMenuItem,\n  NavigationMenuLink,\n  NavigationMenuList,\n  Popover,\n  PopoverContent,\n  PopoverTrigger,\n} from '@timui/react'\nimport { SearchIcon } from 'lucide-react'\n\nimport Logo from '@/registry/default/components/navbar-components/logo'\nimport NotificationMenu from '@/registry/default/components/navbar-components/notification-menu'\nimport UserMenu from '@/registry/default/components/navbar-components/user-menu'\n\n// Navigation links array to be used in both desktop and mobile menus\nconst navigationLinks = [\n  { href: '#', label: 'Home', active: true },\n  { href: '#', label: 'Features' },\n  { href: '#', label: 'Pricing' },\n  { href: '#', label: 'About' },\n]\n\nexport default function Component() {\n  const id = useId()\n\n  return (\n    <header className=\"border-b px-4 md:px-6\">\n      <div className=\"flex h-16 items-center justify-between gap-4\">\n        {/* Left side */}\n        <div className=\"flex flex-1 items-center gap-2\">\n          {/* Mobile menu trigger */}\n          <Popover>\n            <PopoverTrigger asChild>\n              <Button className=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\">\n                <svg\n                  className=\"pointer-events-none\"\n                  width={16}\n                  height={16}\n                  viewBox=\"0 0 24 24\"\n                  fill=\"none\"\n                  stroke=\"currentColor\"\n                  strokeWidth=\"2\"\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  xmlns=\"http://www.w3.org/2000/svg\"\n                >\n                  <path\n                    d=\"M4 12L20 12\"\n                    className=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\"\n                  />\n                  <path\n                    d=\"M4 12H20\"\n                    className=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\"\n                  />\n                  <path\n                    d=\"M4 12H20\"\n                    className=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\"\n                  />\n                </svg>\n              </Button>\n            </PopoverTrigger>\n            <PopoverContent align=\"start\" className=\"w-36 p-1 md:hidden\">\n              <NavigationMenu className=\"max-w-none *:w-full\">\n                <NavigationMenuList className=\"flex-col items-start gap-0 md:gap-2\">\n                  {navigationLinks.map((link, index) => (\n                    <NavigationMenuItem key={index} className=\"w-full\">\n                      <NavigationMenuLink href={link.href} className=\"py-1.5\" active={link.active}>\n                        {link.label}\n                      </NavigationMenuLink>\n                    </NavigationMenuItem>\n                  ))}\n                </NavigationMenuList>\n              </NavigationMenu>\n            </PopoverContent>\n          </Popover>\n          {/* Logo */}\n          <div className=\"flex items-center\">\n            <a href=\"#\" className=\"text-primary hover:text-primary/90\">\n              <Logo />\n            </a>\n          </div>\n        </div>\n        {/* Middle area */}\n        <div className=\"grow\">\n          {/* Search form */}\n          <div className=\"relative mx-auto w-full max-w-xs\">\n            <Input id={id} className=\"peer h-8 ps-8 pe-10\" placeholder=\"Search...\" type=\"search\" />\n            <div className=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-2 peer-disabled:opacity-50\">\n              <SearchIcon size={16} />\n            </div>\n            <div className=\"text-muted-foreground pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-2\">\n              <kbd className=\"text-muted-foreground/70 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">\n                ⌘K\n              </kbd>\n            </div>\n          </div>\n        </div>\n        {/* Right side */}\n        <div className=\"flex flex-1 items-center justify-end gap-2\">\n          {/* Notification */}\n          <NotificationMenu />\n          {/* User menu */}\n          <UserMenu />\n        </div>\n      </div>\n      {/* Bottom navigation */}\n      <div className=\"border-t py-2 max-md:hidden\">\n        {/* Navigation menu */}\n        <NavigationMenu>\n          <NavigationMenuList className=\"gap-2\">\n            {navigationLinks.map((link, index) => (\n              <NavigationMenuItem key={index}>\n                <NavigationMenuLink\n                  active={link.active}\n                  href={link.href}\n                  className=\"text-muted-foreground hover:text-primary py-1.5 font-medium\"\n                >\n                  {link.label}\n                </NavigationMenuLink>\n              </NavigationMenuItem>\n            ))}\n          </NavigationMenuList>\n        </NavigationMenu>\n      </div>\n    </header>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/logo.tsx",
          "type": "registry:component",
          "target": "components/ui/logo.tsx",
          "content": "export default function Logo() {\n  return (\n    <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"33\" height=\"33\" fill=\"currentColor\">\n      <path d=\"M20.46 1.766 17.303.923l-2.66 9.896-2.403-8.934-3.157.843 2.595 9.652-6.464-6.442-2.311 2.304 7.09 7.066-8.83-2.358-.846 3.146 9.648 2.577a6.516 6.516 0 0 1-.169-1.478c0-3.598 2.927-6.515 6.537-6.515s6.537 2.917 6.537 6.515c0 .505-.057.997-.167 1.468l8.768 2.342.846-3.147-9.686-2.586 8.83-2.358-.845-3.147-9.686 2.587 6.464-6.442-2.311-2.304-6.992 6.969 2.369-8.81Z\" />\n      <path d=\"M22.695 18.7a6.495 6.495 0 0 1-1.626 2.986l6.352 6.33 2.31-2.303-7.036-7.013ZM21.005 21.752a6.538 6.538 0 0 1-2.922 1.722l2.312 8.596 3.157-.843-2.547-9.475ZM17.965 23.505a6.569 6.569 0 0 1-1.632.205 6.566 6.566 0 0 1-1.743-.235l-2.314 8.605 3.157.843 2.532-9.418ZM14.478 23.444a6.54 6.54 0 0 1-2.87-1.747l-6.367 6.346 2.31 2.303 6.927-6.902ZM11.555 21.64a6.492 6.492 0 0 1-1.585-2.948L1.173 21.04l.846 3.146 9.536-2.546Z\" />\n    </svg>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/notification-menu.tsx",
          "type": "registry:component",
          "target": "components/ui/notification-menu.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Button, Popover, PopoverContent, PopoverTrigger } from '@timui/react'\nimport { BellIcon } from 'lucide-react'\n\nconst initialNotifications = [\n  {\n    id: 1,\n    user: 'Chris Tompson',\n    action: 'requested review on',\n    target: 'PR #42: Feature implementation',\n    timestamp: '15 minutes ago',\n    unread: true,\n  },\n  {\n    id: 2,\n    user: 'Emma Davis',\n    action: 'shared',\n    target: 'New component library',\n    timestamp: '45 minutes ago',\n    unread: true,\n  },\n  {\n    id: 3,\n    user: 'James Wilson',\n    action: 'assigned you to',\n    target: 'API integration task',\n    timestamp: '4 hours ago',\n    unread: false,\n  },\n  {\n    id: 4,\n    user: 'Alex Morgan',\n    action: 'replied to your comment in',\n    target: 'Authentication flow',\n    timestamp: '12 hours ago',\n    unread: false,\n  },\n  {\n    id: 5,\n    user: 'Sarah Chen',\n    action: 'commented on',\n    target: 'Dashboard redesign',\n    timestamp: '2 days ago',\n    unread: false,\n  },\n  {\n    id: 6,\n    user: 'Miky Derya',\n    action: 'mentioned you in',\n    target: 'Timkit UI open graph image',\n    timestamp: '2 weeks ago',\n    unread: false,\n  },\n]\n\nfunction Dot({ className }: { className?: string }) {\n  return (\n    <svg\n      width=\"6\"\n      height=\"6\"\n      fill=\"currentColor\"\n      viewBox=\"0 0 6 6\"\n      xmlns=\"http://www.w3.org/2000/svg\"\n      className={className}\n      aria-hidden=\"true\"\n    >\n      <circle cx=\"3\" cy=\"3\" r=\"3\" />\n    </svg>\n  )\n}\n\nexport default function NotificationMenu() {\n  const [notifications, setNotifications] = useState(initialNotifications)\n  const unreadCount = notifications.filter((n) => n.unread).length\n\n  const handleMarkAllAsRead = () => {\n    setNotifications(\n      notifications.map((notification) => ({\n        ...notification,\n        unread: false,\n      }))\n    )\n  }\n\n  const handleNotificationClick = (id: number) => {\n    setNotifications(\n      notifications.map((notification) =>\n        notification.id === id ? { ...notification, unread: false } : notification\n      )\n    )\n  }\n\n  return (\n    <Popover>\n      <PopoverTrigger asChild>\n        <Button\n          size=\"icon\"\n          variant=\"ghost\"\n          className=\"text-muted-foreground relative size-8 rounded-full shadow-none\"\n          aria-label=\"Open notifications\"\n        >\n          <BellIcon size={16} aria-hidden=\"true\" />\n          {unreadCount > 0 && (\n            <div\n              aria-hidden=\"true\"\n              className=\"bg-primary absolute top-0.5 right-0.5 size-1 rounded-full\"\n            />\n          )}\n        </Button>\n      </PopoverTrigger>\n      <PopoverContent className=\"w-80 p-1\">\n        <div className=\"flex items-baseline justify-between gap-4 px-3 py-2\">\n          <div className=\"text-sm font-semibold\">Notifications</div>\n          {unreadCount > 0 && (\n            <button className=\"text-xs font-medium hover:underline\" onClick={handleMarkAllAsRead}>\n              Mark all as read\n            </button>\n          )}\n        </div>\n        <div\n          role=\"separator\"\n          aria-orientation=\"horizontal\"\n          className=\"bg-border -mx-1 my-1 h-px\"\n        ></div>\n        {notifications.map((notification) => (\n          <div\n            key={notification.id}\n            className=\"hover:bg-accent rounded-md px-3 py-2 text-sm transition-colors\"\n          >\n            <div className=\"relative flex items-start pe-3\">\n              <div className=\"flex-1 space-y-1\">\n                <button\n                  className=\"text-foreground/80 text-left after:absolute after:inset-0\"\n                  onClick={() => handleNotificationClick(notification.id)}\n                >\n                  <span className=\"text-foreground font-medium hover:underline\">\n                    {notification.user}\n                  </span>{' '}\n                  {notification.action}{' '}\n                  <span className=\"text-foreground font-medium hover:underline\">\n                    {notification.target}\n                  </span>\n                  .\n                </button>\n                <div className=\"text-muted-foreground text-xs\">{notification.timestamp}</div>\n              </div>\n              {notification.unread && (\n                <div className=\"absolute end-0 self-center\">\n                  <span className=\"sr-only\">Unread</span>\n                  <Dot />\n                </div>\n              )}\n            </div>\n          </div>\n        ))}\n      </PopoverContent>\n    </Popover>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/user-menu.tsx",
          "type": "registry:component",
          "target": "components/ui/user-menu.tsx",
          "content": "import {\n  Avatar,\n  AvatarFallback,\n  AvatarImage,\n  Button,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from '@timui/react'\nimport { BoltIcon, BookOpenIcon, Layers2Icon, LogOutIcon, PinIcon, UserPenIcon } from 'lucide-react'\n\nexport default function UserMenu() {\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button variant=\"ghost\" className=\"h-auto p-0 hover:bg-transparent\">\n          <Avatar>\n            <AvatarImage src=\"./avatar.jpg\" alt=\"Profile image\" />\n            <AvatarFallback>KK</AvatarFallback>\n          </Avatar>\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent className=\"max-w-64\" align=\"end\">\n        <DropdownMenuLabel className=\"flex min-w-0 flex-col\">\n          <span className=\"text-foreground truncate text-sm font-medium\">Keith Kennedy</span>\n          <span className=\"text-muted-foreground truncate text-xs font-normal\">\n            k.kennedy@ui.timkit.cn\n          </span>\n        </DropdownMenuLabel>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <BoltIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 1</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <Layers2Icon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 2</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <BookOpenIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 3</span>\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <PinIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 4</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <UserPenIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 5</span>\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuItem>\n          <LogOutIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n          <span>Logout</span>\n        </DropdownMenuItem>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-08.vue",
          "target": "components/ui/navbar-08.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { SearchIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { Input } from '@timui/vue';\nimport { NavigationMenu, NavigationMenuItem, NavigationMenuLink, NavigationMenuList } from '@timui/vue';\nimport { Popover, PopoverContent, PopoverTrigger } from '@timui/vue';\nimport Logo from '@/registry/default/components/navbar-components/logo.vue';\nimport NotificationMenu from '@/registry/default/components/navbar-components/notification-menu.vue';\nimport UserMenu from '@/registry/default/components/navbar-components/user-menu.vue';\n\nconst navigationLinks = [\n  { href: '#', label: 'Home', active: true },\n  { href: '#', label: 'Features' },\n  { href: '#', label: 'Pricing' },\n  { href: '#', label: 'About' },\n];\n\n\nconst id = 'navbar-08';\n\n</script>\n\n<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 items-center justify-between gap-4\"><div class=\"flex flex-1 items-center gap-2\"><Popover><PopoverTrigger as-child><Button class=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\"><svg class=\"pointer-events-none\" :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></Button></PopoverTrigger><PopoverContent align=\"start\" class=\"w-36 p-1 md:hidden\"><NavigationMenu class=\"max-w-none *:w-full\"><NavigationMenuList class=\"flex-col items-start gap-0 md:gap-2\"><NavigationMenuItem v-for=\"(link, index) in navigationLinks\" :key=\"index\" class=\"w-full\"><NavigationMenuLink :href=\"link.href\" class=\"py-1.5\" :active=\"link.active\">{{ link.label }}</NavigationMenuLink></NavigationMenuItem></NavigationMenuList></NavigationMenu></PopoverContent></Popover><div class=\"flex items-center\"><a href=\"#\" class=\"text-primary hover:text-primary/90\"><Logo /></a></div></div><div class=\"grow\"><div class=\"relative mx-auto w-full max-w-xs\"><Input :id=\"id\" class=\"peer h-8 ps-8 pe-10\" placeholder=\"Search...\" type=\"search\" /><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-2 peer-disabled:opacity-50\"><SearchIcon :size=\"16\" /></div><div class=\"text-muted-foreground pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-2\"><kbd class=\"text-muted-foreground/70 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">⌘K\n              </kbd></div></div></div><div class=\"flex flex-1 items-center justify-end gap-2\"><NotificationMenu /><UserMenu /></div></div><div class=\"border-t py-2 max-md:hidden\"><NavigationMenu><NavigationMenuList class=\"gap-2\"><NavigationMenuItem v-for=\"(link, index) in navigationLinks\" :key=\"index\"><NavigationMenuLink :active=\"link.active\" :href=\"link.href\" class=\"text-muted-foreground hover:text-primary py-1.5 font-medium\">{{ link.label }}</NavigationMenuLink></NavigationMenuItem></NavigationMenuList></NavigationMenu></div></header>\n</template>\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-08.html",
          "target": "components/ui/navbar-08.html",
          "type": "registry:component",
          "content": "<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 items-center justify-between gap-4\"><div class=\"flex flex-1 items-center gap-2\"><Popover><PopoverTrigger aschild><Button class=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\"><svg class=\"pointer-events-none\" width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></Button></PopoverTrigger><PopoverContent align=\"start\" class=\"w-36 p-1 md:hidden\"><NavigationMenu class=\"max-w-none *:w-full\"><NavigationMenuList class=\"flex-col items-start gap-0 md:gap-2\"><!-- Loop navigationLinks -->\n<NavigationMenuItem key=\"${index}\" class=\"w-full\"><NavigationMenuLink href=\"${link.href}\" class=\"py-1.5\" active=\"${link.active}\">${link.label}</NavigationMenuLink></NavigationMenuItem>\n<!-- End Loop --></NavigationMenuList></NavigationMenu></PopoverContent></Popover><div class=\"flex items-center\"><a href=\"#\" class=\"text-primary hover:text-primary/90\"><Logo /></a></div></div><div class=\"grow\"><div class=\"relative mx-auto w-full max-w-xs\"><Input id=\"${id}\" class=\"peer h-8 ps-8 pe-10\" placeholder=\"Search...\" type=\"search\" /><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-2 peer-disabled:opacity-50\"><SearchIcon size=\"${16}\" /></div><div class=\"text-muted-foreground pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-2\"><kbd class=\"text-muted-foreground/70 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">⌘K\n              </kbd></div></div></div><div class=\"flex flex-1 items-center justify-end gap-2\"><NotificationMenu /><UserMenu /></div></div><div class=\"border-t py-2 max-md:hidden\"><NavigationMenu><NavigationMenuList class=\"gap-2\"><!-- Loop navigationLinks -->\n<NavigationMenuItem key=\"${index}\"><NavigationMenuLink active=\"${link.active}\" href=\"${link.href}\" class=\"text-muted-foreground hover:text-primary py-1.5 font-medium\">${link.label}</NavigationMenuLink></NavigationMenuItem>\n<!-- End Loop --></NavigationMenuList></NavigationMenu></div></header>\n</template>"
        },
        {
          "path": "registry/default/components/navbar/navbar-08.wxml",
          "target": "components/ui/navbar-08/navbar-08.wxml",
          "type": "registry:component",
          "content": "<view>\n  <header class=\"border-b px-4 md:px-6\"><view class=\"flex h-16 items-center justify-between gap-4\"><view class=\"flex flex-1 items-center gap-2\"><popover><popovertrigger aschild><button class=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\"><svg class=\"pointer-events-none\" width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></button></popovertrigger><popovercontent align=\"start\" class=\"w-36 p-1 md:hidden\"><navigationmenu class=\"max-w-none *:w-full\"><navigationmenulist class=\"flex-col items-start gap-0 md:gap-2\"><navigationmenuitem wx:for=\"{{navigationLinks}}\" wx:for-item=\"link\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{index}}\" class=\"w-full\"><navigationmenulink href=\"{{link.href}}\" class=\"py-1.5\" active=\"{{link.active}}\">{{ link.label }}</navigationmenulink></navigationmenuitem></navigationmenulist></navigationmenu></popovercontent></popover><view class=\"flex items-center\"><a href=\"#\" class=\"text-primary hover:text-primary/90\"><logo /></a></view></view><view class=\"grow\"><view class=\"relative mx-auto w-full max-w-xs\"><input id=\"{{id}}\" class=\"peer h-8 ps-8 pe-10\" placeholder=\"Search...\" type=\"search\" /><view class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-2 peer-disabled:opacity-50\"><searchicon size=\"{{16}}\" /></view><view class=\"text-muted-foreground pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-2\"><kbd class=\"text-muted-foreground/70 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\">⌘K\n              </kbd></view></view></view><view class=\"flex flex-1 items-center justify-end gap-2\"><notificationmenu /><usermenu /></view></view><view class=\"border-t py-2 max-md:hidden\"><navigationmenu><navigationmenulist class=\"gap-2\"><navigationmenuitem wx:for=\"{{navigationLinks}}\" wx:for-item=\"link\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{index}}\"><navigationmenulink active=\"{{link.active}}\" href=\"{{link.href}}\" class=\"text-muted-foreground hover:text-primary py-1.5 font-medium\">{{ link.label }}</navigationmenulink></navigationmenuitem></navigationmenulist></navigationmenu></view></header>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "navbar, navigation"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "navbar-08",
          "group": "navbar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "navbar-08",
              "path": "registry/default/components/navbar/navbar-08.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "navbar-08",
              "path": "registry/default/components/navbar/navbar-08.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "navbar-08",
              "path": "registry/default/components/navbar/navbar-08.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "navbar-08",
              "path": "registry/default/components/navbar/navbar-08.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "navbars",
        "title": "Navbar · Disabled State"
      },
      "categories": [
        "navbars",
        "navbar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "navbar-09",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/avatar.json",
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dropdown-menu.json",
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/navigation-menu.json",
        "https://ui.timkit.cn/r/popover.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/navbar/navbar-09.tsx",
          "type": "registry:component",
          "target": "components/ui/navbar-09.tsx",
          "content": "import { useId } from 'react'\nimport {\n  Button,\n  Input,\n  NavigationMenu,\n  NavigationMenuItem,\n  NavigationMenuLink,\n  NavigationMenuList,\n  Popover,\n  PopoverContent,\n  PopoverTrigger,\n} from '@timui/react'\nimport { HashIcon, HouseIcon, MailIcon, SearchIcon, UsersRound } from 'lucide-react'\n\nimport Logo from '@/registry/default/components/navbar-components/logo'\nimport NotificationMenu from '@/registry/default/components/navbar-components/notification-menu'\nimport UserMenu from '@/registry/default/components/navbar-components/user-menu'\n\nconst teams = ['Acme Inc.', 'Timkit UI', 'Junon']\n\n// Navigation links array to be used in both desktop and mobile menus\nconst navigationLinks = [\n  { href: '#', label: 'Home', icon: HouseIcon },\n  { href: '#', label: 'Hash', icon: HashIcon },\n  { href: '#', label: 'Groups', icon: UsersRound },\n]\n\nexport default function Component() {\n  const id = useId()\n\n  return (\n    <header className=\"border-b px-4 md:px-6\">\n      <div className=\"flex h-16 items-center justify-between gap-4\">\n        {/* Left side */}\n        <div className=\"flex flex-1 items-center gap-2\">\n          {/* Mobile menu trigger */}\n          <Popover>\n            <PopoverTrigger asChild>\n              <Button className=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\">\n                <svg\n                  className=\"pointer-events-none\"\n                  width={16}\n                  height={16}\n                  viewBox=\"0 0 24 24\"\n                  fill=\"none\"\n                  stroke=\"currentColor\"\n                  strokeWidth=\"2\"\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  xmlns=\"http://www.w3.org/2000/svg\"\n                >\n                  <path\n                    d=\"M4 12L20 12\"\n                    className=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\"\n                  />\n                  <path\n                    d=\"M4 12H20\"\n                    className=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\"\n                  />\n                  <path\n                    d=\"M4 12H20\"\n                    className=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\"\n                  />\n                </svg>\n              </Button>\n            </PopoverTrigger>\n            <PopoverContent align=\"start\" className=\"w-48 p-1 md:hidden\">\n              <NavigationMenu className=\"max-w-none *:w-full\">\n                <NavigationMenuList className=\"flex-col items-start gap-0 md:gap-2\">\n                  {navigationLinks.map((link, index) => {\n                    const Icon = link.icon\n                    return (\n                      <NavigationMenuItem key={index} className=\"w-full\">\n                        <NavigationMenuLink\n                          href={link.href}\n                          className=\"flex-row items-center gap-2 py-1.5\"\n                        >\n                          <Icon size={16} className=\"text-muted-foreground\" aria-hidden=\"true\" />\n                          <span>{link.label}</span>\n                        </NavigationMenuLink>\n                      </NavigationMenuItem>\n                    )\n                  })}\n                </NavigationMenuList>\n              </NavigationMenu>\n            </PopoverContent>\n          </Popover>\n          <div className=\"flex items-center gap-6\">\n            <a href=\"#\" className=\"text-primary hover:text-primary/90\">\n              <Logo />\n            </a>\n            {/* Search form */}\n            <div className=\"relative\">\n              <Input id={id} className=\"peer h-8 ps-8 pe-2\" placeholder=\"Search...\" type=\"search\" />\n              <div className=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-2 peer-disabled:opacity-50\">\n                <SearchIcon size={16} />\n              </div>\n            </div>\n          </div>\n        </div>\n        {/* Middle area */}\n        <NavigationMenu className=\"max-md:hidden\">\n          <NavigationMenuList className=\"gap-2\">\n            {navigationLinks.map((link, index) => {\n              const Icon = link.icon\n              return (\n                <NavigationMenuItem key={index}>\n                  <NavigationMenuLink\n                    href={link.href}\n                    className=\"flex size-8 items-center justify-center p-1.5\"\n                    title={link.label}\n                  >\n                    <Icon aria-hidden=\"true\" />\n                    <span className=\"sr-only\">{link.label}</span>\n                  </NavigationMenuLink>\n                </NavigationMenuItem>\n              )\n            })}\n          </NavigationMenuList>\n        </NavigationMenu>\n        {/* Right side */}\n        <div className=\"flex flex-1 items-center justify-end gap-4\">\n          <div className=\"flex items-center gap-2\">\n            {/* Messages */}\n            <Button\n              size=\"icon\"\n              variant=\"ghost\"\n              className=\"text-muted-foreground relative size-8 rounded-full shadow-none\"\n              aria-label=\"Open notifications\"\n            >\n              <MailIcon size={16} aria-hidden=\"true\" />\n              <div\n                aria-hidden=\"true\"\n                className=\"bg-primary absolute top-0.5 right-0.5 size-1 rounded-full\"\n              />\n            </Button>\n            {/* Notification menu */}\n            <NotificationMenu />\n          </div>\n          {/* User menu */}\n          <UserMenu />\n        </div>\n      </div>\n    </header>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/logo.tsx",
          "type": "registry:component",
          "target": "components/ui/logo.tsx",
          "content": "export default function Logo() {\n  return (\n    <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"33\" height=\"33\" fill=\"currentColor\">\n      <path d=\"M20.46 1.766 17.303.923l-2.66 9.896-2.403-8.934-3.157.843 2.595 9.652-6.464-6.442-2.311 2.304 7.09 7.066-8.83-2.358-.846 3.146 9.648 2.577a6.516 6.516 0 0 1-.169-1.478c0-3.598 2.927-6.515 6.537-6.515s6.537 2.917 6.537 6.515c0 .505-.057.997-.167 1.468l8.768 2.342.846-3.147-9.686-2.586 8.83-2.358-.845-3.147-9.686 2.587 6.464-6.442-2.311-2.304-6.992 6.969 2.369-8.81Z\" />\n      <path d=\"M22.695 18.7a6.495 6.495 0 0 1-1.626 2.986l6.352 6.33 2.31-2.303-7.036-7.013ZM21.005 21.752a6.538 6.538 0 0 1-2.922 1.722l2.312 8.596 3.157-.843-2.547-9.475ZM17.965 23.505a6.569 6.569 0 0 1-1.632.205 6.566 6.566 0 0 1-1.743-.235l-2.314 8.605 3.157.843 2.532-9.418ZM14.478 23.444a6.54 6.54 0 0 1-2.87-1.747l-6.367 6.346 2.31 2.303 6.927-6.902ZM11.555 21.64a6.492 6.492 0 0 1-1.585-2.948L1.173 21.04l.846 3.146 9.536-2.546Z\" />\n    </svg>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/notification-menu.tsx",
          "type": "registry:component",
          "target": "components/ui/notification-menu.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Button, Popover, PopoverContent, PopoverTrigger } from '@timui/react'\nimport { BellIcon } from 'lucide-react'\n\nconst initialNotifications = [\n  {\n    id: 1,\n    user: 'Chris Tompson',\n    action: 'requested review on',\n    target: 'PR #42: Feature implementation',\n    timestamp: '15 minutes ago',\n    unread: true,\n  },\n  {\n    id: 2,\n    user: 'Emma Davis',\n    action: 'shared',\n    target: 'New component library',\n    timestamp: '45 minutes ago',\n    unread: true,\n  },\n  {\n    id: 3,\n    user: 'James Wilson',\n    action: 'assigned you to',\n    target: 'API integration task',\n    timestamp: '4 hours ago',\n    unread: false,\n  },\n  {\n    id: 4,\n    user: 'Alex Morgan',\n    action: 'replied to your comment in',\n    target: 'Authentication flow',\n    timestamp: '12 hours ago',\n    unread: false,\n  },\n  {\n    id: 5,\n    user: 'Sarah Chen',\n    action: 'commented on',\n    target: 'Dashboard redesign',\n    timestamp: '2 days ago',\n    unread: false,\n  },\n  {\n    id: 6,\n    user: 'Miky Derya',\n    action: 'mentioned you in',\n    target: 'Timkit UI open graph image',\n    timestamp: '2 weeks ago',\n    unread: false,\n  },\n]\n\nfunction Dot({ className }: { className?: string }) {\n  return (\n    <svg\n      width=\"6\"\n      height=\"6\"\n      fill=\"currentColor\"\n      viewBox=\"0 0 6 6\"\n      xmlns=\"http://www.w3.org/2000/svg\"\n      className={className}\n      aria-hidden=\"true\"\n    >\n      <circle cx=\"3\" cy=\"3\" r=\"3\" />\n    </svg>\n  )\n}\n\nexport default function NotificationMenu() {\n  const [notifications, setNotifications] = useState(initialNotifications)\n  const unreadCount = notifications.filter((n) => n.unread).length\n\n  const handleMarkAllAsRead = () => {\n    setNotifications(\n      notifications.map((notification) => ({\n        ...notification,\n        unread: false,\n      }))\n    )\n  }\n\n  const handleNotificationClick = (id: number) => {\n    setNotifications(\n      notifications.map((notification) =>\n        notification.id === id ? { ...notification, unread: false } : notification\n      )\n    )\n  }\n\n  return (\n    <Popover>\n      <PopoverTrigger asChild>\n        <Button\n          size=\"icon\"\n          variant=\"ghost\"\n          className=\"text-muted-foreground relative size-8 rounded-full shadow-none\"\n          aria-label=\"Open notifications\"\n        >\n          <BellIcon size={16} aria-hidden=\"true\" />\n          {unreadCount > 0 && (\n            <div\n              aria-hidden=\"true\"\n              className=\"bg-primary absolute top-0.5 right-0.5 size-1 rounded-full\"\n            />\n          )}\n        </Button>\n      </PopoverTrigger>\n      <PopoverContent className=\"w-80 p-1\">\n        <div className=\"flex items-baseline justify-between gap-4 px-3 py-2\">\n          <div className=\"text-sm font-semibold\">Notifications</div>\n          {unreadCount > 0 && (\n            <button className=\"text-xs font-medium hover:underline\" onClick={handleMarkAllAsRead}>\n              Mark all as read\n            </button>\n          )}\n        </div>\n        <div\n          role=\"separator\"\n          aria-orientation=\"horizontal\"\n          className=\"bg-border -mx-1 my-1 h-px\"\n        ></div>\n        {notifications.map((notification) => (\n          <div\n            key={notification.id}\n            className=\"hover:bg-accent rounded-md px-3 py-2 text-sm transition-colors\"\n          >\n            <div className=\"relative flex items-start pe-3\">\n              <div className=\"flex-1 space-y-1\">\n                <button\n                  className=\"text-foreground/80 text-left after:absolute after:inset-0\"\n                  onClick={() => handleNotificationClick(notification.id)}\n                >\n                  <span className=\"text-foreground font-medium hover:underline\">\n                    {notification.user}\n                  </span>{' '}\n                  {notification.action}{' '}\n                  <span className=\"text-foreground font-medium hover:underline\">\n                    {notification.target}\n                  </span>\n                  .\n                </button>\n                <div className=\"text-muted-foreground text-xs\">{notification.timestamp}</div>\n              </div>\n              {notification.unread && (\n                <div className=\"absolute end-0 self-center\">\n                  <span className=\"sr-only\">Unread</span>\n                  <Dot />\n                </div>\n              )}\n            </div>\n          </div>\n        ))}\n      </PopoverContent>\n    </Popover>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/user-menu.tsx",
          "type": "registry:component",
          "target": "components/ui/user-menu.tsx",
          "content": "import {\n  Avatar,\n  AvatarFallback,\n  AvatarImage,\n  Button,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from '@timui/react'\nimport { BoltIcon, BookOpenIcon, Layers2Icon, LogOutIcon, PinIcon, UserPenIcon } from 'lucide-react'\n\nexport default function UserMenu() {\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button variant=\"ghost\" className=\"h-auto p-0 hover:bg-transparent\">\n          <Avatar>\n            <AvatarImage src=\"./avatar.jpg\" alt=\"Profile image\" />\n            <AvatarFallback>KK</AvatarFallback>\n          </Avatar>\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent className=\"max-w-64\" align=\"end\">\n        <DropdownMenuLabel className=\"flex min-w-0 flex-col\">\n          <span className=\"text-foreground truncate text-sm font-medium\">Keith Kennedy</span>\n          <span className=\"text-muted-foreground truncate text-xs font-normal\">\n            k.kennedy@ui.timkit.cn\n          </span>\n        </DropdownMenuLabel>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <BoltIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 1</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <Layers2Icon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 2</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <BookOpenIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 3</span>\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <PinIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 4</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <UserPenIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 5</span>\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuItem>\n          <LogOutIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n          <span>Logout</span>\n        </DropdownMenuItem>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-09.vue",
          "target": "components/ui/navbar-09.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { HashIcon, HouseIcon, MailIcon, SearchIcon, UsersRound } from 'lucide-vue-next'\nimport { Button } from '@timui/vue'\nimport { Input } from '@timui/vue'\nimport {\n  NavigationMenu,\n  NavigationMenuItem,\n  NavigationMenuLink,\n  NavigationMenuList,\n} from '@timui/vue'\nimport { Popover, PopoverContent, PopoverTrigger } from '@timui/vue'\nimport Logo from '@/registry/default/components/navbar-components/logo.vue'\nimport NotificationMenu from '@/registry/default/components/navbar-components/notification-menu.vue'\nimport UserMenu from '@/registry/default/components/navbar-components/user-menu.vue'\n\nconst navigationLinks = [\n  { href: '#', label: 'Home', icon: HouseIcon },\n  { href: '#', label: 'Hash', icon: HashIcon },\n  { href: '#', label: 'Groups', icon: UsersRound },\n]\n\nconst id = 'navbar-09-search'\n</script>\n\n<template>\n  <header class=\"border-b px-4 md:px-6\">\n    <div class=\"flex h-16 items-center justify-between gap-4\">\n      <div class=\"flex flex-1 items-center gap-2\">\n        <Popover>\n          <PopoverTrigger as-child>\n            <Button class=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\">\n              <svg\n                class=\"pointer-events-none\"\n                :width=\"16\"\n                :height=\"16\"\n                viewBox=\"0 0 24 24\"\n                fill=\"none\"\n                stroke=\"currentColor\"\n                stroke-width=\"2\"\n                stroke-linecap=\"round\"\n                stroke-linejoin=\"round\"\n                xmlns=\"http://www.w3.org/2000/svg\"\n              >\n                <path\n                  d=\"M4 12L20 12\"\n                  class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\"\n                />\n                <path\n                  d=\"M4 12H20\"\n                  class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\"\n                />\n                <path\n                  d=\"M4 12H20\"\n                  class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\"\n                />\n              </svg>\n            </Button>\n          </PopoverTrigger>\n          <PopoverContent align=\"start\" class=\"w-48 p-1 md:hidden\">\n            <NavigationMenu class=\"max-w-none *:w-full\">\n              <NavigationMenuList class=\"flex-col items-start gap-0 md:gap-2\">\n                <NavigationMenuItem v-for=\"(link, index) in navigationLinks\" :key=\"index\" class=\"w-full\">\n                  <NavigationMenuLink :href=\"link.href\" class=\"flex-row items-center gap-2 py-1.5\">\n                    <component :is=\"link.icon\" :size=\"16\" class=\"text-muted-foreground\" aria-hidden=\"true\" />\n                    <span>{{ link.label }}</span>\n                  </NavigationMenuLink>\n                </NavigationMenuItem>\n              </NavigationMenuList>\n            </NavigationMenu>\n          </PopoverContent>\n        </Popover>\n\n        <div class=\"flex items-center gap-6\">\n          <a href=\"#\" class=\"text-primary hover:text-primary/90\">\n            <Logo />\n          </a>\n          <div class=\"relative\">\n            <Input :id=\"id\" class=\"peer h-8 ps-8 pe-2\" placeholder=\"Search...\" type=\"search\" />\n            <div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-2 peer-disabled:opacity-50\">\n              <SearchIcon :size=\"16\" />\n            </div>\n          </div>\n        </div>\n      </div>\n\n      <NavigationMenu class=\"max-md:hidden\">\n        <NavigationMenuList class=\"gap-2\">\n          <NavigationMenuItem v-for=\"(link, index) in navigationLinks\" :key=\"index\">\n            <NavigationMenuLink\n              :href=\"link.href\"\n              class=\"flex size-8 items-center justify-center p-1.5\"\n              :title=\"link.label\"\n            >\n              <component :is=\"link.icon\" aria-hidden=\"true\" />\n              <span class=\"sr-only\">{{ link.label }}</span>\n            </NavigationMenuLink>\n          </NavigationMenuItem>\n        </NavigationMenuList>\n      </NavigationMenu>\n\n      <div class=\"flex flex-1 items-center justify-end gap-4\">\n        <div class=\"flex items-center gap-2\">\n          <Button\n            size=\"icon\"\n            variant=\"ghost\"\n            class=\"text-muted-foreground relative size-8 rounded-full shadow-none\"\n            aria-label=\"Open notifications\"\n          >\n            <MailIcon :size=\"16\" aria-hidden=\"true\" />\n            <div aria-hidden=\"true\" class=\"bg-primary absolute top-0.5 right-0.5 size-1 rounded-full\" />\n          </Button>\n          <NotificationMenu />\n        </div>\n        <UserMenu />\n      </div>\n    </div>\n  </header>\n</template>\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-09.html",
          "target": "components/ui/navbar-09.html",
          "type": "registry:component",
          "content": "<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 items-center justify-between gap-4\"><div class=\"flex flex-1 items-center gap-2\"><Popover><PopoverTrigger aschild><Button class=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\"><svg class=\"pointer-events-none\" width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></Button></PopoverTrigger><PopoverContent align=\"start\" class=\"w-48 p-1 md:hidden\"><NavigationMenu class=\"max-w-none *:w-full\"><NavigationMenuList class=\"flex-col items-start gap-0 md:gap-2\">${navigationLinks.map((link, index) => {\n                    const Icon = link.icon\n                    return (\n                      <NavigationMenuItem key={index} className=\"w-full\">\n                        <NavigationMenuLink\n                          href={link.href}\n                          className=\"flex-row items-center gap-2 py-1.5\"\n                        >\n                          <Icon size={16} className=\"text-muted-foreground\" aria-hidden=\"true\" />\n                          <span>{link.label}</span>\n                        </NavigationMenuLink>\n                      </NavigationMenuItem>\n                    )\n                  })}</NavigationMenuList></NavigationMenu></PopoverContent></Popover><div class=\"flex items-center gap-6\"><a href=\"#\" class=\"text-primary hover:text-primary/90\"><Logo /></a><div class=\"relative\"><Input id=\"${id}\" class=\"peer h-8 ps-8 pe-2\" placeholder=\"Search...\" type=\"search\" /><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-2 peer-disabled:opacity-50\"><SearchIcon size=\"${16}\" /></div></div></div></div><NavigationMenu class=\"max-md:hidden\"><NavigationMenuList class=\"gap-2\">${navigationLinks.map((link, index) => {\n              const Icon = link.icon\n              return (\n                <NavigationMenuItem key={index}>\n                  <NavigationMenuLink\n                    href={link.href}\n                    className=\"flex size-8 items-center justify-center p-1.5\"\n                    title={link.label}\n                  >\n                    <Icon aria-hidden=\"true\" />\n                    <span className=\"sr-only\">{link.label}</span>\n                  </NavigationMenuLink>\n                </NavigationMenuItem>\n              )\n            })}</NavigationMenuList></NavigationMenu><div class=\"flex flex-1 items-center justify-end gap-4\"><div class=\"flex items-center gap-2\"><Button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground relative size-8 rounded-full shadow-none\" aria-label=\"Open notifications\"><MailIcon size=\"${16}\" aria-hidden=\"true\" /><div aria-hidden=\"true\" class=\"bg-primary absolute top-0.5 right-0.5 size-1 rounded-full\" /></Button><NotificationMenu /></div><UserMenu /></div></div></header>\n</template>"
        },
        {
          "path": "registry/default/components/navbar/navbar-09.wxml",
          "target": "components/ui/navbar-09/navbar-09.wxml",
          "type": "registry:component",
          "content": "<view>\n  <header class=\"border-b px-4 md:px-6\"><view class=\"flex h-16 items-center justify-between gap-4\"><view class=\"flex flex-1 items-center gap-2\"><popover><popovertrigger aschild><button class=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\"><svg class=\"pointer-events-none\" width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></button></popovertrigger><popovercontent align=\"start\" class=\"w-48 p-1 md:hidden\"><navigationmenu class=\"max-w-none *:w-full\"><navigationmenulist class=\"flex-col items-start gap-0 md:gap-2\">{{ navigationLinks.map((link, index) => {\n                    const Icon = link.icon\n                    return (\n                      <NavigationMenuItem key={index} className=\"w-full\">\n                        <NavigationMenuLink\n                          href={link.href}\n                          className=\"flex-row items-center gap-2 py-1.5\"\n                        >\n                          <Icon size={16} className=\"text-muted-foreground\" aria-hidden=\"true\" />\n                          <span>{link.label}</span>\n                        </NavigationMenuLink>\n                      </NavigationMenuItem>\n                    )\n                  }) }}</navigationmenulist></navigationmenu></popovercontent></popover><view class=\"flex items-center gap-6\"><a href=\"#\" class=\"text-primary hover:text-primary/90\"><logo /></a><view class=\"relative\"><input id=\"{{id}}\" class=\"peer h-8 ps-8 pe-2\" placeholder=\"Search...\" type=\"search\" /><view class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-2 peer-disabled:opacity-50\"><searchicon size=\"{{16}}\" /></view></view></view></view><navigationmenu class=\"max-md:hidden\"><navigationmenulist class=\"gap-2\">{{ navigationLinks.map((link, index) => {\n              const Icon = link.icon\n              return (\n                <NavigationMenuItem key={index}>\n                  <NavigationMenuLink\n                    href={link.href}\n                    className=\"flex size-8 items-center justify-center p-1.5\"\n                    title={link.label}\n                  >\n                    <Icon aria-hidden=\"true\" />\n                    <span className=\"sr-only\">{link.label}</span>\n                  </NavigationMenuLink>\n                </NavigationMenuItem>\n              )\n            }) }}</navigationmenulist></navigationmenu><view class=\"flex flex-1 items-center justify-end gap-4\"><view class=\"flex items-center gap-2\"><button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground relative size-8 rounded-full shadow-none\" aria-label=\"Open notifications\"><mailicon size=\"{{16}}\" aria-hidden=\"true\" /><div aria-hidden=\"true\" class=\"bg-primary absolute top-0.5 right-0.5 size-1 rounded-full\" /></button><notificationmenu /></view><usermenu /></view></view></header>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "navbar, navigation"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "navbar-09",
          "group": "navbar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "navbar-09",
              "path": "registry/default/components/navbar/navbar-09.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "navbar-09",
              "path": "registry/default/components/navbar/navbar-09.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "navbar-09",
              "path": "registry/default/components/navbar/navbar-09.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "navbar-09",
              "path": "registry/default/components/navbar/navbar-09.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "navbars",
        "title": "Navbar · Open notifications"
      },
      "categories": [
        "navbars",
        "navbar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "navbar-10",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/avatar.json",
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dropdown-menu.json",
        "https://ui.timkit.cn/r/input.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/navbar/navbar-10.tsx",
          "type": "registry:component",
          "target": "components/ui/navbar-10.tsx",
          "content": "import { useId } from 'react'\nimport { Button, Input } from '@timui/react'\nimport { MicIcon, SearchIcon } from 'lucide-react'\n\nimport Logo from '@/registry/default/components/navbar-components/logo'\nimport ThemeToggle from '@/registry/default/components/navbar-components/theme-toggle'\n\nexport default function Component() {\n  const id = useId()\n\n  return (\n    <header className=\"border-b px-4 md:px-6\">\n      <div className=\"flex h-16 items-center justify-between gap-4\">\n        {/* Logo */}\n        <div className=\"flex-1\">\n          <a href=\"#\" className=\"text-primary hover:text-primary/90\">\n            <Logo />\n          </a>\n        </div>\n        {/* Middle area */}\n        <div className=\"grow max-sm:hidden\">\n          {/* Search form */}\n          <div className=\"relative mx-auto w-full max-w-xs\">\n            <Input id={id} className=\"peer h-8 px-8\" placeholder=\"Search...\" type=\"search\" />\n            <div className=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-2 peer-disabled:opacity-50\">\n              <SearchIcon size={16} />\n            </div>\n            <button\n              className=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\"\n              aria-label=\"Press to speak\"\n              type=\"submit\"\n            >\n              <MicIcon size={16} aria-hidden=\"true\" />\n            </button>\n          </div>\n        </div>\n        {/* Right side */}\n        <div className=\"flex flex-1 items-center justify-end gap-2\">\n          <Button asChild variant=\"ghost\" size=\"sm\" className=\"text-sm\">\n            <a href=\"#\">Community</a>\n          </Button>\n          <Button asChild size=\"sm\" className=\"text-sm\">\n            <a href=\"#\">Get Started</a>\n          </Button>\n          <ThemeToggle />\n        </div>\n      </div>\n    </header>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/logo.tsx",
          "type": "registry:component",
          "target": "components/ui/logo.tsx",
          "content": "export default function Logo() {\n  return (\n    <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"33\" height=\"33\" fill=\"currentColor\">\n      <path d=\"M20.46 1.766 17.303.923l-2.66 9.896-2.403-8.934-3.157.843 2.595 9.652-6.464-6.442-2.311 2.304 7.09 7.066-8.83-2.358-.846 3.146 9.648 2.577a6.516 6.516 0 0 1-.169-1.478c0-3.598 2.927-6.515 6.537-6.515s6.537 2.917 6.537 6.515c0 .505-.057.997-.167 1.468l8.768 2.342.846-3.147-9.686-2.586 8.83-2.358-.845-3.147-9.686 2.587 6.464-6.442-2.311-2.304-6.992 6.969 2.369-8.81Z\" />\n      <path d=\"M22.695 18.7a6.495 6.495 0 0 1-1.626 2.986l6.352 6.33 2.31-2.303-7.036-7.013ZM21.005 21.752a6.538 6.538 0 0 1-2.922 1.722l2.312 8.596 3.157-.843-2.547-9.475ZM17.965 23.505a6.569 6.569 0 0 1-1.632.205 6.566 6.566 0 0 1-1.743-.235l-2.314 8.605 3.157.843 2.532-9.418ZM14.478 23.444a6.54 6.54 0 0 1-2.87-1.747l-6.367 6.346 2.31 2.303 6.927-6.902ZM11.555 21.64a6.492 6.492 0 0 1-1.585-2.948L1.173 21.04l.846 3.146 9.536-2.546Z\" />\n    </svg>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/theme-toggle.tsx",
          "type": "registry:component",
          "target": "components/ui/theme-toggle.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Toggle } from '@timui/react'\nimport { MoonIcon, SunIcon } from 'lucide-react'\n\nexport default function ThemeToggle() {\n  const [theme, setTheme] = useState<string>('light')\n\n  return (\n    <div>\n      <Toggle\n        variant=\"outline\"\n        className=\"group data-[state=on]:hover:bg-muted text-muted-foreground data-[state=on]:text-muted-foreground data-[state=on]:hover:text-foreground size-8 rounded-full border-none shadow-none data-[state=on]:bg-transparent\"\n        pressed={theme === 'dark'}\n        onPressedChange={() => setTheme((prev) => (prev === 'dark' ? 'light' : 'dark'))}\n        aria-label={`Switch to ${theme === 'dark' ? 'light' : 'dark'} mode`}\n      >\n        {/* Note: After dark mode implementation, rely on dark: prefix rather than group-data-[state=on]: */}\n        <MoonIcon\n          size={16}\n          className=\"shrink-0 scale-0 opacity-0 transition-all group-data-[state=on]:scale-100 group-data-[state=on]:opacity-100\"\n          aria-hidden=\"true\"\n        />\n        <SunIcon\n          size={16}\n          className=\"absolute shrink-0 scale-100 opacity-100 transition-all group-data-[state=on]:scale-0 group-data-[state=on]:opacity-0\"\n          aria-hidden=\"true\"\n        />\n      </Toggle>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-10.vue",
          "target": "components/ui/navbar-10.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { MicIcon, SearchIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { Input } from '@timui/vue';\nimport Logo from '@/registry/default/components/navbar-components/logo.vue';\nimport ThemeToggle from '@/registry/default/components/navbar-components/theme-toggle.vue';\n\n\n\n\nconst id = 'navbar-10';\n\n</script>\n\n<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 items-center justify-between gap-4\"><div class=\"flex-1\"><a href=\"#\" class=\"text-primary hover:text-primary/90\"><Logo /></a></div><div class=\"grow max-sm:hidden\"><div class=\"relative mx-auto w-full max-w-xs\"><Input :id=\"id\" class=\"peer h-8 px-8\" placeholder=\"Search...\" type=\"search\" /><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-2 peer-disabled:opacity-50\"><SearchIcon :size=\"16\" /></div><button class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\" aria-label=\"Press to speak\" type=\"submit\"><MicIcon :size=\"16\" aria-hidden=\"true\" /></button></div></div><div class=\"flex flex-1 items-center justify-end gap-2\"><Button as-child variant=\"ghost\" size=\"sm\" class=\"text-sm\"><a href=\"#\">Community</a></Button><Button as-child size=\"sm\" class=\"text-sm\"><a href=\"#\">Get Started</a></Button><ThemeToggle /></div></div></header>\n</template>\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-10.html",
          "target": "components/ui/navbar-10.html",
          "type": "registry:component",
          "content": "<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 items-center justify-between gap-4\"><div class=\"flex-1\"><a href=\"#\" class=\"text-primary hover:text-primary/90\"><Logo /></a></div><div class=\"grow max-sm:hidden\"><div class=\"relative mx-auto w-full max-w-xs\"><Input id=\"${id}\" class=\"peer h-8 px-8\" placeholder=\"Search...\" type=\"search\" /><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-2 peer-disabled:opacity-50\"><SearchIcon size=\"${16}\" /></div><button class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\" aria-label=\"Press to speak\" type=\"submit\"><MicIcon size=\"${16}\" aria-hidden=\"true\" /></button></div></div><div class=\"flex flex-1 items-center justify-end gap-2\"><Button aschild variant=\"ghost\" size=\"sm\" class=\"text-sm\"><a href=\"#\">Community</a></Button><Button aschild size=\"sm\" class=\"text-sm\"><a href=\"#\">Get Started</a></Button><ThemeToggle /></div></div></header>\n</template>"
        },
        {
          "path": "registry/default/components/navbar/navbar-10.wxml",
          "target": "components/ui/navbar-10/navbar-10.wxml",
          "type": "registry:component",
          "content": "<view>\n  <header class=\"border-b px-4 md:px-6\"><view class=\"flex h-16 items-center justify-between gap-4\"><view class=\"flex-1\"><a href=\"#\" class=\"text-primary hover:text-primary/90\"><logo /></a></view><view class=\"grow max-sm:hidden\"><view class=\"relative mx-auto w-full max-w-xs\"><input id=\"{{id}}\" class=\"peer h-8 px-8\" placeholder=\"Search...\" type=\"search\" /><view class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-2 peer-disabled:opacity-50\"><searchicon size=\"{{16}}\" /></view><button class=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\" aria-label=\"Press to speak\" type=\"submit\"><micicon size=\"{{16}}\" aria-hidden=\"true\" /></button></view></view><view class=\"flex flex-1 items-center justify-end gap-2\"><button aschild variant=\"ghost\" size=\"sm\" class=\"text-sm\"><a href=\"#\">Community</a></button><button aschild size=\"sm\" class=\"text-sm\"><a href=\"#\">Get Started</a></button><themetoggle /></view></view></header>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "navbar, navigation"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "navbar-10",
          "group": "navbar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "navbar-10",
              "path": "registry/default/components/navbar/navbar-10.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "navbar-10",
              "path": "registry/default/components/navbar/navbar-10.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "navbar-10",
              "path": "registry/default/components/navbar/navbar-10.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "navbar-10",
              "path": "registry/default/components/navbar/navbar-10.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "navbars",
        "title": "Navbar · Press to speak"
      },
      "categories": [
        "navbars",
        "navbar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "navbar-11",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/navigation-menu.json",
        "https://ui.timkit.cn/r/popover.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/navbar/navbar-11.tsx",
          "type": "registry:component",
          "target": "components/ui/navbar-11.tsx",
          "content": "import { useId } from 'react'\nimport {\n  Button,\n  Input,\n  NavigationMenu,\n  NavigationMenuItem,\n  NavigationMenuLink,\n  NavigationMenuList,\n  Popover,\n  PopoverContent,\n  PopoverTrigger,\n} from '@timui/react'\nimport { HouseIcon, InboxIcon, SearchIcon, ZapIcon } from 'lucide-react'\n\nimport Logo from '@/registry/default/components/navbar-components/logo'\n\n// Navigation links array to be used in both desktop and mobile menus\nconst navigationLinks = [\n  { href: '#', label: 'Home', icon: HouseIcon, active: true },\n  { href: '#', label: 'Inbox', icon: InboxIcon },\n  { href: '#', label: 'Insights', icon: ZapIcon },\n]\n\nexport default function Component() {\n  const id = useId()\n\n  return (\n    <header className=\"border-b px-4 md:px-6\">\n      <div className=\"flex h-16 items-center justify-between gap-4\">\n        {/* Left side */}\n        <div className=\"flex flex-1 items-center gap-2\">\n          {/* Mobile menu trigger */}\n          <Popover>\n            <PopoverTrigger asChild>\n              <Button className=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\">\n                <svg\n                  className=\"pointer-events-none\"\n                  width={16}\n                  height={16}\n                  viewBox=\"0 0 24 24\"\n                  fill=\"none\"\n                  stroke=\"currentColor\"\n                  strokeWidth=\"2\"\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  xmlns=\"http://www.w3.org/2000/svg\"\n                >\n                  <path\n                    d=\"M4 12L20 12\"\n                    className=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\"\n                  />\n                  <path\n                    d=\"M4 12H20\"\n                    className=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\"\n                  />\n                  <path\n                    d=\"M4 12H20\"\n                    className=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\"\n                  />\n                </svg>\n              </Button>\n            </PopoverTrigger>\n            <PopoverContent align=\"start\" className=\"w-36 p-1 md:hidden\">\n              <NavigationMenu className=\"max-w-none *:w-full\">\n                <NavigationMenuList className=\"flex-col items-start gap-0 md:gap-2\">\n                  {navigationLinks.map((link, index) => {\n                    const Icon = link.icon\n                    return (\n                      <NavigationMenuItem key={index} className=\"w-full\">\n                        <NavigationMenuLink\n                          href={link.href}\n                          className=\"flex-row items-center gap-2 py-1.5\"\n                          active={link.active}\n                        >\n                          <Icon size={16} className=\"text-muted-foreground/80\" aria-hidden=\"true\" />\n                          <span>{link.label}</span>\n                        </NavigationMenuLink>\n                      </NavigationMenuItem>\n                    )\n                  })}\n                </NavigationMenuList>\n              </NavigationMenu>\n            </PopoverContent>\n          </Popover>\n          {/* Logo */}\n          <div className=\"flex items-center\">\n            <a href=\"#\" className=\"text-primary hover:text-primary/90\">\n              <Logo />\n            </a>\n          </div>\n        </div>\n        {/* Middle area */}\n        <NavigationMenu className=\"max-md:hidden\">\n          <NavigationMenuList className=\"gap-2\">\n            {navigationLinks.map((link, index) => {\n              const Icon = link.icon\n              return (\n                <NavigationMenuItem key={index}>\n                  <NavigationMenuLink\n                    active={link.active}\n                    href={link.href}\n                    className=\"text-foreground hover:text-primary flex-row items-center gap-2 py-1.5 font-medium\"\n                  >\n                    <Icon size={16} className=\"text-muted-foreground/80\" aria-hidden=\"true\" />\n                    <span>{link.label}</span>\n                  </NavigationMenuLink>\n                </NavigationMenuItem>\n              )\n            })}\n          </NavigationMenuList>\n        </NavigationMenu>\n        {/* Right side */}\n        <div className=\"flex flex-1 items-center justify-end gap-2\">\n          <div className=\"relative\">\n            <Input id={id} className=\"peer h-8 ps-8 pe-2\" placeholder=\"Search...\" type=\"search\" />\n            <div className=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-2 peer-disabled:opacity-50\">\n              <SearchIcon size={16} />\n            </div>\n          </div>\n        </div>\n      </div>\n    </header>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/logo.tsx",
          "type": "registry:component",
          "target": "components/ui/logo.tsx",
          "content": "export default function Logo() {\n  return (\n    <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"33\" height=\"33\" fill=\"currentColor\">\n      <path d=\"M20.46 1.766 17.303.923l-2.66 9.896-2.403-8.934-3.157.843 2.595 9.652-6.464-6.442-2.311 2.304 7.09 7.066-8.83-2.358-.846 3.146 9.648 2.577a6.516 6.516 0 0 1-.169-1.478c0-3.598 2.927-6.515 6.537-6.515s6.537 2.917 6.537 6.515c0 .505-.057.997-.167 1.468l8.768 2.342.846-3.147-9.686-2.586 8.83-2.358-.845-3.147-9.686 2.587 6.464-6.442-2.311-2.304-6.992 6.969 2.369-8.81Z\" />\n      <path d=\"M22.695 18.7a6.495 6.495 0 0 1-1.626 2.986l6.352 6.33 2.31-2.303-7.036-7.013ZM21.005 21.752a6.538 6.538 0 0 1-2.922 1.722l2.312 8.596 3.157-.843-2.547-9.475ZM17.965 23.505a6.569 6.569 0 0 1-1.632.205 6.566 6.566 0 0 1-1.743-.235l-2.314 8.605 3.157.843 2.532-9.418ZM14.478 23.444a6.54 6.54 0 0 1-2.87-1.747l-6.367 6.346 2.31 2.303 6.927-6.902ZM11.555 21.64a6.492 6.492 0 0 1-1.585-2.948L1.173 21.04l.846 3.146 9.536-2.546Z\" />\n    </svg>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-11.vue",
          "target": "components/ui/navbar-11.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { HouseIcon, InboxIcon, SearchIcon, ZapIcon } from 'lucide-vue-next'\nimport { Button } from '@timui/vue'\nimport { Input } from '@timui/vue'\nimport {\n  NavigationMenu,\n  NavigationMenuItem,\n  NavigationMenuLink,\n  NavigationMenuList,\n} from '@timui/vue'\nimport { Popover, PopoverContent, PopoverTrigger } from '@timui/vue'\nimport Logo from '@/registry/default/components/navbar-components/logo.vue'\n\nconst navigationLinks = [\n  { href: '#', label: 'Home', icon: HouseIcon, active: true },\n  { href: '#', label: 'Inbox', icon: InboxIcon },\n  { href: '#', label: 'Insights', icon: ZapIcon },\n]\n\nconst id = 'navbar-11-search'\n</script>\n\n<template>\n  <header class=\"border-b px-4 md:px-6\">\n    <div class=\"flex h-16 items-center justify-between gap-4\">\n      <div class=\"flex flex-1 items-center gap-2\">\n        <Popover>\n          <PopoverTrigger as-child>\n            <Button class=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\">\n              <svg\n                class=\"pointer-events-none\"\n                :width=\"16\"\n                :height=\"16\"\n                viewBox=\"0 0 24 24\"\n                fill=\"none\"\n                stroke=\"currentColor\"\n                stroke-width=\"2\"\n                stroke-linecap=\"round\"\n                stroke-linejoin=\"round\"\n                xmlns=\"http://www.w3.org/2000/svg\"\n              >\n                <path\n                  d=\"M4 12L20 12\"\n                  class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\"\n                />\n                <path\n                  d=\"M4 12H20\"\n                  class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\"\n                />\n                <path\n                  d=\"M4 12H20\"\n                  class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\"\n                />\n              </svg>\n            </Button>\n          </PopoverTrigger>\n          <PopoverContent align=\"start\" class=\"w-36 p-1 md:hidden\">\n            <NavigationMenu class=\"max-w-none *:w-full\">\n              <NavigationMenuList class=\"flex-col items-start gap-0 md:gap-2\">\n                <NavigationMenuItem v-for=\"(link, index) in navigationLinks\" :key=\"index\" class=\"w-full\">\n                  <NavigationMenuLink\n                    :href=\"link.href\"\n                    class=\"flex-row items-center gap-2 py-1.5\"\n                    :active=\"link.active\"\n                  >\n                    <component :is=\"link.icon\" :size=\"16\" class=\"text-muted-foreground/80\" aria-hidden=\"true\" />\n                    <span>{{ link.label }}</span>\n                  </NavigationMenuLink>\n                </NavigationMenuItem>\n              </NavigationMenuList>\n            </NavigationMenu>\n          </PopoverContent>\n        </Popover>\n\n        <div class=\"flex items-center\">\n          <a href=\"#\" class=\"text-primary hover:text-primary/90\">\n            <Logo />\n          </a>\n        </div>\n      </div>\n\n      <NavigationMenu class=\"max-md:hidden\">\n        <NavigationMenuList class=\"gap-2\">\n          <NavigationMenuItem v-for=\"(link, index) in navigationLinks\" :key=\"index\">\n            <NavigationMenuLink\n              :active=\"link.active\"\n              :href=\"link.href\"\n              class=\"text-foreground hover:text-primary flex-row items-center gap-2 py-1.5 font-medium\"\n            >\n              <component :is=\"link.icon\" :size=\"16\" class=\"text-muted-foreground/80\" aria-hidden=\"true\" />\n              <span>{{ link.label }}</span>\n            </NavigationMenuLink>\n          </NavigationMenuItem>\n        </NavigationMenuList>\n      </NavigationMenu>\n\n      <div class=\"flex flex-1 items-center justify-end gap-2\">\n        <div class=\"relative\">\n          <Input :id=\"id\" class=\"peer h-8 ps-8 pe-2\" placeholder=\"Search...\" type=\"search\" />\n          <div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-2 peer-disabled:opacity-50\">\n            <SearchIcon :size=\"16\" />\n          </div>\n        </div>\n      </div>\n    </div>\n  </header>\n</template>\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-11.html",
          "target": "components/ui/navbar-11.html",
          "type": "registry:component",
          "content": "<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 items-center justify-between gap-4\"><div class=\"flex flex-1 items-center gap-2\"><Popover><PopoverTrigger aschild><Button class=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\"><svg class=\"pointer-events-none\" width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></Button></PopoverTrigger><PopoverContent align=\"start\" class=\"w-36 p-1 md:hidden\"><NavigationMenu class=\"max-w-none *:w-full\"><NavigationMenuList class=\"flex-col items-start gap-0 md:gap-2\">${navigationLinks.map((link, index) => {\n                    const Icon = link.icon\n                    return (\n                      <NavigationMenuItem key={index} className=\"w-full\">\n                        <NavigationMenuLink\n                          href={link.href}\n                          className=\"flex-row items-center gap-2 py-1.5\"\n                          active={link.active}\n                        >\n                          <Icon size={16} className=\"text-muted-foreground/80\" aria-hidden=\"true\" />\n                          <span>{link.label}</span>\n                        </NavigationMenuLink>\n                      </NavigationMenuItem>\n                    )\n                  })}</NavigationMenuList></NavigationMenu></PopoverContent></Popover><div class=\"flex items-center\"><a href=\"#\" class=\"text-primary hover:text-primary/90\"><Logo /></a></div></div><NavigationMenu class=\"max-md:hidden\"><NavigationMenuList class=\"gap-2\">${navigationLinks.map((link, index) => {\n              const Icon = link.icon\n              return (\n                <NavigationMenuItem key={index}>\n                  <NavigationMenuLink\n                    active={link.active}\n                    href={link.href}\n                    className=\"text-foreground hover:text-primary flex-row items-center gap-2 py-1.5 font-medium\"\n                  >\n                    <Icon size={16} className=\"text-muted-foreground/80\" aria-hidden=\"true\" />\n                    <span>{link.label}</span>\n                  </NavigationMenuLink>\n                </NavigationMenuItem>\n              )\n            })}</NavigationMenuList></NavigationMenu><div class=\"flex flex-1 items-center justify-end gap-2\"><div class=\"relative\"><Input id=\"${id}\" class=\"peer h-8 ps-8 pe-2\" placeholder=\"Search...\" type=\"search\" /><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-2 peer-disabled:opacity-50\"><SearchIcon size=\"${16}\" /></div></div></div></div></header>\n</template>"
        },
        {
          "path": "registry/default/components/navbar/navbar-11.wxml",
          "target": "components/ui/navbar-11/navbar-11.wxml",
          "type": "registry:component",
          "content": "<view>\n  <header class=\"border-b px-4 md:px-6\"><view class=\"flex h-16 items-center justify-between gap-4\"><view class=\"flex flex-1 items-center gap-2\"><popover><popovertrigger aschild><button class=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\"><svg class=\"pointer-events-none\" width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></button></popovertrigger><popovercontent align=\"start\" class=\"w-36 p-1 md:hidden\"><navigationmenu class=\"max-w-none *:w-full\"><navigationmenulist class=\"flex-col items-start gap-0 md:gap-2\">{{ navigationLinks.map((link, index) => {\n                    const Icon = link.icon\n                    return (\n                      <NavigationMenuItem key={index} className=\"w-full\">\n                        <NavigationMenuLink\n                          href={link.href}\n                          className=\"flex-row items-center gap-2 py-1.5\"\n                          active={link.active}\n                        >\n                          <Icon size={16} className=\"text-muted-foreground/80\" aria-hidden=\"true\" />\n                          <span>{link.label}</span>\n                        </NavigationMenuLink>\n                      </NavigationMenuItem>\n                    )\n                  }) }}</navigationmenulist></navigationmenu></popovercontent></popover><view class=\"flex items-center\"><a href=\"#\" class=\"text-primary hover:text-primary/90\"><logo /></a></view></view><navigationmenu class=\"max-md:hidden\"><navigationmenulist class=\"gap-2\">{{ navigationLinks.map((link, index) => {\n              const Icon = link.icon\n              return (\n                <NavigationMenuItem key={index}>\n                  <NavigationMenuLink\n                    active={link.active}\n                    href={link.href}\n                    className=\"text-foreground hover:text-primary flex-row items-center gap-2 py-1.5 font-medium\"\n                  >\n                    <Icon size={16} className=\"text-muted-foreground/80\" aria-hidden=\"true\" />\n                    <span>{link.label}</span>\n                  </NavigationMenuLink>\n                </NavigationMenuItem>\n              )\n            }) }}</navigationmenulist></navigationmenu><view class=\"flex flex-1 items-center justify-end gap-2\"><view class=\"relative\"><input id=\"{{id}}\" class=\"peer h-8 ps-8 pe-2\" placeholder=\"Search...\" type=\"search\" /><view class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-2 peer-disabled:opacity-50\"><searchicon size=\"{{16}}\" /></view></view></view></view></header>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "navbar, navigation"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "navbar-11",
          "group": "navbar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "navbar-11",
              "path": "registry/default/components/navbar/navbar-11.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "navbar-11",
              "path": "registry/default/components/navbar/navbar-11.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "navbar-11",
              "path": "registry/default/components/navbar/navbar-11.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "navbar-11",
              "path": "registry/default/components/navbar/navbar-11.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "navbars",
        "title": "Navbar · Disabled State"
      },
      "categories": [
        "navbars",
        "navbar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "navbar-12",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/navigation-menu.json",
        "https://ui.timkit.cn/r/popover.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/navbar/navbar-12.tsx",
          "type": "registry:component",
          "target": "components/ui/navbar-12.tsx",
          "content": "import {\n  Button,\n  NavigationMenu,\n  NavigationMenuItem,\n  NavigationMenuLink,\n  NavigationMenuList,\n  Popover,\n  PopoverContent,\n  PopoverTrigger,\n} from '@timui/react'\nimport { HouseIcon, InboxIcon, SparklesIcon, ZapIcon } from 'lucide-react'\n\nimport Logo from '@/registry/default/components/navbar-components/logo'\nimport UserMenu from '@/registry/default/components/navbar-components/user-menu'\n\n// Navigation links array\nconst navigationLinks = [\n  { href: '#', label: 'Home', icon: HouseIcon, active: true },\n  { href: '#', label: 'Inbox', icon: InboxIcon },\n  { href: '#', label: 'Insights', icon: ZapIcon },\n]\n\nexport default function Component() {\n  return (\n    <header className=\"border-b px-4 md:px-6\">\n      <div className=\"flex h-16 items-center justify-between gap-4\">\n        {/* Left side */}\n        <div className=\"flex flex-1 items-center gap-2\">\n          {/* Mobile menu trigger */}\n          <Popover>\n            <PopoverTrigger asChild>\n              <Button className=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\">\n                <svg\n                  className=\"pointer-events-none\"\n                  width={16}\n                  height={16}\n                  viewBox=\"0 0 24 24\"\n                  fill=\"none\"\n                  stroke=\"currentColor\"\n                  strokeWidth=\"2\"\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  xmlns=\"http://www.w3.org/2000/svg\"\n                >\n                  <path\n                    d=\"M4 12L20 12\"\n                    className=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\"\n                  />\n                  <path\n                    d=\"M4 12H20\"\n                    className=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\"\n                  />\n                  <path\n                    d=\"M4 12H20\"\n                    className=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\"\n                  />\n                </svg>\n              </Button>\n            </PopoverTrigger>\n            <PopoverContent align=\"start\" className=\"w-36 p-1 md:hidden\">\n              <NavigationMenu className=\"max-w-none *:w-full\">\n                <NavigationMenuList className=\"flex-col items-start gap-0 md:gap-2\">\n                  {navigationLinks.map((link, index) => {\n                    const Icon = link.icon\n                    return (\n                      <NavigationMenuItem key={index} className=\"w-full\">\n                        <NavigationMenuLink\n                          href={link.href}\n                          className=\"flex-row items-center gap-2 py-1.5\"\n                          active={link.active}\n                        >\n                          <Icon size={16} className=\"text-muted-foreground/80\" aria-hidden=\"true\" />\n                          <span>{link.label}</span>\n                        </NavigationMenuLink>\n                      </NavigationMenuItem>\n                    )\n                  })}\n                </NavigationMenuList>\n              </NavigationMenu>\n            </PopoverContent>\n          </Popover>\n\n          <NavigationMenu className=\"max-md:hidden\">\n            <NavigationMenuList className=\"gap-2\">\n              {navigationLinks.map((link, index) => {\n                const Icon = link.icon\n                return (\n                  <NavigationMenuItem key={index}>\n                    <NavigationMenuLink\n                      active={link.active}\n                      href={link.href}\n                      className=\"text-foreground hover:text-primary flex-row items-center gap-2 py-1.5 font-medium\"\n                    >\n                      <Icon size={16} className=\"text-muted-foreground/80\" aria-hidden=\"true\" />\n                      <span>{link.label}</span>\n                    </NavigationMenuLink>\n                  </NavigationMenuItem>\n                )\n              })}\n            </NavigationMenuList>\n          </NavigationMenu>\n        </div>\n\n        {/* Middle side: Logo */}\n        <div className=\"flex items-center\">\n          <a href=\"#\" className=\"text-primary hover:text-primary/90\">\n            <Logo />\n          </a>\n        </div>\n\n        {/* Right side: Actions */}\n        <div className=\"flex flex-1 items-center justify-end gap-4\">\n          {/* User menu */}\n          <UserMenu />\n          {/* Upgrade button */}\n          <Button size=\"sm\" className=\"aspect-square text-sm\">\n            <SparklesIcon\n              className=\"opacity-60 max-sm:hidden sm:-ms-1\"\n              size={16}\n              aria-hidden=\"true\"\n            />\n            Upgrade\n          </Button>\n        </div>\n      </div>\n    </header>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/logo.tsx",
          "type": "registry:component",
          "target": "components/ui/logo.tsx",
          "content": "export default function Logo() {\n  return (\n    <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"33\" height=\"33\" fill=\"currentColor\">\n      <path d=\"M20.46 1.766 17.303.923l-2.66 9.896-2.403-8.934-3.157.843 2.595 9.652-6.464-6.442-2.311 2.304 7.09 7.066-8.83-2.358-.846 3.146 9.648 2.577a6.516 6.516 0 0 1-.169-1.478c0-3.598 2.927-6.515 6.537-6.515s6.537 2.917 6.537 6.515c0 .505-.057.997-.167 1.468l8.768 2.342.846-3.147-9.686-2.586 8.83-2.358-.845-3.147-9.686 2.587 6.464-6.442-2.311-2.304-6.992 6.969 2.369-8.81Z\" />\n      <path d=\"M22.695 18.7a6.495 6.495 0 0 1-1.626 2.986l6.352 6.33 2.31-2.303-7.036-7.013ZM21.005 21.752a6.538 6.538 0 0 1-2.922 1.722l2.312 8.596 3.157-.843-2.547-9.475ZM17.965 23.505a6.569 6.569 0 0 1-1.632.205 6.566 6.566 0 0 1-1.743-.235l-2.314 8.605 3.157.843 2.532-9.418ZM14.478 23.444a6.54 6.54 0 0 1-2.87-1.747l-6.367 6.346 2.31 2.303 6.927-6.902ZM11.555 21.64a6.492 6.492 0 0 1-1.585-2.948L1.173 21.04l.846 3.146 9.536-2.546Z\" />\n    </svg>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/user-menu.tsx",
          "type": "registry:component",
          "target": "components/ui/user-menu.tsx",
          "content": "import {\n  Avatar,\n  AvatarFallback,\n  AvatarImage,\n  Button,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from '@timui/react'\nimport { BoltIcon, BookOpenIcon, Layers2Icon, LogOutIcon, PinIcon, UserPenIcon } from 'lucide-react'\n\nexport default function UserMenu() {\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button variant=\"ghost\" className=\"h-auto p-0 hover:bg-transparent\">\n          <Avatar>\n            <AvatarImage src=\"./avatar.jpg\" alt=\"Profile image\" />\n            <AvatarFallback>KK</AvatarFallback>\n          </Avatar>\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent className=\"max-w-64\" align=\"end\">\n        <DropdownMenuLabel className=\"flex min-w-0 flex-col\">\n          <span className=\"text-foreground truncate text-sm font-medium\">Keith Kennedy</span>\n          <span className=\"text-muted-foreground truncate text-xs font-normal\">\n            k.kennedy@ui.timkit.cn\n          </span>\n        </DropdownMenuLabel>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <BoltIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 1</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <Layers2Icon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 2</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <BookOpenIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 3</span>\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <PinIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 4</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <UserPenIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 5</span>\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuItem>\n          <LogOutIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n          <span>Logout</span>\n        </DropdownMenuItem>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-12.vue",
          "target": "components/ui/navbar-12.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { HouseIcon, InboxIcon, SparklesIcon, ZapIcon } from 'lucide-vue-next'\nimport { Button } from '@timui/vue'\nimport {\n  NavigationMenu,\n  NavigationMenuItem,\n  NavigationMenuLink,\n  NavigationMenuList,\n} from '@timui/vue'\nimport { Popover, PopoverContent, PopoverTrigger } from '@timui/vue'\nimport Logo from '@/registry/default/components/navbar-components/logo.vue'\nimport UserMenu from '@/registry/default/components/navbar-components/user-menu.vue'\n\nconst navigationLinks = [\n  { href: '#', label: 'Home', icon: HouseIcon, active: true },\n  { href: '#', label: 'Inbox', icon: InboxIcon },\n  { href: '#', label: 'Insights', icon: ZapIcon },\n]\n</script>\n\n<template>\n  <header class=\"border-b px-4 md:px-6\">\n    <div class=\"flex h-16 items-center justify-between gap-4\">\n      <div class=\"flex flex-1 items-center gap-2\">\n        <Popover>\n          <PopoverTrigger as-child>\n            <Button class=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\">\n              <svg\n                class=\"pointer-events-none\"\n                :width=\"16\"\n                :height=\"16\"\n                viewBox=\"0 0 24 24\"\n                fill=\"none\"\n                stroke=\"currentColor\"\n                stroke-width=\"2\"\n                stroke-linecap=\"round\"\n                stroke-linejoin=\"round\"\n                xmlns=\"http://www.w3.org/2000/svg\"\n              >\n                <path\n                  d=\"M4 12L20 12\"\n                  class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\"\n                />\n                <path\n                  d=\"M4 12H20\"\n                  class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\"\n                />\n                <path\n                  d=\"M4 12H20\"\n                  class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\"\n                />\n              </svg>\n            </Button>\n          </PopoverTrigger>\n          <PopoverContent align=\"start\" class=\"w-36 p-1 md:hidden\">\n            <NavigationMenu class=\"max-w-none *:w-full\">\n              <NavigationMenuList class=\"flex-col items-start gap-0 md:gap-2\">\n                <NavigationMenuItem v-for=\"(link, index) in navigationLinks\" :key=\"index\" class=\"w-full\">\n                  <NavigationMenuLink\n                    :href=\"link.href\"\n                    class=\"flex-row items-center gap-2 py-1.5\"\n                    :active=\"link.active\"\n                  >\n                    <component :is=\"link.icon\" :size=\"16\" class=\"text-muted-foreground/80\" aria-hidden=\"true\" />\n                    <span>{{ link.label }}</span>\n                  </NavigationMenuLink>\n                </NavigationMenuItem>\n              </NavigationMenuList>\n            </NavigationMenu>\n          </PopoverContent>\n        </Popover>\n\n        <NavigationMenu class=\"max-md:hidden\">\n          <NavigationMenuList class=\"gap-2\">\n            <NavigationMenuItem v-for=\"(link, index) in navigationLinks\" :key=\"index\">\n              <NavigationMenuLink\n                :active=\"link.active\"\n                :href=\"link.href\"\n                class=\"text-foreground hover:text-primary flex-row items-center gap-2 py-1.5 font-medium\"\n              >\n                <component :is=\"link.icon\" :size=\"16\" class=\"text-muted-foreground/80\" aria-hidden=\"true\" />\n                <span>{{ link.label }}</span>\n              </NavigationMenuLink>\n            </NavigationMenuItem>\n          </NavigationMenuList>\n        </NavigationMenu>\n      </div>\n\n      <div class=\"flex items-center\">\n        <a href=\"#\" class=\"text-primary hover:text-primary/90\">\n          <Logo />\n        </a>\n      </div>\n\n      <div class=\"flex flex-1 items-center justify-end gap-4\">\n        <UserMenu />\n        <Button size=\"sm\" class=\"aspect-square text-sm\">\n          <SparklesIcon class=\"opacity-60 max-sm:hidden sm:-ms-1\" :size=\"16\" aria-hidden=\"true\" />\n          Upgrade\n        </Button>\n      </div>\n    </div>\n  </header>\n</template>\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-12.html",
          "target": "components/ui/navbar-12.html",
          "type": "registry:component",
          "content": "<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 items-center justify-between gap-4\"><div class=\"flex flex-1 items-center gap-2\"><Popover><PopoverTrigger aschild><Button class=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\"><svg class=\"pointer-events-none\" width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></Button></PopoverTrigger><PopoverContent align=\"start\" class=\"w-36 p-1 md:hidden\"><NavigationMenu class=\"max-w-none *:w-full\"><NavigationMenuList class=\"flex-col items-start gap-0 md:gap-2\">${navigationLinks.map((link, index) => {\n                    const Icon = link.icon\n                    return (\n                      <NavigationMenuItem key={index} className=\"w-full\">\n                        <NavigationMenuLink\n                          href={link.href}\n                          className=\"flex-row items-center gap-2 py-1.5\"\n                          active={link.active}\n                        >\n                          <Icon size={16} className=\"text-muted-foreground/80\" aria-hidden=\"true\" />\n                          <span>{link.label}</span>\n                        </NavigationMenuLink>\n                      </NavigationMenuItem>\n                    )\n                  })}</NavigationMenuList></NavigationMenu></PopoverContent></Popover><NavigationMenu class=\"max-md:hidden\"><NavigationMenuList class=\"gap-2\">${navigationLinks.map((link, index) => {\n                const Icon = link.icon\n                return (\n                  <NavigationMenuItem key={index}>\n                    <NavigationMenuLink\n                      active={link.active}\n                      href={link.href}\n                      className=\"text-foreground hover:text-primary flex-row items-center gap-2 py-1.5 font-medium\"\n                    >\n                      <Icon size={16} className=\"text-muted-foreground/80\" aria-hidden=\"true\" />\n                      <span>{link.label}</span>\n                    </NavigationMenuLink>\n                  </NavigationMenuItem>\n                )\n              })}</NavigationMenuList></NavigationMenu></div><div class=\"flex items-center\"><a href=\"#\" class=\"text-primary hover:text-primary/90\"><Logo /></a></div><div class=\"flex flex-1 items-center justify-end gap-4\"><UserMenu /><Button size=\"sm\" class=\"aspect-square text-sm\"><SparklesIcon class=\"opacity-60 max-sm:hidden sm:-ms-1\" size=\"${16}\" aria-hidden=\"true\" />Upgrade\n          </Button></div></div></header>\n</template>"
        },
        {
          "path": "registry/default/components/navbar/navbar-12.wxml",
          "target": "components/ui/navbar-12/navbar-12.wxml",
          "type": "registry:component",
          "content": "<view>\n  <header class=\"border-b px-4 md:px-6\"><view class=\"flex h-16 items-center justify-between gap-4\"><view class=\"flex flex-1 items-center gap-2\"><popover><popovertrigger aschild><button class=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\"><svg class=\"pointer-events-none\" width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></button></popovertrigger><popovercontent align=\"start\" class=\"w-36 p-1 md:hidden\"><navigationmenu class=\"max-w-none *:w-full\"><navigationmenulist class=\"flex-col items-start gap-0 md:gap-2\">{{ navigationLinks.map((link, index) => {\n                    const Icon = link.icon\n                    return (\n                      <NavigationMenuItem key={index} className=\"w-full\">\n                        <NavigationMenuLink\n                          href={link.href}\n                          className=\"flex-row items-center gap-2 py-1.5\"\n                          active={link.active}\n                        >\n                          <Icon size={16} className=\"text-muted-foreground/80\" aria-hidden=\"true\" />\n                          <span>{link.label}</span>\n                        </NavigationMenuLink>\n                      </NavigationMenuItem>\n                    )\n                  }) }}</navigationmenulist></navigationmenu></popovercontent></popover><navigationmenu class=\"max-md:hidden\"><navigationmenulist class=\"gap-2\">{{ navigationLinks.map((link, index) => {\n                const Icon = link.icon\n                return (\n                  <NavigationMenuItem key={index}>\n                    <NavigationMenuLink\n                      active={link.active}\n                      href={link.href}\n                      className=\"text-foreground hover:text-primary flex-row items-center gap-2 py-1.5 font-medium\"\n                    >\n                      <Icon size={16} className=\"text-muted-foreground/80\" aria-hidden=\"true\" />\n                      <span>{link.label}</span>\n                    </NavigationMenuLink>\n                  </NavigationMenuItem>\n                )\n              }) }}</navigationmenulist></navigationmenu></view><view class=\"flex items-center\"><a href=\"#\" class=\"text-primary hover:text-primary/90\"><logo /></a></view><view class=\"flex flex-1 items-center justify-end gap-4\"><usermenu /><button size=\"sm\" class=\"aspect-square text-sm\"><sparklesicon class=\"opacity-60 max-sm:hidden sm:-ms-1\" size=\"{{16}}\" aria-hidden=\"true\" />Upgrade\n          </button></view></view></header>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "navbar, navigation"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "navbar-12",
          "group": "navbar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "navbar-12",
              "path": "registry/default/components/navbar/navbar-12.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "navbar-12",
              "path": "registry/default/components/navbar/navbar-12.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "navbar-12",
              "path": "registry/default/components/navbar/navbar-12.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "navbar-12",
              "path": "registry/default/components/navbar/navbar-12.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "navbars",
        "title": "Navbar · Interactive State"
      },
      "categories": [
        "navbars",
        "navbar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "navbar-13",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/avatar.json",
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/breadcrumb.json",
        "https://ui.timkit.cn/r/dropdown-menu.json",
        "https://ui.timkit.cn/r/navigation-menu.json",
        "https://ui.timkit.cn/r/popover.json",
        "https://ui.timkit.cn/r/select.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/navbar/navbar-13.tsx",
          "type": "registry:component",
          "target": "components/ui/navbar-13.tsx",
          "content": "import { useState } from 'react'\nimport {\n  Breadcrumb,\n  BreadcrumbItem,\n  BreadcrumbList,\n  BreadcrumbSeparator,\n  Button,\n  NavigationMenu,\n  NavigationMenuItem,\n  NavigationMenuLink,\n  NavigationMenuList,\n  Popover,\n  PopoverContent,\n  PopoverTrigger,\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from '@timui/react'\nimport { ChevronsUpDown } from 'lucide-react'\n\nimport SettingsMenu from '@/registry/default/components/navbar-components/settings-menu'\nimport UserMenu from '@/registry/default/components/navbar-components/user-menu'\n\n// Navigation links array to be used in both desktop and mobile menus\nconst navigationLinks = [\n  { href: '#', label: 'Dashboard' },\n  { href: '#', label: 'Docs' },\n  { href: '#', label: 'API reference' },\n]\n\nexport default function Component() {\n  const [accountType, setAccountType] = useState('personal')\n  const [projectValue, setProjectValue] = useState('1')\n\n  return (\n    <header className=\"border-b px-4 md:px-6\">\n      <div className=\"flex h-16 items-center justify-between gap-4\">\n        {/* Left side */}\n        <div className=\"flex items-center gap-2\">\n          {/* Mobile menu trigger */}\n          <Popover>\n            <PopoverTrigger asChild>\n              <Button className=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\">\n                <svg\n                  className=\"pointer-events-none\"\n                  width={16}\n                  height={16}\n                  viewBox=\"0 0 24 24\"\n                  fill=\"none\"\n                  stroke=\"currentColor\"\n                  strokeWidth=\"2\"\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  xmlns=\"http://www.w3.org/2000/svg\"\n                >\n                  <path\n                    d=\"M4 12L20 12\"\n                    className=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\"\n                  />\n                  <path\n                    d=\"M4 12H20\"\n                    className=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\"\n                  />\n                  <path\n                    d=\"M4 12H20\"\n                    className=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\"\n                  />\n                </svg>\n              </Button>\n            </PopoverTrigger>\n            <PopoverContent align=\"start\" className=\"w-36 p-1 md:hidden\">\n              <NavigationMenu className=\"max-w-none *:w-full\">\n                <NavigationMenuList className=\"flex-col items-start gap-0 md:gap-2\">\n                  {navigationLinks.map((link, index) => (\n                    <NavigationMenuItem key={index} className=\"w-full\">\n                      <NavigationMenuLink href={link.href} className=\"py-1.5\">\n                        {link.label}\n                      </NavigationMenuLink>\n                    </NavigationMenuItem>\n                  ))}\n                </NavigationMenuList>\n              </NavigationMenu>\n            </PopoverContent>\n          </Popover>\n          {/* Breadcrumb */}\n          <Breadcrumb>\n            <BreadcrumbList>\n              <BreadcrumbItem>\n                <Select value={accountType} onValueChange={(value) => setAccountType(value)}>\n                  <SelectTrigger aria-label=\"Select account type\" asChild>\n                    <Button\n                      variant=\"ghost\"\n                      className=\"focus-visible:bg-accent text-foreground h-8 p-1.5 focus-visible:ring-0\"\n                    >\n                      <SelectValue placeholder=\"Select account type\" />\n                      <ChevronsUpDown size={14} className=\"text-muted-foreground/80\" />\n                    </Button>\n                  </SelectTrigger>\n                  <SelectContent className=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\">\n                    <SelectItem value=\"personal\">Personal</SelectItem>\n                    <SelectItem value=\"team\">Team</SelectItem>\n                    <SelectItem value=\"business\">Business</SelectItem>\n                  </SelectContent>\n                </Select>\n              </BreadcrumbItem>\n              <BreadcrumbSeparator> / </BreadcrumbSeparator>\n              <BreadcrumbItem>\n                <Select value={projectValue} onValueChange={(value) => setProjectValue(value)}>\n                  <SelectTrigger aria-label=\"Select project\" asChild>\n                    <Button\n                      variant=\"ghost\"\n                      className=\"focus-visible:bg-accent text-foreground h-8 p-1.5 focus-visible:ring-0\"\n                    >\n                      <SelectValue placeholder=\"Select project\" />\n                      <ChevronsUpDown size={14} className=\"text-muted-foreground/80\" />\n                    </Button>\n                  </SelectTrigger>\n                  <SelectContent className=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\">\n                    <SelectItem value=\"1\">Main project</SelectItem>\n                    <SelectItem value=\"2\">Origin project</SelectItem>\n                  </SelectContent>\n                </Select>\n              </BreadcrumbItem>\n            </BreadcrumbList>\n          </Breadcrumb>\n        </div>\n        {/* Right side */}\n        <div className=\"flex items-center gap-4\">\n          <div className=\"flex items-center gap-2\">\n            {/* Nav menu */}\n            <NavigationMenu className=\"max-md:hidden\">\n              <NavigationMenuList className=\"gap-2\">\n                {navigationLinks.map((link, index) => (\n                  <NavigationMenuItem key={index}>\n                    <NavigationMenuLink\n                      href={link.href}\n                      className=\"text-muted-foreground hover:text-primary py-1.5 font-medium\"\n                    >\n                      {link.label}\n                    </NavigationMenuLink>\n                  </NavigationMenuItem>\n                ))}\n              </NavigationMenuList>\n            </NavigationMenu>\n            {/* Settings */}\n            <SettingsMenu />\n          </div>\n          {/* User menu */}\n          <UserMenu />\n        </div>\n      </div>\n    </header>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/settings-menu.tsx",
          "type": "registry:component",
          "target": "components/ui/settings-menu.tsx",
          "content": "import {\n  Button,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuTrigger,\n} from '@timui/react'\nimport { SettingsIcon } from 'lucide-react'\n\nexport default function SettingsMenu() {\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button\n          size=\"icon\"\n          variant=\"ghost\"\n          className=\"rounded-full shadow-none\"\n          aria-label=\"Open edit menu\"\n        >\n          <SettingsIcon className=\"text-muted-foreground\" size={16} aria-hidden=\"true\" />\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent className=\"max-w-64\">\n        <DropdownMenuItem>Appearance</DropdownMenuItem>\n        <DropdownMenuItem>Preferences</DropdownMenuItem>\n        <DropdownMenuItem>API Settings</DropdownMenuItem>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/user-menu.tsx",
          "type": "registry:component",
          "target": "components/ui/user-menu.tsx",
          "content": "import {\n  Avatar,\n  AvatarFallback,\n  AvatarImage,\n  Button,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from '@timui/react'\nimport { BoltIcon, BookOpenIcon, Layers2Icon, LogOutIcon, PinIcon, UserPenIcon } from 'lucide-react'\n\nexport default function UserMenu() {\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button variant=\"ghost\" className=\"h-auto p-0 hover:bg-transparent\">\n          <Avatar>\n            <AvatarImage src=\"./avatar.jpg\" alt=\"Profile image\" />\n            <AvatarFallback>KK</AvatarFallback>\n          </Avatar>\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent className=\"max-w-64\" align=\"end\">\n        <DropdownMenuLabel className=\"flex min-w-0 flex-col\">\n          <span className=\"text-foreground truncate text-sm font-medium\">Keith Kennedy</span>\n          <span className=\"text-muted-foreground truncate text-xs font-normal\">\n            k.kennedy@ui.timkit.cn\n          </span>\n        </DropdownMenuLabel>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <BoltIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 1</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <Layers2Icon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 2</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <BookOpenIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 3</span>\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <PinIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 4</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <UserPenIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 5</span>\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuItem>\n          <LogOutIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n          <span>Logout</span>\n        </DropdownMenuItem>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-13.vue",
          "target": "components/ui/navbar-13.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { ChevronsUpDown } from 'lucide-vue-next';\nimport { Breadcrumb, BreadcrumbItem, BreadcrumbList, BreadcrumbSeparator } from '@timui/vue';\nimport { Button } from '@timui/vue';\nimport { NavigationMenu, NavigationMenuItem, NavigationMenuLink, NavigationMenuList } from '@timui/vue';\nimport { Popover, PopoverContent, PopoverTrigger } from '@timui/vue';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@timui/vue';\nimport SettingsMenu from '@/registry/default/components/navbar-components/settings-menu.vue';\nimport UserMenu from '@/registry/default/components/navbar-components/user-menu.vue';\n\nconst navigationLinks = [\n  { href: '#', label: 'Dashboard' },\n  { href: '#', label: 'Docs' },\n  { href: '#', label: 'API reference' },\n];\nconst accountType = ref('personal');\nconst projectValue = ref('1');\n\n</script>\n\n<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 items-center justify-between gap-4\"><div class=\"flex items-center gap-2\"><Popover><PopoverTrigger as-child><Button class=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\"><svg class=\"pointer-events-none\" :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></Button></PopoverTrigger><PopoverContent align=\"start\" class=\"w-36 p-1 md:hidden\"><NavigationMenu class=\"max-w-none *:w-full\"><NavigationMenuList class=\"flex-col items-start gap-0 md:gap-2\"><NavigationMenuItem v-for=\"(link, index) in navigationLinks\" :key=\"index\" class=\"w-full\"><NavigationMenuLink :href=\"link.href\" class=\"py-1.5\">{{ link.label }}</NavigationMenuLink></NavigationMenuItem></NavigationMenuList></NavigationMenu></PopoverContent></Popover><Breadcrumb><BreadcrumbList><BreadcrumbItem><Select v-model=\"accountType\"><SelectTrigger aria-label=\"Select account type\" as-child><Button variant=\"ghost\" class=\"focus-visible:bg-accent text-foreground h-8 p-1.5 focus-visible:ring-0\"><SelectValue placeholder=\"Select account type\" /><ChevronsUpDown :size=\"14\" class=\"text-muted-foreground/80\" /></Button></SelectTrigger><SelectContent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\"><SelectItem value=\"personal\">Personal</SelectItem><SelectItem value=\"team\">Team</SelectItem><SelectItem value=\"business\">Business</SelectItem></SelectContent></Select></BreadcrumbItem><BreadcrumbSeparator>/ </BreadcrumbSeparator><BreadcrumbItem><Select v-model=\"projectValue\"><SelectTrigger aria-label=\"Select project\" as-child><Button variant=\"ghost\" class=\"focus-visible:bg-accent text-foreground h-8 p-1.5 focus-visible:ring-0\"><SelectValue placeholder=\"Select project\" /><ChevronsUpDown :size=\"14\" class=\"text-muted-foreground/80\" /></Button></SelectTrigger><SelectContent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\"><SelectItem value=\"1\">Main project</SelectItem><SelectItem value=\"2\">Origin project</SelectItem></SelectContent></Select></BreadcrumbItem></BreadcrumbList></Breadcrumb></div><div class=\"flex items-center gap-4\"><div class=\"flex items-center gap-2\"><NavigationMenu class=\"max-md:hidden\"><NavigationMenuList class=\"gap-2\"><NavigationMenuItem v-for=\"(link, index) in navigationLinks\" :key=\"index\"><NavigationMenuLink :href=\"link.href\" class=\"text-muted-foreground hover:text-primary py-1.5 font-medium\">{{ link.label }}</NavigationMenuLink></NavigationMenuItem></NavigationMenuList></NavigationMenu><SettingsMenu /></div><UserMenu /></div></div></header>\n</template>\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-13.html",
          "target": "components/ui/navbar-13.html",
          "type": "registry:component",
          "content": "<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 items-center justify-between gap-4\"><div class=\"flex items-center gap-2\"><Popover><PopoverTrigger aschild><Button class=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\"><svg class=\"pointer-events-none\" width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></Button></PopoverTrigger><PopoverContent align=\"start\" class=\"w-36 p-1 md:hidden\"><NavigationMenu class=\"max-w-none *:w-full\"><NavigationMenuList class=\"flex-col items-start gap-0 md:gap-2\"><!-- Loop navigationLinks -->\n<NavigationMenuItem key=\"${index}\" class=\"w-full\"><NavigationMenuLink href=\"${link.href}\" class=\"py-1.5\">${link.label}</NavigationMenuLink></NavigationMenuItem>\n<!-- End Loop --></NavigationMenuList></NavigationMenu></PopoverContent></Popover><Breadcrumb><BreadcrumbList><BreadcrumbItem><Select default-value=\"personal\"><SelectTrigger aria-label=\"Select account type\" aschild><Button variant=\"ghost\" class=\"focus-visible:bg-accent text-foreground h-8 p-1.5 focus-visible:ring-0\"><SelectValue placeholder=\"Select account type\" /><ChevronsUpDown size=\"${14}\" class=\"text-muted-foreground/80\" /></Button></SelectTrigger><SelectContent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\"><SelectItem value=\"personal\">Personal</SelectItem><SelectItem value=\"team\">Team</SelectItem><SelectItem value=\"business\">Business</SelectItem></SelectContent></Select></BreadcrumbItem><BreadcrumbSeparator>/ </BreadcrumbSeparator><BreadcrumbItem><Select default-value=\"1\"><SelectTrigger aria-label=\"Select project\" aschild><Button variant=\"ghost\" class=\"focus-visible:bg-accent text-foreground h-8 p-1.5 focus-visible:ring-0\"><SelectValue placeholder=\"Select project\" /><ChevronsUpDown size=\"${14}\" class=\"text-muted-foreground/80\" /></Button></SelectTrigger><SelectContent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\"><SelectItem value=\"1\">Main project</SelectItem><SelectItem value=\"2\">Origin project</SelectItem></SelectContent></Select></BreadcrumbItem></BreadcrumbList></Breadcrumb></div><div class=\"flex items-center gap-4\"><div class=\"flex items-center gap-2\"><NavigationMenu class=\"max-md:hidden\"><NavigationMenuList class=\"gap-2\"><!-- Loop navigationLinks -->\n<NavigationMenuItem key=\"${index}\"><NavigationMenuLink href=\"${link.href}\" class=\"text-muted-foreground hover:text-primary py-1.5 font-medium\">${link.label}</NavigationMenuLink></NavigationMenuItem>\n<!-- End Loop --></NavigationMenuList></NavigationMenu><SettingsMenu /></div><UserMenu /></div></div></header>\n</template>"
        },
        {
          "path": "registry/default/components/navbar/navbar-13.wxml",
          "target": "components/ui/navbar-13/navbar-13.wxml",
          "type": "registry:component",
          "content": "<view>\n  <header class=\"border-b px-4 md:px-6\"><view class=\"flex h-16 items-center justify-between gap-4\"><view class=\"flex items-center gap-2\"><popover><popovertrigger aschild><button class=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\"><svg class=\"pointer-events-none\" width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></button></popovertrigger><popovercontent align=\"start\" class=\"w-36 p-1 md:hidden\"><navigationmenu class=\"max-w-none *:w-full\"><navigationmenulist class=\"flex-col items-start gap-0 md:gap-2\"><navigationmenuitem wx:for=\"{{navigationLinks}}\" wx:for-item=\"link\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{index}}\" class=\"w-full\"><navigationmenulink href=\"{{link.href}}\" class=\"py-1.5\">{{ link.label }}</navigationmenulink></navigationmenuitem></navigationmenulist></navigationmenu></popovercontent></popover><breadcrumb><breadcrumblist><breadcrumbitem><select default-value=\"personal\"><selecttrigger aria-label=\"Select account type\" aschild><button variant=\"ghost\" class=\"focus-visible:bg-accent text-foreground h-8 p-1.5 focus-visible:ring-0\"><selectvalue placeholder=\"Select account type\" /><chevronsupdown size=\"{{14}}\" class=\"text-muted-foreground/80\" /></button></selecttrigger><selectcontent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\"><selectitem value=\"personal\">Personal</selectitem><selectitem value=\"team\">Team</selectitem><selectitem value=\"business\">Business</selectitem></selectcontent></select></breadcrumbitem><breadcrumbseparator>/ </breadcrumbseparator><breadcrumbitem><select default-value=\"1\"><selecttrigger aria-label=\"Select project\" aschild><button variant=\"ghost\" class=\"focus-visible:bg-accent text-foreground h-8 p-1.5 focus-visible:ring-0\"><selectvalue placeholder=\"Select project\" /><chevronsupdown size=\"{{14}}\" class=\"text-muted-foreground/80\" /></button></selecttrigger><selectcontent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\"><selectitem value=\"1\">Main project</selectitem><selectitem value=\"2\">Origin project</selectitem></selectcontent></select></breadcrumbitem></breadcrumblist></breadcrumb></view><view class=\"flex items-center gap-4\"><view class=\"flex items-center gap-2\"><navigationmenu class=\"max-md:hidden\"><navigationmenulist class=\"gap-2\"><navigationmenuitem wx:for=\"{{navigationLinks}}\" wx:for-item=\"link\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{index}}\"><navigationmenulink href=\"{{link.href}}\" class=\"text-muted-foreground hover:text-primary py-1.5 font-medium\">{{ link.label }}</navigationmenulink></navigationmenuitem></navigationmenulist></navigationmenu><settingsmenu /></view><usermenu /></view></view></header>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "navbar, navigation"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "navbar-13",
          "group": "navbar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "navbar-13",
              "path": "registry/default/components/navbar/navbar-13.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "navbar-13",
              "path": "registry/default/components/navbar/navbar-13.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "navbar-13",
              "path": "registry/default/components/navbar/navbar-13.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "navbar-13",
              "path": "registry/default/components/navbar/navbar-13.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "navbars",
        "title": "Navbar · Select account type"
      },
      "categories": [
        "navbars",
        "navbar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "navbar-14",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/avatar.json",
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dropdown-menu.json",
        "https://ui.timkit.cn/r/navigation-menu.json",
        "https://ui.timkit.cn/r/popover.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/navbar/navbar-14.tsx",
          "type": "registry:component",
          "target": "components/ui/navbar-14.tsx",
          "content": "import {\n  Button,\n  NavigationMenu,\n  NavigationMenuItem,\n  NavigationMenuLink,\n  NavigationMenuList,\n  Popover,\n  PopoverContent,\n  PopoverTrigger,\n} from '@timui/react'\nimport { CompassIcon, FeatherIcon, HouseIcon, PlusIcon, SearchIcon } from 'lucide-react'\n\nimport NotificationMenu from '@/registry/default/components/navbar-components/notification-menu'\nimport TeamSwitcher from '@/registry/default/components/navbar-components/team-switcher'\nimport UserMenu from '@/registry/default/components/navbar-components/user-menu'\n\nconst teams = ['Acme Inc.', 'Timkit UI', 'Junon']\n\n// Navigation links array to be used in both desktop and mobile menus\nconst navigationLinks = [\n  { href: '#', label: 'Dashboard', icon: HouseIcon },\n  { href: '#', label: 'Explore', icon: CompassIcon },\n  { href: '#', label: 'Write', icon: FeatherIcon },\n  { href: '#', label: 'Search', icon: SearchIcon },\n]\n\nexport default function Component() {\n  return (\n    <header className=\"border-b px-4 md:px-6\">\n      <div className=\"flex h-16 items-center justify-between gap-4\">\n        {/* Left side */}\n        <div className=\"flex flex-1 items-center gap-2\">\n          {/* Mobile menu trigger */}\n          <Popover>\n            <PopoverTrigger asChild>\n              <Button className=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\">\n                <svg\n                  className=\"pointer-events-none\"\n                  width={16}\n                  height={16}\n                  viewBox=\"0 0 24 24\"\n                  fill=\"none\"\n                  stroke=\"currentColor\"\n                  strokeWidth=\"2\"\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  xmlns=\"http://www.w3.org/2000/svg\"\n                >\n                  <path\n                    d=\"M4 12L20 12\"\n                    className=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\"\n                  />\n                  <path\n                    d=\"M4 12H20\"\n                    className=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\"\n                  />\n                  <path\n                    d=\"M4 12H20\"\n                    className=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\"\n                  />\n                </svg>\n              </Button>\n            </PopoverTrigger>\n            <PopoverContent align=\"start\" className=\"w-48 p-1 md:hidden\">\n              <NavigationMenu className=\"max-w-none *:w-full\">\n                <NavigationMenuList className=\"flex-col items-start gap-0 md:gap-2\">\n                  {navigationLinks.map((link, index) => {\n                    const Icon = link.icon\n                    return (\n                      <NavigationMenuItem key={index} className=\"w-full\">\n                        <NavigationMenuLink\n                          href={link.href}\n                          className=\"flex-row items-center gap-2 py-1.5\"\n                        >\n                          <Icon size={16} className=\"text-muted-foreground\" aria-hidden=\"true\" />\n                          <span>{link.label}</span>\n                        </NavigationMenuLink>\n                      </NavigationMenuItem>\n                    )\n                  })}\n                </NavigationMenuList>\n              </NavigationMenu>\n            </PopoverContent>\n          </Popover>\n          <TeamSwitcher teams={teams} defaultTeam={teams[0]} />\n        </div>\n        {/* Middle area */}\n        <NavigationMenu className=\"max-md:hidden\">\n          <NavigationMenuList className=\"gap-2\">\n            {navigationLinks.map((link, index) => {\n              const Icon = link.icon\n              return (\n                <NavigationMenuItem key={index}>\n                  <NavigationMenuLink\n                    href={link.href}\n                    className=\"flex size-8 items-center justify-center p-1.5\"\n                    title={link.label}\n                  >\n                    <Icon aria-hidden=\"true\" />\n                    <span className=\"sr-only\">{link.label}</span>\n                  </NavigationMenuLink>\n                </NavigationMenuItem>\n              )\n            })}\n          </NavigationMenuList>\n        </NavigationMenu>\n        {/* Right side */}\n        <div className=\"flex flex-1 items-center justify-end gap-4\">\n          <Button size=\"sm\" className=\"aspect-square text-sm max-sm:p-0\">\n            <PlusIcon className=\"opacity-60 sm:-ms-1\" size={16} aria-hidden=\"true\" />\n            <span className=\"max-sm:sr-only\">Post</span>\n          </Button>\n          <NotificationMenu />\n          <UserMenu />\n        </div>\n      </div>\n    </header>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/notification-menu.tsx",
          "type": "registry:component",
          "target": "components/ui/notification-menu.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Button, Popover, PopoverContent, PopoverTrigger } from '@timui/react'\nimport { BellIcon } from 'lucide-react'\n\nconst initialNotifications = [\n  {\n    id: 1,\n    user: 'Chris Tompson',\n    action: 'requested review on',\n    target: 'PR #42: Feature implementation',\n    timestamp: '15 minutes ago',\n    unread: true,\n  },\n  {\n    id: 2,\n    user: 'Emma Davis',\n    action: 'shared',\n    target: 'New component library',\n    timestamp: '45 minutes ago',\n    unread: true,\n  },\n  {\n    id: 3,\n    user: 'James Wilson',\n    action: 'assigned you to',\n    target: 'API integration task',\n    timestamp: '4 hours ago',\n    unread: false,\n  },\n  {\n    id: 4,\n    user: 'Alex Morgan',\n    action: 'replied to your comment in',\n    target: 'Authentication flow',\n    timestamp: '12 hours ago',\n    unread: false,\n  },\n  {\n    id: 5,\n    user: 'Sarah Chen',\n    action: 'commented on',\n    target: 'Dashboard redesign',\n    timestamp: '2 days ago',\n    unread: false,\n  },\n  {\n    id: 6,\n    user: 'Miky Derya',\n    action: 'mentioned you in',\n    target: 'Timkit UI open graph image',\n    timestamp: '2 weeks ago',\n    unread: false,\n  },\n]\n\nfunction Dot({ className }: { className?: string }) {\n  return (\n    <svg\n      width=\"6\"\n      height=\"6\"\n      fill=\"currentColor\"\n      viewBox=\"0 0 6 6\"\n      xmlns=\"http://www.w3.org/2000/svg\"\n      className={className}\n      aria-hidden=\"true\"\n    >\n      <circle cx=\"3\" cy=\"3\" r=\"3\" />\n    </svg>\n  )\n}\n\nexport default function NotificationMenu() {\n  const [notifications, setNotifications] = useState(initialNotifications)\n  const unreadCount = notifications.filter((n) => n.unread).length\n\n  const handleMarkAllAsRead = () => {\n    setNotifications(\n      notifications.map((notification) => ({\n        ...notification,\n        unread: false,\n      }))\n    )\n  }\n\n  const handleNotificationClick = (id: number) => {\n    setNotifications(\n      notifications.map((notification) =>\n        notification.id === id ? { ...notification, unread: false } : notification\n      )\n    )\n  }\n\n  return (\n    <Popover>\n      <PopoverTrigger asChild>\n        <Button\n          size=\"icon\"\n          variant=\"ghost\"\n          className=\"text-muted-foreground relative size-8 rounded-full shadow-none\"\n          aria-label=\"Open notifications\"\n        >\n          <BellIcon size={16} aria-hidden=\"true\" />\n          {unreadCount > 0 && (\n            <div\n              aria-hidden=\"true\"\n              className=\"bg-primary absolute top-0.5 right-0.5 size-1 rounded-full\"\n            />\n          )}\n        </Button>\n      </PopoverTrigger>\n      <PopoverContent className=\"w-80 p-1\">\n        <div className=\"flex items-baseline justify-between gap-4 px-3 py-2\">\n          <div className=\"text-sm font-semibold\">Notifications</div>\n          {unreadCount > 0 && (\n            <button className=\"text-xs font-medium hover:underline\" onClick={handleMarkAllAsRead}>\n              Mark all as read\n            </button>\n          )}\n        </div>\n        <div\n          role=\"separator\"\n          aria-orientation=\"horizontal\"\n          className=\"bg-border -mx-1 my-1 h-px\"\n        ></div>\n        {notifications.map((notification) => (\n          <div\n            key={notification.id}\n            className=\"hover:bg-accent rounded-md px-3 py-2 text-sm transition-colors\"\n          >\n            <div className=\"relative flex items-start pe-3\">\n              <div className=\"flex-1 space-y-1\">\n                <button\n                  className=\"text-foreground/80 text-left after:absolute after:inset-0\"\n                  onClick={() => handleNotificationClick(notification.id)}\n                >\n                  <span className=\"text-foreground font-medium hover:underline\">\n                    {notification.user}\n                  </span>{' '}\n                  {notification.action}{' '}\n                  <span className=\"text-foreground font-medium hover:underline\">\n                    {notification.target}\n                  </span>\n                  .\n                </button>\n                <div className=\"text-muted-foreground text-xs\">{notification.timestamp}</div>\n              </div>\n              {notification.unread && (\n                <div className=\"absolute end-0 self-center\">\n                  <span className=\"sr-only\">Unread</span>\n                  <Dot />\n                </div>\n              )}\n            </div>\n          </div>\n        ))}\n      </PopoverContent>\n    </Popover>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/team-switcher.tsx",
          "type": "registry:component",
          "target": "components/ui/team-switcher.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport {\n  Button,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuTrigger,\n} from '@timui/react'\nimport { ChevronsUpDown } from 'lucide-react'\n\nexport default function TeamSwitcher({\n  teams,\n  defaultTeam,\n}: {\n  teams: string[]\n  defaultTeam: string\n}) {\n  const [selectedProject, setSelectedProject] = React.useState(defaultTeam)\n\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button variant=\"ghost\" className=\"p-0 hover:bg-transparent\">\n          <span className=\"bg-primary text-primary-foreground flex size-8 items-center justify-center rounded-full\">\n            {selectedProject.charAt(0).toUpperCase()}\n          </span>\n          <div className=\"flex flex-col gap-0.5 leading-none\">\n            <span className=\"\">{selectedProject}</span>\n          </div>\n          <ChevronsUpDown size={14} className=\"text-muted-foreground/80\" />\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent align=\"start\">\n        {teams.map((project) => (\n          <DropdownMenuItem key={project} onClick={() => setSelectedProject(project)}>\n            {project}\n          </DropdownMenuItem>\n        ))}\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/user-menu.tsx",
          "type": "registry:component",
          "target": "components/ui/user-menu.tsx",
          "content": "import {\n  Avatar,\n  AvatarFallback,\n  AvatarImage,\n  Button,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from '@timui/react'\nimport { BoltIcon, BookOpenIcon, Layers2Icon, LogOutIcon, PinIcon, UserPenIcon } from 'lucide-react'\n\nexport default function UserMenu() {\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button variant=\"ghost\" className=\"h-auto p-0 hover:bg-transparent\">\n          <Avatar>\n            <AvatarImage src=\"./avatar.jpg\" alt=\"Profile image\" />\n            <AvatarFallback>KK</AvatarFallback>\n          </Avatar>\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent className=\"max-w-64\" align=\"end\">\n        <DropdownMenuLabel className=\"flex min-w-0 flex-col\">\n          <span className=\"text-foreground truncate text-sm font-medium\">Keith Kennedy</span>\n          <span className=\"text-muted-foreground truncate text-xs font-normal\">\n            k.kennedy@ui.timkit.cn\n          </span>\n        </DropdownMenuLabel>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <BoltIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 1</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <Layers2Icon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 2</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <BookOpenIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 3</span>\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <PinIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 4</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <UserPenIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 5</span>\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuItem>\n          <LogOutIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n          <span>Logout</span>\n        </DropdownMenuItem>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-14.vue",
          "target": "components/ui/navbar-14.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { CompassIcon, FeatherIcon, HouseIcon, PlusIcon, SearchIcon } from 'lucide-vue-next'\nimport { Button } from '@timui/vue'\nimport {\n  NavigationMenu,\n  NavigationMenuItem,\n  NavigationMenuLink,\n  NavigationMenuList,\n} from '@timui/vue'\nimport { Popover, PopoverContent, PopoverTrigger } from '@timui/vue'\nimport NotificationMenu from '@/registry/default/components/navbar-components/notification-menu.vue'\nimport TeamSwitcher from '@/registry/default/components/navbar-components/team-switcher.vue'\nimport UserMenu from '@/registry/default/components/navbar-components/user-menu.vue'\n\nconst teams = ['Acme Inc.', 'Timkit UI', 'Junon']\n\nconst navigationLinks = [\n  { href: '#', label: 'Dashboard', icon: HouseIcon },\n  { href: '#', label: 'Explore', icon: CompassIcon },\n  { href: '#', label: 'Write', icon: FeatherIcon },\n  { href: '#', label: 'Search', icon: SearchIcon },\n]\n</script>\n\n<template>\n  <header class=\"border-b px-4 md:px-6\">\n    <div class=\"flex h-16 items-center justify-between gap-4\">\n      <div class=\"flex flex-1 items-center gap-2\">\n        <Popover>\n          <PopoverTrigger as-child>\n            <Button class=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\">\n              <svg\n                class=\"pointer-events-none\"\n                :width=\"16\"\n                :height=\"16\"\n                viewBox=\"0 0 24 24\"\n                fill=\"none\"\n                stroke=\"currentColor\"\n                stroke-width=\"2\"\n                stroke-linecap=\"round\"\n                stroke-linejoin=\"round\"\n                xmlns=\"http://www.w3.org/2000/svg\"\n              >\n                <path\n                  d=\"M4 12L20 12\"\n                  class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\"\n                />\n                <path\n                  d=\"M4 12H20\"\n                  class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\"\n                />\n                <path\n                  d=\"M4 12H20\"\n                  class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\"\n                />\n              </svg>\n            </Button>\n          </PopoverTrigger>\n          <PopoverContent align=\"start\" class=\"w-48 p-1 md:hidden\">\n            <NavigationMenu class=\"max-w-none *:w-full\">\n              <NavigationMenuList class=\"flex-col items-start gap-0 md:gap-2\">\n                <NavigationMenuItem v-for=\"(link, index) in navigationLinks\" :key=\"index\" class=\"w-full\">\n                  <NavigationMenuLink :href=\"link.href\" class=\"flex-row items-center gap-2 py-1.5\">\n                    <component :is=\"link.icon\" :size=\"16\" class=\"text-muted-foreground\" aria-hidden=\"true\" />\n                    <span>{{ link.label }}</span>\n                  </NavigationMenuLink>\n                </NavigationMenuItem>\n              </NavigationMenuList>\n            </NavigationMenu>\n          </PopoverContent>\n        </Popover>\n\n        <TeamSwitcher :teams=\"teams\" :defaultTeam=\"teams[0]\" />\n      </div>\n\n      <NavigationMenu class=\"max-md:hidden\">\n        <NavigationMenuList class=\"gap-2\">\n          <NavigationMenuItem v-for=\"(link, index) in navigationLinks\" :key=\"index\">\n            <NavigationMenuLink\n              :href=\"link.href\"\n              class=\"flex size-8 items-center justify-center p-1.5\"\n              :title=\"link.label\"\n            >\n              <component :is=\"link.icon\" aria-hidden=\"true\" />\n              <span class=\"sr-only\">{{ link.label }}</span>\n            </NavigationMenuLink>\n          </NavigationMenuItem>\n        </NavigationMenuList>\n      </NavigationMenu>\n\n      <div class=\"flex flex-1 items-center justify-end gap-4\">\n        <Button size=\"sm\" class=\"aspect-square text-sm max-sm:p-0\">\n          <PlusIcon class=\"opacity-60 sm:-ms-1\" :size=\"16\" aria-hidden=\"true\" />\n          <span class=\"max-sm:sr-only\">Post</span>\n        </Button>\n        <NotificationMenu />\n        <UserMenu />\n      </div>\n    </div>\n  </header>\n</template>\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-14.html",
          "target": "components/ui/navbar-14.html",
          "type": "registry:component",
          "content": "<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 items-center justify-between gap-4\"><div class=\"flex flex-1 items-center gap-2\"><Popover><PopoverTrigger aschild><Button class=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\"><svg class=\"pointer-events-none\" width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></Button></PopoverTrigger><PopoverContent align=\"start\" class=\"w-48 p-1 md:hidden\"><NavigationMenu class=\"max-w-none *:w-full\"><NavigationMenuList class=\"flex-col items-start gap-0 md:gap-2\">${navigationLinks.map((link, index) => {\n                    const Icon = link.icon\n                    return (\n                      <NavigationMenuItem key={index} className=\"w-full\">\n                        <NavigationMenuLink\n                          href={link.href}\n                          className=\"flex-row items-center gap-2 py-1.5\"\n                        >\n                          <Icon size={16} className=\"text-muted-foreground\" aria-hidden=\"true\" />\n                          <span>{link.label}</span>\n                        </NavigationMenuLink>\n                      </NavigationMenuItem>\n                    )\n                  })}</NavigationMenuList></NavigationMenu></PopoverContent></Popover><TeamSwitcher teams=\"${teams}\" defaultteam=\"${teams[0]}\" /></div><NavigationMenu class=\"max-md:hidden\"><NavigationMenuList class=\"gap-2\">${navigationLinks.map((link, index) => {\n              const Icon = link.icon\n              return (\n                <NavigationMenuItem key={index}>\n                  <NavigationMenuLink\n                    href={link.href}\n                    className=\"flex size-8 items-center justify-center p-1.5\"\n                    title={link.label}\n                  >\n                    <Icon aria-hidden=\"true\" />\n                    <span className=\"sr-only\">{link.label}</span>\n                  </NavigationMenuLink>\n                </NavigationMenuItem>\n              )\n            })}</NavigationMenuList></NavigationMenu><div class=\"flex flex-1 items-center justify-end gap-4\"><Button size=\"sm\" class=\"aspect-square text-sm max-sm:p-0\"><PlusIcon class=\"opacity-60 sm:-ms-1\" size=\"${16}\" aria-hidden=\"true\" /><span class=\"max-sm:sr-only\">Post</span></Button><NotificationMenu /><UserMenu /></div></div></header>\n</template>"
        },
        {
          "path": "registry/default/components/navbar/navbar-14.wxml",
          "target": "components/ui/navbar-14/navbar-14.wxml",
          "type": "registry:component",
          "content": "<view>\n  <header class=\"border-b px-4 md:px-6\"><view class=\"flex h-16 items-center justify-between gap-4\"><view class=\"flex flex-1 items-center gap-2\"><popover><popovertrigger aschild><button class=\"group size-8 md:hidden\" variant=\"ghost\" size=\"icon\"><svg class=\"pointer-events-none\" width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></button></popovertrigger><popovercontent align=\"start\" class=\"w-48 p-1 md:hidden\"><navigationmenu class=\"max-w-none *:w-full\"><navigationmenulist class=\"flex-col items-start gap-0 md:gap-2\">{{ navigationLinks.map((link, index) => {\n                    const Icon = link.icon\n                    return (\n                      <NavigationMenuItem key={index} className=\"w-full\">\n                        <NavigationMenuLink\n                          href={link.href}\n                          className=\"flex-row items-center gap-2 py-1.5\"\n                        >\n                          <Icon size={16} className=\"text-muted-foreground\" aria-hidden=\"true\" />\n                          <span>{link.label}</span>\n                        </NavigationMenuLink>\n                      </NavigationMenuItem>\n                    )\n                  }) }}</navigationmenulist></navigationmenu></popovercontent></popover><teamswitcher teams=\"{{teams}}\" defaultteam=\"{{teams[0]}}\" /></view><navigationmenu class=\"max-md:hidden\"><navigationmenulist class=\"gap-2\">{{ navigationLinks.map((link, index) => {\n              const Icon = link.icon\n              return (\n                <NavigationMenuItem key={index}>\n                  <NavigationMenuLink\n                    href={link.href}\n                    className=\"flex size-8 items-center justify-center p-1.5\"\n                    title={link.label}\n                  >\n                    <Icon aria-hidden=\"true\" />\n                    <span className=\"sr-only\">{link.label}</span>\n                  </NavigationMenuLink>\n                </NavigationMenuItem>\n              )\n            }) }}</navigationmenulist></navigationmenu><view class=\"flex flex-1 items-center justify-end gap-4\"><button size=\"sm\" class=\"aspect-square text-sm max-sm:p-0\"><plusicon class=\"opacity-60 sm:-ms-1\" size=\"{{16}}\" aria-hidden=\"true\" /><text class=\"max-sm:sr-only\">Post</text></button><notificationmenu /><usermenu /></view></view></header>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "navbar, navigation"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "navbar-14",
          "group": "navbar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "navbar-14",
              "path": "registry/default/components/navbar/navbar-14.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "navbar-14",
              "path": "registry/default/components/navbar/navbar-14.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "navbar-14",
              "path": "registry/default/components/navbar/navbar-14.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "navbar-14",
              "path": "registry/default/components/navbar/navbar-14.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "navbars",
        "title": "Navbar · Overlay Pattern"
      },
      "categories": [
        "navbars",
        "navbar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "navbar-15",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/avatar.json",
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dropdown-menu.json",
        "https://ui.timkit.cn/r/select.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/navbar/navbar-15.tsx",
          "type": "registry:component",
          "target": "components/ui/navbar-15.tsx",
          "content": "import {\n  Button,\n  Select,\n  SelectContent,\n  SelectGroup,\n  SelectItem,\n  SelectLabel,\n  SelectTrigger,\n  SelectValue,\n} from '@timui/react'\nimport { BotMessageSquareIcon, MessageCircleDashedIcon } from 'lucide-react'\n\nimport UserMenu from '@/registry/default/components/navbar-components/user-menu'\n\nexport default function Component() {\n  return (\n    <header className=\"border-b px-4 md:px-6\">\n      <div className=\"flex h-16 items-center justify-between gap-4\">\n        {/* Left side */}\n        <div>\n          <Select defaultValue=\"orion-alpha-45\" aria-label=\"Select AI model\">\n            <SelectTrigger className=\"[&>svg]:text-muted-foreground/80 **:data-desc:hidden [&>svg]:shrink-0\">\n              <BotMessageSquareIcon size={16} aria-hidden=\"true\" />\n              <SelectValue placeholder=\"Choose an AI model\" />\n            </SelectTrigger>\n            <SelectContent className=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\">\n              <SelectGroup>\n                <SelectLabel className=\"ps-2\">Models</SelectLabel>\n                <SelectItem value=\"orion-alpha-45\">\n                  Orion-Alpha 4.5\n                  <span className=\"text-muted-foreground mt-1 block text-xs\" data-desc>\n                    Balanced performance and creativity\n                  </span>\n                </SelectItem>\n                <SelectItem value=\"orion-code-4\">\n                  Orion-Code 4\n                  <span className=\"text-muted-foreground mt-1 block text-xs\" data-desc>\n                    Optimized for code generation and understanding\n                  </span>\n                </SelectItem>\n                <SelectItem value=\"nova-chat-4\">\n                  Nova-Chat 4\n                  <span className=\"text-muted-foreground mt-1 block text-xs\" data-desc>\n                    Excels at natural, engaging conversations\n                  </span>\n                </SelectItem>\n                <SelectItem value=\"galaxy-max-4\">\n                  Galaxy-Max 4\n                  <span className=\"text-muted-foreground mt-1 block text-xs\" data-desc>\n                    Most powerful model for complex tasks\n                  </span>\n                </SelectItem>\n              </SelectGroup>\n            </SelectContent>\n          </Select>\n        </div>\n\n        {/* Right side: Actions */}\n        <div className=\"flex items-center justify-end gap-2\">\n          {/* Layout button */}\n          <Button\n            size=\"icon\"\n            variant=\"ghost\"\n            className=\"text-muted-foreground size-8 rounded-full shadow-none\"\n            aria-label=\"Temporary chat\"\n          >\n            <MessageCircleDashedIcon size={16} aria-hidden=\"true\" />\n          </Button>\n          {/* User menu */}\n          <UserMenu />\n        </div>\n      </div>\n    </header>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/user-menu.tsx",
          "type": "registry:component",
          "target": "components/ui/user-menu.tsx",
          "content": "import {\n  Avatar,\n  AvatarFallback,\n  AvatarImage,\n  Button,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from '@timui/react'\nimport { BoltIcon, BookOpenIcon, Layers2Icon, LogOutIcon, PinIcon, UserPenIcon } from 'lucide-react'\n\nexport default function UserMenu() {\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button variant=\"ghost\" className=\"h-auto p-0 hover:bg-transparent\">\n          <Avatar>\n            <AvatarImage src=\"./avatar.jpg\" alt=\"Profile image\" />\n            <AvatarFallback>KK</AvatarFallback>\n          </Avatar>\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent className=\"max-w-64\" align=\"end\">\n        <DropdownMenuLabel className=\"flex min-w-0 flex-col\">\n          <span className=\"text-foreground truncate text-sm font-medium\">Keith Kennedy</span>\n          <span className=\"text-muted-foreground truncate text-xs font-normal\">\n            k.kennedy@ui.timkit.cn\n          </span>\n        </DropdownMenuLabel>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <BoltIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 1</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <Layers2Icon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 2</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <BookOpenIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 3</span>\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <PinIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 4</span>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <UserPenIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            <span>Option 5</span>\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuItem>\n          <LogOutIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n          <span>Logout</span>\n        </DropdownMenuItem>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-15.vue",
          "target": "components/ui/navbar-15.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { BotMessageSquareIcon, MessageCircleDashedIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue } from '@timui/vue';\nimport UserMenu from '@/registry/default/components/navbar-components/user-menu.vue';\n\n\n\n</script>\n\n<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 items-center justify-between gap-4\"><div><Select default-value=\"orion-alpha-45\" aria-label=\"Select AI model\"><SelectTrigger class=\"[&>svg]:text-muted-foreground/80 **:data-desc:hidden [&>svg]:shrink-0\"><BotMessageSquareIcon :size=\"16\" aria-hidden=\"true\" /><SelectValue placeholder=\"Choose an AI model\" /></SelectTrigger><SelectContent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\"><SelectGroup><SelectLabel class=\"ps-2\">Models</SelectLabel><SelectItem value=\"orion-alpha-45\">Orion-Alpha 4.5\n                  <span class=\"text-muted-foreground mt-1 block text-xs\" data-desc>Balanced performance and creativity\n                  </span></SelectItem><SelectItem value=\"orion-code-4\">Orion-Code 4\n                  <span class=\"text-muted-foreground mt-1 block text-xs\" data-desc>Optimized for code generation and understanding\n                  </span></SelectItem><SelectItem value=\"nova-chat-4\">Nova-Chat 4\n                  <span class=\"text-muted-foreground mt-1 block text-xs\" data-desc>Excels at natural, engaging conversations\n                  </span></SelectItem><SelectItem value=\"galaxy-max-4\">Galaxy-Max 4\n                  <span class=\"text-muted-foreground mt-1 block text-xs\" data-desc>Most powerful model for complex tasks\n                  </span></SelectItem></SelectGroup></SelectContent></Select></div><div class=\"flex items-center justify-end gap-2\"><Button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground size-8 rounded-full shadow-none\" aria-label=\"Temporary chat\"><MessageCircleDashedIcon :size=\"16\" aria-hidden=\"true\" /></Button><UserMenu /></div></div></header>\n</template>\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-15.html",
          "target": "components/ui/navbar-15.html",
          "type": "registry:component",
          "content": "<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 items-center justify-between gap-4\"><div><Select default-value=\"orion-alpha-45\" aria-label=\"Select AI model\"><SelectTrigger class=\"[&>svg]:text-muted-foreground/80 **:data-desc:hidden [&>svg]:shrink-0\"><BotMessageSquareIcon size=\"${16}\" aria-hidden=\"true\" /><SelectValue placeholder=\"Choose an AI model\" /></SelectTrigger><SelectContent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\"><SelectGroup><SelectLabel class=\"ps-2\">Models</SelectLabel><SelectItem value=\"orion-alpha-45\">Orion-Alpha 4.5\n                  <span class=\"text-muted-foreground mt-1 block text-xs\" data-desc>Balanced performance and creativity\n                  </span></SelectItem><SelectItem value=\"orion-code-4\">Orion-Code 4\n                  <span class=\"text-muted-foreground mt-1 block text-xs\" data-desc>Optimized for code generation and understanding\n                  </span></SelectItem><SelectItem value=\"nova-chat-4\">Nova-Chat 4\n                  <span class=\"text-muted-foreground mt-1 block text-xs\" data-desc>Excels at natural, engaging conversations\n                  </span></SelectItem><SelectItem value=\"galaxy-max-4\">Galaxy-Max 4\n                  <span class=\"text-muted-foreground mt-1 block text-xs\" data-desc>Most powerful model for complex tasks\n                  </span></SelectItem></SelectGroup></SelectContent></Select></div><div class=\"flex items-center justify-end gap-2\"><Button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground size-8 rounded-full shadow-none\" aria-label=\"Temporary chat\"><MessageCircleDashedIcon size=\"${16}\" aria-hidden=\"true\" /></Button><UserMenu /></div></div></header>\n</template>"
        },
        {
          "path": "registry/default/components/navbar/navbar-15.wxml",
          "target": "components/ui/navbar-15/navbar-15.wxml",
          "type": "registry:component",
          "content": "<view>\n  <header class=\"border-b px-4 md:px-6\"><view class=\"flex h-16 items-center justify-between gap-4\"><view><select default-value=\"orion-alpha-45\" aria-label=\"Select AI model\"><selecttrigger class=\"[&>svg]:text-muted-foreground/80 **:data-desc:hidden [&>svg]:shrink-0\"><botmessagesquareicon size=\"{{16}}\" aria-hidden=\"true\" /><selectvalue placeholder=\"Choose an AI model\" /></selecttrigger><selectcontent class=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2\"><selectgroup><selectlabel class=\"ps-2\">Models</selectlabel><selectitem value=\"orion-alpha-45\">Orion-Alpha 4.5\n                  <text class=\"text-muted-foreground mt-1 block text-xs\" data-desc>Balanced performance and creativity\n                  </text></selectitem><selectitem value=\"orion-code-4\">Orion-Code 4\n                  <text class=\"text-muted-foreground mt-1 block text-xs\" data-desc>Optimized for code generation and understanding\n                  </text></selectitem><selectitem value=\"nova-chat-4\">Nova-Chat 4\n                  <text class=\"text-muted-foreground mt-1 block text-xs\" data-desc>Excels at natural, engaging conversations\n                  </text></selectitem><selectitem value=\"galaxy-max-4\">Galaxy-Max 4\n                  <text class=\"text-muted-foreground mt-1 block text-xs\" data-desc>Most powerful model for complex tasks\n                  </text></selectitem></selectgroup></selectcontent></select></view><view class=\"flex items-center justify-end gap-2\"><button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground size-8 rounded-full shadow-none\" aria-label=\"Temporary chat\"><messagecircledashedicon size=\"{{16}}\" aria-hidden=\"true\" /></button><usermenu /></view></view></header>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "navbar, navigation"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "navbar-15",
          "group": "navbar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "navbar-15",
              "path": "registry/default/components/navbar/navbar-15.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "navbar-15",
              "path": "registry/default/components/navbar/navbar-15.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "navbar-15",
              "path": "registry/default/components/navbar/navbar-15.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "navbar-15",
              "path": "registry/default/components/navbar/navbar-15.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "navbars",
        "title": "Navbar · Select AI model"
      },
      "categories": [
        "navbars",
        "navbar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "navbar-16",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dropdown-menu.json",
        "https://ui.timkit.cn/r/input.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/popover.json",
        "https://ui.timkit.cn/r/switch.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/navbar/navbar-16.tsx",
          "type": "registry:component",
          "target": "components/ui/navbar-16.tsx",
          "content": "'use client'\n\nimport { useId, useState } from 'react'\nimport { Button, Input, Label, Switch } from '@timui/react'\nimport { LayoutGridIcon, PlusIcon, SearchIcon } from 'lucide-react'\n\nimport InfoMenu from '@/registry/default/components/navbar-components/info-menu'\nimport NotificationMenu from '@/registry/default/components/navbar-components/notification-menu'\nimport SettingsMenu from '@/registry/default/components/navbar-components/settings-menu'\n\nexport default function Component() {\n  const id = useId()\n  const [checked, setChecked] = useState<boolean>(true)\n\n  return (\n    <header className=\"border-b px-4 md:px-6\">\n      <div className=\"flex h-16 items-center justify-between gap-4\">\n        {/* Left side */}\n        <div className=\"relative flex-1\">\n          <Input\n            id={`input-${id}`}\n            className=\"peer h-8 w-full max-w-xs ps-8 pe-2\"\n            placeholder=\"Search...\"\n            type=\"search\"\n          />\n          <div className=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-2 peer-disabled:opacity-50\">\n            <SearchIcon size={16} />\n          </div>\n        </div>\n        {/* Right side */}\n        <div className=\"flex items-center gap-4\">\n          {/* Test mode */}\n          <div className=\"inline-flex items-center gap-2 max-md:hidden\">\n            <Label htmlFor={`switch-${id}`} className=\"text-sm font-medium\">\n              Test mode\n            </Label>\n            <Switch\n              id={`switch-${id}`}\n              checked={checked}\n              onCheckedChange={setChecked}\n              className=\"h-5 w-8 [&_span]:size-4 data-[state=checked]:[&_span]:translate-x-3 data-[state=checked]:[&_span]:rtl:-translate-x-3\"\n              aria-label=\"Toggle switch\"\n            />\n          </div>\n          <div className=\"flex items-center gap-2\">\n            {/* Layout button */}\n            <Button\n              size=\"icon\"\n              variant=\"ghost\"\n              className=\"text-muted-foreground size-8 rounded-full shadow-none\"\n              aria-label=\"Open layout menu\"\n            >\n              <LayoutGridIcon size={16} aria-hidden=\"true\" />\n            </Button>\n            {/* Info menu */}\n            <InfoMenu />\n            {/* Notification */}\n            <NotificationMenu />\n            {/* Settings */}\n            <SettingsMenu />\n          </div>\n          {/* Add button */}\n          <Button className=\"size-8 rounded-full\" size=\"icon\" aria-label=\"Add new item\">\n            <PlusIcon size={16} aria-hidden=\"true\" />\n          </Button>\n        </div>\n      </div>\n    </header>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/info-menu.tsx",
          "type": "registry:component",
          "target": "components/ui/info-menu.tsx",
          "content": "import {\n  Button,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuTrigger,\n} from '@timui/react'\nimport { BookIcon, InfoIcon, LifeBuoyIcon, MessageCircleMoreIcon } from 'lucide-react'\n\nexport default function InfoMenu() {\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button\n          size=\"icon\"\n          variant=\"ghost\"\n          className=\"size-8 rounded-full shadow-none\"\n          aria-label=\"Open edit menu\"\n        >\n          <InfoIcon className=\"text-muted-foreground\" size={16} aria-hidden=\"true\" />\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent className=\"pb-2\">\n        <DropdownMenuLabel>Need help?</DropdownMenuLabel>\n        <DropdownMenuItem\n          className=\"cursor-pointer py-1 data-[highlighted]:bg-transparent data-[highlighted]:underline\"\n          asChild\n        >\n          <a href=\"#\">\n            <BookIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            Documentation\n          </a>\n        </DropdownMenuItem>\n        <DropdownMenuItem\n          className=\"cursor-pointer py-1 data-[highlighted]:bg-transparent data-[highlighted]:underline\"\n          asChild\n        >\n          <a href=\"#\">\n            <LifeBuoyIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            Support\n          </a>\n        </DropdownMenuItem>\n        <DropdownMenuItem\n          className=\"cursor-pointer py-1 data-[highlighted]:bg-transparent data-[highlighted]:underline\"\n          asChild\n        >\n          <a href=\"#\">\n            <MessageCircleMoreIcon size={16} className=\"opacity-60\" aria-hidden=\"true\" />\n            Contact us\n          </a>\n        </DropdownMenuItem>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/notification-menu.tsx",
          "type": "registry:component",
          "target": "components/ui/notification-menu.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { Button, Popover, PopoverContent, PopoverTrigger } from '@timui/react'\nimport { BellIcon } from 'lucide-react'\n\nconst initialNotifications = [\n  {\n    id: 1,\n    user: 'Chris Tompson',\n    action: 'requested review on',\n    target: 'PR #42: Feature implementation',\n    timestamp: '15 minutes ago',\n    unread: true,\n  },\n  {\n    id: 2,\n    user: 'Emma Davis',\n    action: 'shared',\n    target: 'New component library',\n    timestamp: '45 minutes ago',\n    unread: true,\n  },\n  {\n    id: 3,\n    user: 'James Wilson',\n    action: 'assigned you to',\n    target: 'API integration task',\n    timestamp: '4 hours ago',\n    unread: false,\n  },\n  {\n    id: 4,\n    user: 'Alex Morgan',\n    action: 'replied to your comment in',\n    target: 'Authentication flow',\n    timestamp: '12 hours ago',\n    unread: false,\n  },\n  {\n    id: 5,\n    user: 'Sarah Chen',\n    action: 'commented on',\n    target: 'Dashboard redesign',\n    timestamp: '2 days ago',\n    unread: false,\n  },\n  {\n    id: 6,\n    user: 'Miky Derya',\n    action: 'mentioned you in',\n    target: 'Timkit UI open graph image',\n    timestamp: '2 weeks ago',\n    unread: false,\n  },\n]\n\nfunction Dot({ className }: { className?: string }) {\n  return (\n    <svg\n      width=\"6\"\n      height=\"6\"\n      fill=\"currentColor\"\n      viewBox=\"0 0 6 6\"\n      xmlns=\"http://www.w3.org/2000/svg\"\n      className={className}\n      aria-hidden=\"true\"\n    >\n      <circle cx=\"3\" cy=\"3\" r=\"3\" />\n    </svg>\n  )\n}\n\nexport default function NotificationMenu() {\n  const [notifications, setNotifications] = useState(initialNotifications)\n  const unreadCount = notifications.filter((n) => n.unread).length\n\n  const handleMarkAllAsRead = () => {\n    setNotifications(\n      notifications.map((notification) => ({\n        ...notification,\n        unread: false,\n      }))\n    )\n  }\n\n  const handleNotificationClick = (id: number) => {\n    setNotifications(\n      notifications.map((notification) =>\n        notification.id === id ? { ...notification, unread: false } : notification\n      )\n    )\n  }\n\n  return (\n    <Popover>\n      <PopoverTrigger asChild>\n        <Button\n          size=\"icon\"\n          variant=\"ghost\"\n          className=\"text-muted-foreground relative size-8 rounded-full shadow-none\"\n          aria-label=\"Open notifications\"\n        >\n          <BellIcon size={16} aria-hidden=\"true\" />\n          {unreadCount > 0 && (\n            <div\n              aria-hidden=\"true\"\n              className=\"bg-primary absolute top-0.5 right-0.5 size-1 rounded-full\"\n            />\n          )}\n        </Button>\n      </PopoverTrigger>\n      <PopoverContent className=\"w-80 p-1\">\n        <div className=\"flex items-baseline justify-between gap-4 px-3 py-2\">\n          <div className=\"text-sm font-semibold\">Notifications</div>\n          {unreadCount > 0 && (\n            <button className=\"text-xs font-medium hover:underline\" onClick={handleMarkAllAsRead}>\n              Mark all as read\n            </button>\n          )}\n        </div>\n        <div\n          role=\"separator\"\n          aria-orientation=\"horizontal\"\n          className=\"bg-border -mx-1 my-1 h-px\"\n        ></div>\n        {notifications.map((notification) => (\n          <div\n            key={notification.id}\n            className=\"hover:bg-accent rounded-md px-3 py-2 text-sm transition-colors\"\n          >\n            <div className=\"relative flex items-start pe-3\">\n              <div className=\"flex-1 space-y-1\">\n                <button\n                  className=\"text-foreground/80 text-left after:absolute after:inset-0\"\n                  onClick={() => handleNotificationClick(notification.id)}\n                >\n                  <span className=\"text-foreground font-medium hover:underline\">\n                    {notification.user}\n                  </span>{' '}\n                  {notification.action}{' '}\n                  <span className=\"text-foreground font-medium hover:underline\">\n                    {notification.target}\n                  </span>\n                  .\n                </button>\n                <div className=\"text-muted-foreground text-xs\">{notification.timestamp}</div>\n              </div>\n              {notification.unread && (\n                <div className=\"absolute end-0 self-center\">\n                  <span className=\"sr-only\">Unread</span>\n                  <Dot />\n                </div>\n              )}\n            </div>\n          </div>\n        ))}\n      </PopoverContent>\n    </Popover>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/settings-menu.tsx",
          "type": "registry:component",
          "target": "components/ui/settings-menu.tsx",
          "content": "import {\n  Button,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuTrigger,\n} from '@timui/react'\nimport { SettingsIcon } from 'lucide-react'\n\nexport default function SettingsMenu() {\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button\n          size=\"icon\"\n          variant=\"ghost\"\n          className=\"rounded-full shadow-none\"\n          aria-label=\"Open edit menu\"\n        >\n          <SettingsIcon className=\"text-muted-foreground\" size={16} aria-hidden=\"true\" />\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent className=\"max-w-64\">\n        <DropdownMenuItem>Appearance</DropdownMenuItem>\n        <DropdownMenuItem>Preferences</DropdownMenuItem>\n        <DropdownMenuItem>API Settings</DropdownMenuItem>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-16.vue",
          "target": "components/ui/navbar-16.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { LayoutGridIcon, PlusIcon, SearchIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport { Input } from '@timui/vue';\nimport { Label } from '@timui/vue';\nimport { Switch } from '@timui/vue';\nimport InfoMenu from '@/registry/default/components/navbar-components/info-menu.vue';\nimport NotificationMenu from '@/registry/default/components/navbar-components/notification-menu.vue';\nimport SettingsMenu from '@/registry/default/components/navbar-components/settings-menu.vue';\n\n\nconst checked = ref<boolean>(true);\n\n\nconst id = 'navbar-16';\n\n\nfunction setChecked(next: typeof checked.value | ((prev: typeof checked.value) => typeof checked.value)) {\n  checked.value = typeof next === 'function'\n    ? (next as (prev: typeof checked.value) => typeof checked.value)(checked.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 items-center justify-between gap-4\"><div class=\"relative flex-1\"><Input :id=\"`input-${id}`\" class=\"peer h-8 w-full max-w-xs ps-8 pe-2\" placeholder=\"Search...\" type=\"search\" /><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-2 peer-disabled:opacity-50\"><SearchIcon :size=\"16\" /></div></div><div class=\"flex items-center gap-4\"><div class=\"inline-flex items-center gap-2 max-md:hidden\"><Label :htmlFor=\"`switch-${id}`\" class=\"text-sm font-medium\">Test mode\n            </Label><Switch :id=\"`switch-${id}`\" :checked=\"checked\" :onCheckedChange=\"setChecked\" class=\"h-5 w-8 [&_span]:size-4 data-[state=checked]:[&_span]:translate-x-3 data-[state=checked]:[&_span]:rtl:-translate-x-3\" aria-label=\"Toggle switch\" /></div><div class=\"flex items-center gap-2\"><Button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground size-8 rounded-full shadow-none\" aria-label=\"Open layout menu\"><LayoutGridIcon :size=\"16\" aria-hidden=\"true\" /></Button><InfoMenu /><NotificationMenu /><SettingsMenu /></div><Button class=\"size-8 rounded-full\" size=\"icon\" aria-label=\"Add new item\"><PlusIcon :size=\"16\" aria-hidden=\"true\" /></Button></div></div></header>\n</template>\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-16.html",
          "target": "components/ui/navbar-16.html",
          "type": "registry:component",
          "content": "<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 items-center justify-between gap-4\"><div class=\"relative flex-1\"><Input id=\"${`input-${id}`}\" class=\"peer h-8 w-full max-w-xs ps-8 pe-2\" placeholder=\"Search...\" type=\"search\" /><div class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-2 peer-disabled:opacity-50\"><SearchIcon size=\"${16}\" /></div></div><div class=\"flex items-center gap-4\"><div class=\"inline-flex items-center gap-2 max-md:hidden\"><Label htmlfor=\"${`switch-${id}`}\" class=\"text-sm font-medium\">Test mode\n            </Label><Switch id=\"${`switch-${id}`}\" checked=\"${checked}\" oncheckedchange=\"${setChecked}\" class=\"h-5 w-8 [&_span]:size-4 data-[state=checked]:[&_span]:translate-x-3 data-[state=checked]:[&_span]:rtl:-translate-x-3\" aria-label=\"Toggle switch\" /></div><div class=\"flex items-center gap-2\"><Button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground size-8 rounded-full shadow-none\" aria-label=\"Open layout menu\"><LayoutGridIcon size=\"${16}\" aria-hidden=\"true\" /></Button><InfoMenu /><NotificationMenu /><SettingsMenu /></div><Button class=\"size-8 rounded-full\" size=\"icon\" aria-label=\"Add new item\"><PlusIcon size=\"${16}\" aria-hidden=\"true\" /></Button></div></div></header>\n</template>"
        },
        {
          "path": "registry/default/components/navbar/navbar-16.wxml",
          "target": "components/ui/navbar-16/navbar-16.wxml",
          "type": "registry:component",
          "content": "<view>\n  <header class=\"border-b px-4 md:px-6\"><view class=\"flex h-16 items-center justify-between gap-4\"><view class=\"relative flex-1\"><input id=\"{{`input-${id}`}}\" class=\"peer h-8 w-full max-w-xs ps-8 pe-2\" placeholder=\"Search...\" type=\"search\" /><view class=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-2 peer-disabled:opacity-50\"><searchicon size=\"{{16}}\" /></view></view><view class=\"flex items-center gap-4\"><view class=\"inline-flex items-center gap-2 max-md:hidden\"><label htmlfor=\"{{`switch-${id}`}}\" class=\"text-sm font-medium\">Test mode\n            </label><switch id=\"{{`switch-${id}`}}\" checked=\"{{checked}}\" oncheckedchange=\"{{setChecked}}\" class=\"h-5 w-8 [&_span]:size-4 data-[state=checked]:[&_span]:translate-x-3 data-[state=checked]:[&_span]:rtl:-translate-x-3\" aria-label=\"Toggle switch\" /></view><view class=\"flex items-center gap-2\"><button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground size-8 rounded-full shadow-none\" aria-label=\"Open layout menu\"><layoutgridicon size=\"{{16}}\" aria-hidden=\"true\" /></button><infomenu /><notificationmenu /><settingsmenu /></view><button class=\"size-8 rounded-full\" size=\"icon\" aria-label=\"Add new item\"><plusicon size=\"{{16}}\" aria-hidden=\"true\" /></button></view></view></header>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "navbar, navigation"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "navbar-16",
          "group": "navbar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "navbar-16",
              "path": "registry/default/components/navbar/navbar-16.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "navbar-16",
              "path": "registry/default/components/navbar/navbar-16.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "navbar-16",
              "path": "registry/default/components/navbar/navbar-16.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "navbar-16",
              "path": "registry/default/components/navbar/navbar-16.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "navbars",
        "title": "Navbar · Test mode"
      },
      "categories": [
        "navbars",
        "navbar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "navbar-17",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/breadcrumb.json",
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/calendar.json",
        "https://ui.timkit.cn/r/checkbox.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/popover.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/navbar/navbar-17.tsx",
          "type": "registry:component",
          "target": "components/ui/navbar-17.tsx",
          "content": "import {\n  Breadcrumb,\n  BreadcrumbItem,\n  BreadcrumbLink,\n  BreadcrumbList,\n  BreadcrumbPage,\n  BreadcrumbSeparator,\n  Button,\n} from '@timui/react'\nimport { BookmarkIcon, HomeIcon } from 'lucide-react'\n\nimport DatePicker from '@/registry/default/components/navbar-components/date-picker'\nimport Filters from '@/registry/default/components/navbar-components/filters'\n\nexport default function Component() {\n  return (\n    <header className=\"border-b px-4 md:px-6\">\n      <div className=\"flex h-16 items-center justify-between gap-4\">\n        {/* Left side */}\n        <Breadcrumb>\n          <BreadcrumbList>\n            <BreadcrumbItem>\n              <BreadcrumbLink href=\"#\">\n                <HomeIcon size={16} aria-hidden=\"true\" />\n                <span className=\"sr-only\">Home</span>\n              </BreadcrumbLink>\n            </BreadcrumbItem>\n            <BreadcrumbSeparator />\n            <BreadcrumbItem>\n              <BreadcrumbPage>Reports</BreadcrumbPage>\n            </BreadcrumbItem>\n          </BreadcrumbList>\n        </Breadcrumb>\n        {/* Right side */}\n        <div className=\"flex items-center gap-2\">\n          {/* Date picker */}\n          <DatePicker />\n          {/* Filters */}\n          <Filters />\n          {/* Saved button */}\n          <Button size=\"sm\" variant=\"outline\" className=\"aspect-square text-sm max-sm:p-0\">\n            <BookmarkIcon\n              className=\"text-muted-foreground/80 sm:-ms-1\"\n              size={16}\n              aria-hidden=\"true\"\n            />\n            <span className=\"max-sm:sr-only\">Saved</span>\n          </Button>\n        </div>\n      </div>\n    </header>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/date-picker.tsx",
          "type": "registry:component",
          "target": "components/ui/date-picker.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { cn } from '@timui/core'\nimport { Button, Calendar, Popover, PopoverContent, PopoverTrigger } from '@timui/react'\nimport { format } from 'date-fns'\nimport { CalendarIcon } from 'lucide-react'\n\ntype CalendarRangeValue = { from: Date | undefined; to?: Date }\ntype CalendarSelectedValue = Date | Date[] | CalendarRangeValue | undefined\n\nexport default function DatePicker() {\n  const [date, setDate] = useState<CalendarRangeValue | undefined>()\n\n  return (\n    <Popover>\n      <PopoverTrigger asChild>\n        <Button\n          variant=\"outline\"\n          size=\"sm\"\n          className=\"group bg-background border-input w-full justify-between px-3 text-sm font-normal outline-offset-0 outline-none focus-visible:outline-[3px]\"\n        >\n          <CalendarIcon\n            size={16}\n            className=\"text-muted-foreground/80 -ms-1 shrink-0 transition-colors\"\n            aria-hidden=\"true\"\n          />\n          <span className={cn('truncate', !date && 'font-medium')}>\n            {date?.from ? (\n              date.to ? (\n                <>\n                  {format(date.from, 'LLL dd, y')} - {format(date.to, 'LLL dd, y')}\n                </>\n              ) : (\n                format(date.from, 'LLL dd, y')\n              )\n            ) : (\n              'Date'\n            )}\n          </span>\n        </Button>\n      </PopoverTrigger>\n      <PopoverContent className=\"w-auto p-2\" align=\"start\">\n        <Calendar\n          mode=\"range\"\n          selected={date}\n          onSelect={(next: CalendarSelectedValue) =>\n            setDate(next as CalendarRangeValue | undefined)\n          }\n        />\n      </PopoverContent>\n    </Popover>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/filters.tsx",
          "type": "registry:component",
          "target": "components/ui/filters.tsx",
          "content": "import { useId } from 'react'\nimport { Button, Checkbox, Label, Popover, PopoverContent, PopoverTrigger } from '@timui/react'\nimport { ListFilterIcon } from 'lucide-react'\n\nexport default function Component() {\n  const id = useId()\n  return (\n    <div className=\"flex flex-col gap-4\">\n      <Popover>\n        <PopoverTrigger asChild>\n          <Button variant=\"outline\" size=\"sm\" className=\"text-sm\">\n            <ListFilterIcon\n              size={16}\n              className=\"text-muted-foreground/80 -ms-1\"\n              aria-hidden=\"true\"\n            />\n            Filters\n          </Button>\n        </PopoverTrigger>\n        <PopoverContent className=\"w-36 p-3\">\n          <div className=\"space-y-3\">\n            <div className=\"text-xs font-medium\">Filters</div>\n            <form>\n              <div className=\"space-y-3\">\n                <div className=\"flex items-center gap-2\">\n                  <Checkbox id={`${id}-1`} />\n                  <Label htmlFor={`${id}-1`} className=\"font-normal\">\n                    Real Time\n                  </Label>\n                </div>\n                <div className=\"flex items-center gap-2\">\n                  <Checkbox id={`${id}-2`} />\n                  <Label htmlFor={`${id}-2`} className=\"font-normal\">\n                    Top Channels\n                  </Label>\n                </div>\n                <div className=\"flex items-center gap-2\">\n                  <Checkbox id={`${id}-3`} />\n                  <Label htmlFor={`${id}-3`} className=\"font-normal\">\n                    Last Orders\n                  </Label>\n                </div>\n                <div className=\"flex items-center gap-2\">\n                  <Checkbox id={`${id}-4`} />\n                  <Label htmlFor={`${id}-4`} className=\"font-normal\">\n                    Total Spent\n                  </Label>\n                </div>\n              </div>\n              <div\n                role=\"separator\"\n                aria-orientation=\"horizontal\"\n                className=\"bg-border -mx-3 my-3 h-px\"\n              ></div>\n              <div className=\"flex justify-between gap-2\">\n                <Button size=\"sm\" variant=\"outline\" className=\"h-7 px-2\">\n                  Clear\n                </Button>\n                <Button size=\"sm\" className=\"h-7 px-2\">\n                  Apply\n                </Button>\n              </div>\n            </form>\n          </div>\n        </PopoverContent>\n      </Popover>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-17.vue",
          "target": "components/ui/navbar-17.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { BookmarkIcon, HomeIcon } from 'lucide-vue-next';\nimport { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from '@timui/vue';\nimport { Button } from '@timui/vue';\nimport DatePicker from '@/registry/default/components/navbar-components/date-picker.vue';\nimport Filters from '@/registry/default/components/navbar-components/filters.vue';\n\n\n\n</script>\n\n<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 items-center justify-between gap-4\"><Breadcrumb><BreadcrumbList><BreadcrumbItem><BreadcrumbLink href=\"#\"><HomeIcon :size=\"16\" aria-hidden=\"true\" /><span class=\"sr-only\">Home</span></BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator /><BreadcrumbItem><BreadcrumbPage>Reports</BreadcrumbPage></BreadcrumbItem></BreadcrumbList></Breadcrumb><div class=\"flex items-center gap-2\"><DatePicker /><Filters /><Button size=\"sm\" variant=\"outline\" class=\"aspect-square text-sm max-sm:p-0\"><BookmarkIcon class=\"text-muted-foreground/80 sm:-ms-1\" :size=\"16\" aria-hidden=\"true\" /><span class=\"max-sm:sr-only\">Saved</span></Button></div></div></header>\n</template>\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-17.html",
          "target": "components/ui/navbar-17.html",
          "type": "registry:component",
          "content": "<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 items-center justify-between gap-4\"><Breadcrumb><BreadcrumbList><BreadcrumbItem><BreadcrumbLink href=\"#\"><HomeIcon size=\"${16}\" aria-hidden=\"true\" /><span class=\"sr-only\">Home</span></BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator /><BreadcrumbItem><BreadcrumbPage>Reports</BreadcrumbPage></BreadcrumbItem></BreadcrumbList></Breadcrumb><div class=\"flex items-center gap-2\"><DatePicker /><Filters /><Button size=\"sm\" variant=\"outline\" class=\"aspect-square text-sm max-sm:p-0\"><BookmarkIcon class=\"text-muted-foreground/80 sm:-ms-1\" size=\"${16}\" aria-hidden=\"true\" /><span class=\"max-sm:sr-only\">Saved</span></Button></div></div></header>\n</template>"
        },
        {
          "path": "registry/default/components/navbar/navbar-17.wxml",
          "target": "components/ui/navbar-17/navbar-17.wxml",
          "type": "registry:component",
          "content": "<view>\n  <header class=\"border-b px-4 md:px-6\"><view class=\"flex h-16 items-center justify-between gap-4\"><breadcrumb><breadcrumblist><breadcrumbitem><breadcrumblink href=\"#\"><homeicon size=\"{{16}}\" aria-hidden=\"true\" /><text class=\"sr-only\">Home</text></breadcrumblink></breadcrumbitem><breadcrumbseparator /><breadcrumbitem><breadcrumbpage>Reports</breadcrumbpage></breadcrumbitem></breadcrumblist></breadcrumb><view class=\"flex items-center gap-2\"><datepicker /><filters /><button size=\"sm\" variant=\"outline\" class=\"aspect-square text-sm max-sm:p-0\"><bookmarkicon class=\"text-muted-foreground/80 sm:-ms-1\" size=\"{{16}}\" aria-hidden=\"true\" /><text class=\"max-sm:sr-only\">Saved</text></button></view></view></header>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "navbar, navigation"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "navbar-17",
          "group": "navbar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "navbar-17",
              "path": "registry/default/components/navbar/navbar-17.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "navbar-17",
              "path": "registry/default/components/navbar/navbar-17.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "navbar-17",
              "path": "registry/default/components/navbar/navbar-17.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "navbar-17",
              "path": "registry/default/components/navbar/navbar-17.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@timui/react",
              "date-fns"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "navbars",
        "title": "Navbar · Search Pattern"
      },
      "categories": [
        "navbars",
        "navbar"
      ],
      "dependencies": [
        "@timui/core",
        "@timui/react",
        "date-fns"
      ]
    },
    {
      "name": "navbar-18",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/dropdown-menu.json",
        "https://ui.timkit.cn/r/radio-group.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/navbar/navbar-18.tsx",
          "type": "registry:component",
          "target": "components/ui/navbar-18.tsx",
          "content": "import { Button } from '@timui/react'\nimport { SparklesIcon, UploadIcon } from 'lucide-react'\n\nimport AppToggle from '@/registry/default/components/navbar-components/app-toggle'\nimport TeamSwitcher from '@/registry/default/components/navbar-components/team-switcher'\n\nconst teams = ['Acme Inc.', 'Timkit UI', 'Junon']\n\nexport default function Component() {\n  return (\n    <header className=\"border-b px-4 md:px-6\">\n      <div className=\"flex h-16 items-center justify-between gap-4\">\n        {/* Left side */}\n        <div className=\"flex flex-1 items-center gap-2\">\n          <TeamSwitcher teams={teams} defaultTeam={teams[0]} />\n        </div>\n        {/* Middle area */}\n        <AppToggle />\n        {/* Right side */}\n        <div className=\"flex flex-1 items-center justify-end gap-2\">\n          <Button size=\"sm\" variant=\"ghost\" className=\"aspect-square text-sm max-sm:p-0\">\n            <UploadIcon className=\"opacity-60 sm:-ms-1\" size={16} aria-hidden=\"true\" />\n            <span className=\"max-sm:sr-only\">Export</span>\n          </Button>\n          <Button size=\"sm\" className=\"aspect-square text-sm max-sm:p-0\">\n            <SparklesIcon className=\"opacity-60 sm:-ms-1\" size={16} aria-hidden=\"true\" />\n            <span className=\"max-sm:sr-only\">Upgrade</span>\n          </Button>\n        </div>\n      </div>\n    </header>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/app-toggle.tsx",
          "type": "registry:component",
          "target": "components/ui/app-toggle.tsx",
          "content": "'use client'\n\nimport { useState } from 'react'\nimport { cn } from '@timui/core'\n\nexport default function AppToggle() {\n  const [selectedValue, setSelectedValue] = useState('on')\n\n  return (\n    <div className=\"bg-input/50 relative inline-grid h-8 grid-cols-2 rounded-md p-0.5 text-sm font-medium\">\n      <span\n        aria-hidden=\"true\"\n        className={cn(\n          'bg-background pointer-events-none absolute inset-y-0 m-0.5 w-[calc(50%-2px)] rounded-sm shadow-xs transition-transform duration-300 ease-[cubic-bezier(0.16,1,0.3,1)]',\n          selectedValue === 'on' ? 'translate-x-[calc(100%+2px)]' : 'translate-x-0'\n        )}\n      />\n      <button\n        type=\"button\"\n        aria-pressed={selectedValue === 'off'}\n        onClick={() => setSelectedValue('off')}\n        className={cn(\n          'relative z-10 inline-flex h-full min-w-8 cursor-pointer items-center justify-center px-3 whitespace-nowrap transition-colors select-none',\n          selectedValue === 'on' && 'text-muted-foreground/70'\n        )}\n      >\n        Sitemap\n      </button>\n      <button\n        type=\"button\"\n        aria-pressed={selectedValue === 'on'}\n        onClick={() => setSelectedValue('on')}\n        className={cn(\n          'relative z-10 inline-flex h-full min-w-8 cursor-pointer items-center justify-center px-3 whitespace-nowrap transition-colors select-none',\n          selectedValue === 'off' && 'text-muted-foreground/70'\n        )}\n      >\n        Wireframe\n      </button>\n    </div>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar-components/team-switcher.tsx",
          "type": "registry:component",
          "target": "components/ui/team-switcher.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport {\n  Button,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuTrigger,\n} from '@timui/react'\nimport { ChevronsUpDown } from 'lucide-react'\n\nexport default function TeamSwitcher({\n  teams,\n  defaultTeam,\n}: {\n  teams: string[]\n  defaultTeam: string\n}) {\n  const [selectedProject, setSelectedProject] = React.useState(defaultTeam)\n\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button variant=\"ghost\" className=\"p-0 hover:bg-transparent\">\n          <span className=\"bg-primary text-primary-foreground flex size-8 items-center justify-center rounded-full\">\n            {selectedProject.charAt(0).toUpperCase()}\n          </span>\n          <div className=\"flex flex-col gap-0.5 leading-none\">\n            <span className=\"\">{selectedProject}</span>\n          </div>\n          <ChevronsUpDown size={14} className=\"text-muted-foreground/80\" />\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent align=\"start\">\n        {teams.map((project) => (\n          <DropdownMenuItem key={project} onClick={() => setSelectedProject(project)}>\n            {project}\n          </DropdownMenuItem>\n        ))}\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-18.vue",
          "target": "components/ui/navbar-18.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { SparklesIcon, UploadIcon } from 'lucide-vue-next';\nimport { Button } from '@timui/vue';\nimport AppToggle from '@/registry/default/components/navbar-components/app-toggle.vue';\nimport TeamSwitcher from '@/registry/default/components/navbar-components/team-switcher.vue';\n\n\n\n</script>\n\n<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 items-center justify-between gap-4\"><div class=\"flex flex-1 items-center gap-2\"><TeamSwitcher :teams=\"teams\" :defaultTeam=\"teams[0]\" /></div><AppToggle /><div class=\"flex flex-1 items-center justify-end gap-2\"><Button size=\"sm\" variant=\"ghost\" class=\"aspect-square text-sm max-sm:p-0\"><UploadIcon class=\"opacity-60 sm:-ms-1\" :size=\"16\" aria-hidden=\"true\" /><span class=\"max-sm:sr-only\">Export</span></Button><Button size=\"sm\" class=\"aspect-square text-sm max-sm:p-0\"><SparklesIcon class=\"opacity-60 sm:-ms-1\" :size=\"16\" aria-hidden=\"true\" /><span class=\"max-sm:sr-only\">Upgrade</span></Button></div></div></header>\n</template>\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-18.html",
          "target": "components/ui/navbar-18.html",
          "type": "registry:component",
          "content": "<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 items-center justify-between gap-4\"><div class=\"flex flex-1 items-center gap-2\"><TeamSwitcher teams=\"${teams}\" defaultteam=\"${teams[0]}\" /></div><AppToggle /><div class=\"flex flex-1 items-center justify-end gap-2\"><Button size=\"sm\" variant=\"ghost\" class=\"aspect-square text-sm max-sm:p-0\"><UploadIcon class=\"opacity-60 sm:-ms-1\" size=\"${16}\" aria-hidden=\"true\" /><span class=\"max-sm:sr-only\">Export</span></Button><Button size=\"sm\" class=\"aspect-square text-sm max-sm:p-0\"><SparklesIcon class=\"opacity-60 sm:-ms-1\" size=\"${16}\" aria-hidden=\"true\" /><span class=\"max-sm:sr-only\">Upgrade</span></Button></div></div></header>\n</template>"
        },
        {
          "path": "registry/default/components/navbar/navbar-18.wxml",
          "target": "components/ui/navbar-18/navbar-18.wxml",
          "type": "registry:component",
          "content": "<view>\n  <header class=\"border-b px-4 md:px-6\"><view class=\"flex h-16 items-center justify-between gap-4\"><view class=\"flex flex-1 items-center gap-2\"><teamswitcher teams=\"{{teams}}\" defaultteam=\"{{teams[0]}}\" /></view><apptoggle /><view class=\"flex flex-1 items-center justify-end gap-2\"><button size=\"sm\" variant=\"ghost\" class=\"aspect-square text-sm max-sm:p-0\"><uploadicon class=\"opacity-60 sm:-ms-1\" size=\"{{16}}\" aria-hidden=\"true\" /><text class=\"max-sm:sr-only\">Export</text></button><button size=\"sm\" class=\"aspect-square text-sm max-sm:p-0\"><sparklesicon class=\"opacity-60 sm:-ms-1\" size=\"{{16}}\" aria-hidden=\"true\" /><text class=\"max-sm:sr-only\">Upgrade</text></button></view></view></header>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "navbar, navigation"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "navbar-18",
          "group": "navbar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "navbar-18",
              "path": "registry/default/components/navbar/navbar-18.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "navbar-18",
              "path": "registry/default/components/navbar/navbar-18.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "navbar-18",
              "path": "registry/default/components/navbar/navbar-18.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "navbar-18",
              "path": "registry/default/components/navbar/navbar-18.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "navbars",
        "title": "Navbar · With icon"
      },
      "categories": [
        "navbars",
        "navbar"
      ],
      "dependencies": [
        "@timui/core",
        "@timui/react"
      ]
    },
    {
      "name": "navbar-19",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/avatar.json",
        "https://ui.timkit.cn/r/button.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/navbar/navbar-19.tsx",
          "type": "registry:component",
          "target": "components/ui/navbar-19.tsx",
          "content": "import { Avatar, AvatarFallback, AvatarImage, Button } from '@timui/react'\nimport { ChevronLeftIcon, HistoryIcon, MessageSquareText, UserRoundPlus } from 'lucide-react'\n\nexport default function Component() {\n  return (\n    <header className=\"border-b px-4 md:px-6\">\n      <div className=\"flex h-16 items-center justify-between gap-4\">\n        {/* Left side */}\n        <div className=\"flex items-center gap-2\">\n          <Button className=\"size-8\" variant=\"ghost\" size=\"icon\" aria-label=\"Go back\" asChild>\n            <a href=\"#\">\n              <ChevronLeftIcon />\n            </a>\n          </Button>\n          <h1 className=\"text-sm font-medium\">Basic UI</h1>\n        </div>\n        {/* Right side */}\n        <div className=\"flex items-center gap-2\">\n          {/* History button */}\n          <Button\n            size=\"icon\"\n            variant=\"ghost\"\n            className=\"text-muted-foreground size-8 rounded-full shadow-none\"\n            aria-label=\"History\"\n          >\n            <HistoryIcon size={16} aria-hidden=\"true\" />\n          </Button>\n          {/* Comments button */}\n          <Button\n            size=\"icon\"\n            variant=\"ghost\"\n            className=\"text-muted-foreground size-8 rounded-full shadow-none\"\n            aria-label=\"Save\"\n          >\n            <MessageSquareText size={16} aria-hidden=\"true\" />\n          </Button>\n          {/* Add user */}\n          <Button\n            size=\"icon\"\n            variant=\"ghost\"\n            className=\"text-muted-foreground size-8 rounded-full shadow-none\"\n            aria-label=\"Add user\"\n          >\n            <UserRoundPlus size={16} aria-hidden=\"true\" />\n          </Button>\n          {/* Online users */}\n          <div className=\"ml-2 flex items-center gap-2\">\n            <div className=\"relative\">\n              <Avatar>\n                <AvatarImage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" />\n                <AvatarFallback>KK</AvatarFallback>\n              </Avatar>\n              <span className=\"border-background absolute -end-0.5 -bottom-0.5 size-3 rounded-full border-2 bg-emerald-500\">\n                <span className=\"sr-only\">Online</span>\n              </span>\n            </div>\n            <div className=\"relative\">\n              <Avatar>\n                <AvatarImage src=\"./avatar-80-06.jpg\" alt=\"Martha Johnson\" />\n                <AvatarFallback>KK</AvatarFallback>\n              </Avatar>\n              <span className=\"border-background bg-muted-foreground absolute -end-0.5 -bottom-0.5 size-3 rounded-full border-2\">\n                <span className=\"sr-only\">Online</span>\n              </span>\n            </div>\n            <div className=\"relative\">\n              <Avatar>\n                <AvatarImage src=\"./avatar-80-05.jpg\" alt=\"Linda Green\" />\n                <AvatarFallback>KK</AvatarFallback>\n              </Avatar>\n              <span className=\"border-background bg-muted-foreground absolute -end-0.5 -bottom-0.5 size-3 rounded-full border-2\">\n                <span className=\"sr-only\">Online</span>\n              </span>\n            </div>\n            <Button\n              variant=\"secondary\"\n              className=\"bg-secondary text-muted-foreground ring-background hover:bg-secondary hover:text-foreground flex size-8 items-center justify-center rounded-full text-xs\"\n              size=\"icon\"\n            >\n              +3\n            </Button>\n          </div>\n        </div>\n      </div>\n    </header>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-19.vue",
          "target": "components/ui/navbar-19.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ChevronLeftIcon, HistoryIcon, MessageSquareText, UserRoundPlus } from 'lucide-vue-next';\nimport { Avatar, AvatarFallback, AvatarImage } from '@timui/vue';\nimport { Button } from '@timui/vue';\n\n\n\n\n</script>\n\n<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 items-center justify-between gap-4\"><div class=\"flex items-center gap-2\"><Button class=\"size-8\" variant=\"ghost\" size=\"icon\" aria-label=\"Go back\" as-child><a href=\"#\"><ChevronLeftIcon /></a></Button><h1 class=\"text-sm font-medium\">Basic UI</h1></div><div class=\"flex items-center gap-2\"><Button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground size-8 rounded-full shadow-none\" aria-label=\"History\"><HistoryIcon :size=\"16\" aria-hidden=\"true\" /></Button><Button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground size-8 rounded-full shadow-none\" aria-label=\"Save\"><MessageSquareText :size=\"16\" aria-hidden=\"true\" /></Button><Button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground size-8 rounded-full shadow-none\" aria-label=\"Add user\"><UserRoundPlus :size=\"16\" aria-hidden=\"true\" /></Button><div class=\"ml-2 flex items-center gap-2\"><div class=\"relative\"><Avatar><AvatarImage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" /><AvatarFallback>KK</AvatarFallback></Avatar><span class=\"border-background absolute -end-0.5 -bottom-0.5 size-3 rounded-full border-2 bg-emerald-500\"><span class=\"sr-only\">Online</span></span></div><div class=\"relative\"><Avatar><AvatarImage src=\"./avatar-80-06.jpg\" alt=\"Martha Johnson\" /><AvatarFallback>KK</AvatarFallback></Avatar><span class=\"border-background bg-muted-foreground absolute -end-0.5 -bottom-0.5 size-3 rounded-full border-2\"><span class=\"sr-only\">Online</span></span></div><div class=\"relative\"><Avatar><AvatarImage src=\"./avatar-80-05.jpg\" alt=\"Linda Green\" /><AvatarFallback>KK</AvatarFallback></Avatar><span class=\"border-background bg-muted-foreground absolute -end-0.5 -bottom-0.5 size-3 rounded-full border-2\"><span class=\"sr-only\">Online</span></span></div><Button variant=\"secondary\" class=\"bg-secondary text-muted-foreground ring-background hover:bg-secondary hover:text-foreground flex size-8 items-center justify-center rounded-full text-xs\" size=\"icon\">+3\n            </Button></div></div></div></header>\n</template>\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-19.html",
          "target": "components/ui/navbar-19.html",
          "type": "registry:component",
          "content": "<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 items-center justify-between gap-4\"><div class=\"flex items-center gap-2\"><Button class=\"size-8\" variant=\"ghost\" size=\"icon\" aria-label=\"Go back\" aschild><a href=\"#\"><ChevronLeftIcon /></a></Button><h1 class=\"text-sm font-medium\">Basic UI</h1></div><div class=\"flex items-center gap-2\"><Button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground size-8 rounded-full shadow-none\" aria-label=\"History\"><HistoryIcon size=\"${16}\" aria-hidden=\"true\" /></Button><Button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground size-8 rounded-full shadow-none\" aria-label=\"Save\"><MessageSquareText size=\"${16}\" aria-hidden=\"true\" /></Button><Button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground size-8 rounded-full shadow-none\" aria-label=\"Add user\"><UserRoundPlus size=\"${16}\" aria-hidden=\"true\" /></Button><div class=\"ml-2 flex items-center gap-2\"><div class=\"relative\"><Avatar><AvatarImage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" /><AvatarFallback>KK</AvatarFallback></Avatar><span class=\"border-background absolute -end-0.5 -bottom-0.5 size-3 rounded-full border-2 bg-emerald-500\"><span class=\"sr-only\">Online</span></span></div><div class=\"relative\"><Avatar><AvatarImage src=\"./avatar-80-06.jpg\" alt=\"Martha Johnson\" /><AvatarFallback>KK</AvatarFallback></Avatar><span class=\"border-background bg-muted-foreground absolute -end-0.5 -bottom-0.5 size-3 rounded-full border-2\"><span class=\"sr-only\">Online</span></span></div><div class=\"relative\"><Avatar><AvatarImage src=\"./avatar-80-05.jpg\" alt=\"Linda Green\" /><AvatarFallback>KK</AvatarFallback></Avatar><span class=\"border-background bg-muted-foreground absolute -end-0.5 -bottom-0.5 size-3 rounded-full border-2\"><span class=\"sr-only\">Online</span></span></div><Button variant=\"secondary\" class=\"bg-secondary text-muted-foreground ring-background hover:bg-secondary hover:text-foreground flex size-8 items-center justify-center rounded-full text-xs\" size=\"icon\">+3\n            </Button></div></div></div></header>\n</template>"
        },
        {
          "path": "registry/default/components/navbar/navbar-19.wxml",
          "target": "components/ui/navbar-19/navbar-19.wxml",
          "type": "registry:component",
          "content": "<view>\n  <header class=\"border-b px-4 md:px-6\"><view class=\"flex h-16 items-center justify-between gap-4\"><view class=\"flex items-center gap-2\"><button class=\"size-8\" variant=\"ghost\" size=\"icon\" aria-label=\"Go back\" aschild><a href=\"#\"><chevronlefticon /></a></button><h1 class=\"text-sm font-medium\">Basic UI</h1></view><view class=\"flex items-center gap-2\"><button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground size-8 rounded-full shadow-none\" aria-label=\"History\"><historyicon size=\"{{16}}\" aria-hidden=\"true\" /></button><button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground size-8 rounded-full shadow-none\" aria-label=\"Save\"><messagesquaretext size=\"{{16}}\" aria-hidden=\"true\" /></button><button size=\"icon\" variant=\"ghost\" class=\"text-muted-foreground size-8 rounded-full shadow-none\" aria-label=\"Add user\"><userroundplus size=\"{{16}}\" aria-hidden=\"true\" /></button><view class=\"ml-2 flex items-center gap-2\"><view class=\"relative\"><avatar><avatarimage src=\"./avatar-80-07.jpg\" alt=\"Kelly King\" /><avatarfallback>KK</avatarfallback></avatar><text class=\"border-background absolute -end-0.5 -bottom-0.5 size-3 rounded-full border-2 bg-emerald-500\"><text class=\"sr-only\">Online</text></text></view><view class=\"relative\"><avatar><avatarimage src=\"./avatar-80-06.jpg\" alt=\"Martha Johnson\" /><avatarfallback>KK</avatarfallback></avatar><text class=\"border-background bg-muted-foreground absolute -end-0.5 -bottom-0.5 size-3 rounded-full border-2\"><text class=\"sr-only\">Online</text></text></view><view class=\"relative\"><avatar><avatarimage src=\"./avatar-80-05.jpg\" alt=\"Linda Green\" /><avatarfallback>KK</avatarfallback></avatar><text class=\"border-background bg-muted-foreground absolute -end-0.5 -bottom-0.5 size-3 rounded-full border-2\"><text class=\"sr-only\">Online</text></text></view><button variant=\"secondary\" class=\"bg-secondary text-muted-foreground ring-background hover:bg-secondary hover:text-foreground flex size-8 items-center justify-center rounded-full text-xs\" size=\"icon\">+3\n            </button></view></view></view></header>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "navbar, navigation"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "navbar-19",
          "group": "navbar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "navbar-19",
              "path": "registry/default/components/navbar/navbar-19.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "navbar-19",
              "path": "registry/default/components/navbar/navbar-19.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "navbar-19",
              "path": "registry/default/components/navbar/navbar-19.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "navbar-19",
              "path": "registry/default/components/navbar/navbar-19.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "navbars",
        "title": "Navbar · Basic UI"
      },
      "categories": [
        "navbars",
        "navbar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "navbar-20",
      "type": "registry:component",
      "registryDependencies": [
        "https://ui.timkit.cn/r/badge.json",
        "https://ui.timkit.cn/r/button.json",
        "https://ui.timkit.cn/r/label.json",
        "https://ui.timkit.cn/r/navigation-menu.json",
        "https://ui.timkit.cn/r/popover.json",
        "https://ui.timkit.cn/r/switch.json"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/components/navbar/navbar-20.tsx",
          "type": "registry:component",
          "target": "components/ui/navbar-20.tsx",
          "content": "'use client'\n\nimport { useId, useState } from 'react'\nimport {\n  Badge,\n  Button,\n  Label,\n  NavigationMenu,\n  NavigationMenuItem,\n  NavigationMenuLink,\n  NavigationMenuList,\n  Popover,\n  PopoverContent,\n  PopoverTrigger,\n  Switch,\n} from '@timui/react'\nimport { ClockIcon, PowerIcon, PowerOffIcon, ZapIcon } from 'lucide-react'\n\n// Navigation links array to be used in both desktop and mobile menus\nconst navigationLinks = [\n  { href: '#', label: 'Overview', active: true },\n  { href: '#', label: 'Graphs' },\n  { href: '#', label: 'Backups' },\n]\n\nexport default function Component() {\n  const id = useId()\n  const [checked, setChecked] = useState<boolean>(true)\n\n  return (\n    <header className=\"border-b px-4 md:px-6\">\n      <div className=\"flex h-16 justify-between gap-4\">\n        {/* Left side */}\n        <div className=\"flex gap-2\">\n          <div className=\"flex items-center md:hidden\">\n            {/* Mobile menu trigger */}\n            <Popover>\n              <PopoverTrigger asChild>\n                <Button className=\"group size-8\" variant=\"ghost\" size=\"icon\">\n                  <svg\n                    className=\"pointer-events-none\"\n                    width={16}\n                    height={16}\n                    viewBox=\"0 0 24 24\"\n                    fill=\"none\"\n                    stroke=\"currentColor\"\n                    strokeWidth=\"2\"\n                    strokeLinecap=\"round\"\n                    strokeLinejoin=\"round\"\n                    xmlns=\"http://www.w3.org/2000/svg\"\n                  >\n                    <path\n                      d=\"M4 12L20 12\"\n                      className=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\"\n                    />\n                    <path\n                      d=\"M4 12H20\"\n                      className=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\"\n                    />\n                    <path\n                      d=\"M4 12H20\"\n                      className=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\"\n                    />\n                  </svg>\n                </Button>\n              </PopoverTrigger>\n              <PopoverContent align=\"start\" className=\"w-36 p-1 md:hidden\">\n                <NavigationMenu className=\"max-w-none *:w-full\">\n                  <NavigationMenuList className=\"flex-col items-start gap-0 md:gap-2\">\n                    {navigationLinks.map((link, index) => (\n                      <NavigationMenuItem key={index} className=\"w-full\">\n                        <NavigationMenuLink href={link.href} className=\"py-1.5\">\n                          {link.label}\n                        </NavigationMenuLink>\n                      </NavigationMenuItem>\n                    ))}\n                  </NavigationMenuList>\n                </NavigationMenu>\n              </PopoverContent>\n            </Popover>\n          </div>\n          {/* Main nav */}\n          <div className=\"flex items-center gap-6\">\n            {/* Navigation menu */}\n            <NavigationMenu className=\"h-full *:h-full max-md:hidden\">\n              <NavigationMenuList className=\"h-full gap-2\">\n                {navigationLinks.map((link, index) => (\n                  <NavigationMenuItem key={index} className=\"h-full\">\n                    <NavigationMenuLink\n                      active={link.active}\n                      href={link.href}\n                      className=\"text-muted-foreground hover:text-primary border-b-primary hover:border-b-primary data-[active]:border-b-primary h-full justify-center rounded-none border-y-2 border-transparent py-1.5 font-medium hover:bg-transparent data-[active]:bg-transparent!\"\n                    >\n                      {link.label}\n                    </NavigationMenuLink>\n                  </NavigationMenuItem>\n                ))}\n              </NavigationMenuList>\n            </NavigationMenu>\n          </div>\n        </div>\n        {/* Right side */}\n        <div className=\"flex items-center gap-4\">\n          <div className=\"flex items-center gap-2\">\n            <Badge variant=\"outline\" className=\"gap-1.5 text-emerald-600\">\n              <span className=\"size-1.5 rounded-full bg-emerald-500\" aria-hidden=\"true\"></span>\n              Online\n            </Badge>\n            <Badge variant=\"outline\" className=\"gap-1.5\">\n              <ZapIcon className=\"-ms-0.5 opacity-60\" size={12} aria-hidden=\"true\" />\n              99.9%\n            </Badge>\n            <Badge variant=\"outline\" className=\"gap-1.5\">\n              <ClockIcon className=\"-ms-0.5 opacity-60\" size={12} aria-hidden=\"true\" />\n              45ms\n            </Badge>\n          </div>\n          {/* Switch */}\n          <div>\n            <div className=\"relative inline-grid h-7 grid-cols-[1fr_1fr] items-center text-sm font-medium\">\n              <Switch\n                id={id}\n                checked={checked}\n                onCheckedChange={setChecked}\n                className=\"peer data-[state=unchecked]:bg-input/50 absolute inset-0 h-[inherit] w-auto [&_span]:z-10 [&_span]:h-full [&_span]:w-1/2 [&_span]:transition-transform [&_span]:duration-300 [&_span]:ease-[cubic-bezier(0.16,1,0.3,1)] [&_span]:data-[state=checked]:translate-x-full [&_span]:data-[state=checked]:rtl:-translate-x-full\"\n              />\n              <span className=\"pointer-events-none relative ms-0.5 flex w-6 items-center justify-center text-center transition-transform duration-300 ease-[cubic-bezier(0.16,1,0.3,1)] peer-data-[state=checked]:invisible peer-data-[state=unchecked]:translate-x-full peer-data-[state=unchecked]:rtl:-translate-x-full\">\n                <PowerOffIcon size={12} aria-hidden=\"true\" />\n              </span>\n              <span className=\"peer-data-[state=checked]:text-background pointer-events-none relative me-0.5 flex w-6 items-center justify-center text-center transition-transform duration-300 ease-[cubic-bezier(0.16,1,0.3,1)] peer-data-[state=checked]:-translate-x-full peer-data-[state=unchecked]:invisible peer-data-[state=checked]:rtl:translate-x-full\">\n                <PowerIcon size={12} aria-hidden=\"true\" />\n              </span>\n            </div>\n            <Label htmlFor={id} className=\"sr-only\">\n              Power\n            </Label>\n          </div>\n        </div>\n      </div>\n    </header>\n  )\n}\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-20.vue",
          "target": "components/ui/navbar-20.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { ClockIcon, PowerIcon, PowerOffIcon, ZapIcon } from 'lucide-vue-next';\nimport { Badge } from '@timui/vue';\nimport { Button } from '@timui/vue';\nimport { Label } from '@timui/vue';\nimport { NavigationMenu, NavigationMenuItem, NavigationMenuLink, NavigationMenuList } from '@timui/vue';\nimport { Popover, PopoverContent, PopoverTrigger } from '@timui/vue';\nimport { Switch } from '@timui/vue';\n\n\nconst navigationLinks = [\n  { href: '#', label: 'Overview', active: true },\n  { href: '#', label: 'Graphs' },\n  { href: '#', label: 'Backups' },\n];\nconst checked = ref<boolean>(true);\n\n\nconst id = 'navbar-20';\n\n\nfunction setChecked(next: typeof checked.value | ((prev: typeof checked.value) => typeof checked.value)) {\n  checked.value = typeof next === 'function'\n    ? (next as (prev: typeof checked.value) => typeof checked.value)(checked.value)\n    : next;\n}\n\n</script>\n\n<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 justify-between gap-4\"><div class=\"flex gap-2\"><div class=\"flex items-center md:hidden\"><Popover><PopoverTrigger as-child><Button class=\"group size-8\" variant=\"ghost\" size=\"icon\"><svg class=\"pointer-events-none\" :width=\"16\" :height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></Button></PopoverTrigger><PopoverContent align=\"start\" class=\"w-36 p-1 md:hidden\"><NavigationMenu class=\"max-w-none *:w-full\"><NavigationMenuList class=\"flex-col items-start gap-0 md:gap-2\"><NavigationMenuItem v-for=\"(link, index) in navigationLinks\" :key=\"index\" class=\"w-full\"><NavigationMenuLink :href=\"link.href\" class=\"py-1.5\">{{ link.label }}</NavigationMenuLink></NavigationMenuItem></NavigationMenuList></NavigationMenu></PopoverContent></Popover></div><div class=\"flex items-center gap-6\"><NavigationMenu class=\"h-full *:h-full max-md:hidden\"><NavigationMenuList class=\"h-full gap-2\"><NavigationMenuItem v-for=\"(link, index) in navigationLinks\" :key=\"index\" class=\"h-full\"><NavigationMenuLink :active=\"link.active\" :href=\"link.href\" class=\"text-muted-foreground hover:text-primary border-b-primary hover:border-b-primary data-[active]:border-b-primary h-full justify-center rounded-none border-y-2 border-transparent py-1.5 font-medium hover:bg-transparent data-[active]:bg-transparent!\">{{ link.label }}</NavigationMenuLink></NavigationMenuItem></NavigationMenuList></NavigationMenu></div></div><div class=\"flex items-center gap-4\"><div class=\"flex items-center gap-2\"><Badge variant=\"outline\" class=\"gap-1.5 text-emerald-600\"><span class=\"size-1.5 rounded-full bg-emerald-500\" aria-hidden=\"true\"></span>Online\n            </Badge><Badge variant=\"outline\" class=\"gap-1.5\"><ZapIcon class=\"-ms-0.5 opacity-60\" :size=\"12\" aria-hidden=\"true\" />99.9%\n            </Badge><Badge variant=\"outline\" class=\"gap-1.5\"><ClockIcon class=\"-ms-0.5 opacity-60\" :size=\"12\" aria-hidden=\"true\" />45ms\n            </Badge></div><div><div class=\"relative inline-grid h-7 grid-cols-[1fr_1fr] items-center text-sm font-medium\"><Switch :id=\"id\" :checked=\"checked\" :onCheckedChange=\"setChecked\" class=\"peer data-[state=unchecked]:bg-input/50 absolute inset-0 h-[inherit] w-auto [&_span]:z-10 [&_span]:h-full [&_span]:w-1/2 [&_span]:transition-transform [&_span]:duration-300 [&_span]:ease-[cubic-bezier(0.16,1,0.3,1)] [&_span]:data-[state=checked]:translate-x-full [&_span]:data-[state=checked]:rtl:-translate-x-full\" /><span class=\"pointer-events-none relative ms-0.5 flex w-6 items-center justify-center text-center transition-transform duration-300 ease-[cubic-bezier(0.16,1,0.3,1)] peer-data-[state=checked]:invisible peer-data-[state=unchecked]:translate-x-full peer-data-[state=unchecked]:rtl:-translate-x-full\"><PowerOffIcon :size=\"12\" aria-hidden=\"true\" /></span><span class=\"peer-data-[state=checked]:text-background pointer-events-none relative me-0.5 flex w-6 items-center justify-center text-center transition-transform duration-300 ease-[cubic-bezier(0.16,1,0.3,1)] peer-data-[state=checked]:-translate-x-full peer-data-[state=unchecked]:invisible peer-data-[state=checked]:rtl:translate-x-full\"><PowerIcon :size=\"12\" aria-hidden=\"true\" /></span></div><Label :htmlFor=\"id\" class=\"sr-only\">Power\n            </Label></div></div></div></header>\n</template>\n"
        },
        {
          "path": "registry/default/components/navbar/navbar-20.html",
          "target": "components/ui/navbar-20.html",
          "type": "registry:component",
          "content": "<template>\n  <header class=\"border-b px-4 md:px-6\"><div class=\"flex h-16 justify-between gap-4\"><div class=\"flex gap-2\"><div class=\"flex items-center md:hidden\"><Popover><PopoverTrigger aschild><Button class=\"group size-8\" variant=\"ghost\" size=\"icon\"><svg class=\"pointer-events-none\" width=\"${16}\" height=\"${16}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></Button></PopoverTrigger><PopoverContent align=\"start\" class=\"w-36 p-1 md:hidden\"><NavigationMenu class=\"max-w-none *:w-full\"><NavigationMenuList class=\"flex-col items-start gap-0 md:gap-2\"><!-- Loop navigationLinks -->\n<NavigationMenuItem key=\"${index}\" class=\"w-full\"><NavigationMenuLink href=\"${link.href}\" class=\"py-1.5\">${link.label}</NavigationMenuLink></NavigationMenuItem>\n<!-- End Loop --></NavigationMenuList></NavigationMenu></PopoverContent></Popover></div><div class=\"flex items-center gap-6\"><NavigationMenu class=\"h-full *:h-full max-md:hidden\"><NavigationMenuList class=\"h-full gap-2\"><!-- Loop navigationLinks -->\n<NavigationMenuItem key=\"${index}\" class=\"h-full\"><NavigationMenuLink active=\"${link.active}\" href=\"${link.href}\" class=\"text-muted-foreground hover:text-primary border-b-primary hover:border-b-primary data-[active]:border-b-primary h-full justify-center rounded-none border-y-2 border-transparent py-1.5 font-medium hover:bg-transparent data-[active]:bg-transparent!\">${link.label}</NavigationMenuLink></NavigationMenuItem>\n<!-- End Loop --></NavigationMenuList></NavigationMenu></div></div><div class=\"flex items-center gap-4\"><div class=\"flex items-center gap-2\"><Badge variant=\"outline\" class=\"gap-1.5 text-emerald-600\"><span class=\"size-1.5 rounded-full bg-emerald-500\" aria-hidden=\"true\"></span>Online\n            </Badge><Badge variant=\"outline\" class=\"gap-1.5\"><ZapIcon class=\"-ms-0.5 opacity-60\" size=\"${12}\" aria-hidden=\"true\" />99.9%\n            </Badge><Badge variant=\"outline\" class=\"gap-1.5\"><ClockIcon class=\"-ms-0.5 opacity-60\" size=\"${12}\" aria-hidden=\"true\" />45ms\n            </Badge></div><div><div class=\"relative inline-grid h-7 grid-cols-[1fr_1fr] items-center text-sm font-medium\"><Switch id=\"${id}\" checked=\"${checked}\" oncheckedchange=\"${setChecked}\" class=\"peer data-[state=unchecked]:bg-input/50 absolute inset-0 h-[inherit] w-auto [&_span]:z-10 [&_span]:h-full [&_span]:w-1/2 [&_span]:transition-transform [&_span]:duration-300 [&_span]:ease-[cubic-bezier(0.16,1,0.3,1)] [&_span]:data-[state=checked]:translate-x-full [&_span]:data-[state=checked]:rtl:-translate-x-full\" /><span class=\"pointer-events-none relative ms-0.5 flex w-6 items-center justify-center text-center transition-transform duration-300 ease-[cubic-bezier(0.16,1,0.3,1)] peer-data-[state=checked]:invisible peer-data-[state=unchecked]:translate-x-full peer-data-[state=unchecked]:rtl:-translate-x-full\"><PowerOffIcon size=\"${12}\" aria-hidden=\"true\" /></span><span class=\"peer-data-[state=checked]:text-background pointer-events-none relative me-0.5 flex w-6 items-center justify-center text-center transition-transform duration-300 ease-[cubic-bezier(0.16,1,0.3,1)] peer-data-[state=checked]:-translate-x-full peer-data-[state=unchecked]:invisible peer-data-[state=checked]:rtl:translate-x-full\"><PowerIcon size=\"${12}\" aria-hidden=\"true\" /></span></div><Label htmlfor=\"${id}\" class=\"sr-only\">Power\n            </Label></div></div></div></header>\n</template>"
        },
        {
          "path": "registry/default/components/navbar/navbar-20.wxml",
          "target": "components/ui/navbar-20/navbar-20.wxml",
          "type": "registry:component",
          "content": "<view>\n  <header class=\"border-b px-4 md:px-6\"><view class=\"flex h-16 justify-between gap-4\"><view class=\"flex gap-2\"><view class=\"flex items-center md:hidden\"><popover><popovertrigger aschild><button class=\"group size-8\" variant=\"ghost\" size=\"icon\"><svg class=\"pointer-events-none\" width=\"{{16}}\" height=\"{{16}}\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 12L20 12\" class=\"origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[315deg]\" /><path d=\"M4 12H20\" class=\"origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45\" /><path d=\"M4 12H20\" class=\"origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-[135deg]\" /></svg></button></popovertrigger><popovercontent align=\"start\" class=\"w-36 p-1 md:hidden\"><navigationmenu class=\"max-w-none *:w-full\"><navigationmenulist class=\"flex-col items-start gap-0 md:gap-2\"><navigationmenuitem wx:for=\"{{navigationLinks}}\" wx:for-item=\"link\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{index}}\" class=\"w-full\"><navigationmenulink href=\"{{link.href}}\" class=\"py-1.5\">{{ link.label }}</navigationmenulink></navigationmenuitem></navigationmenulist></navigationmenu></popovercontent></popover></view><view class=\"flex items-center gap-6\"><navigationmenu class=\"h-full *:h-full max-md:hidden\"><navigationmenulist class=\"h-full gap-2\"><navigationmenuitem wx:for=\"{{navigationLinks}}\" wx:for-item=\"link\" wx:for-index=\"index\" wx:key=\"index\" key=\"{{index}}\" class=\"h-full\"><navigationmenulink active=\"{{link.active}}\" href=\"{{link.href}}\" class=\"text-muted-foreground hover:text-primary border-b-primary hover:border-b-primary data-[active]:border-b-primary h-full justify-center rounded-none border-y-2 border-transparent py-1.5 font-medium hover:bg-transparent data-[active]:bg-transparent!\">{{ link.label }}</navigationmenulink></navigationmenuitem></navigationmenulist></navigationmenu></view></view><view class=\"flex items-center gap-4\"><view class=\"flex items-center gap-2\"><badge variant=\"outline\" class=\"gap-1.5 text-emerald-600\"><text class=\"size-1.5 rounded-full bg-emerald-500\" aria-hidden=\"true\"></text>Online\n            </badge><badge variant=\"outline\" class=\"gap-1.5\"><zapicon class=\"-ms-0.5 opacity-60\" size=\"{{12}}\" aria-hidden=\"true\" />99.9%\n            </badge><badge variant=\"outline\" class=\"gap-1.5\"><clockicon class=\"-ms-0.5 opacity-60\" size=\"{{12}}\" aria-hidden=\"true\" />45ms\n            </badge></view><view><view class=\"relative inline-grid h-7 grid-cols-[1fr_1fr] items-center text-sm font-medium\"><switch id=\"{{id}}\" checked=\"{{checked}}\" oncheckedchange=\"{{setChecked}}\" class=\"peer data-[state=unchecked]:bg-input/50 absolute inset-0 h-[inherit] w-auto [&_span]:z-10 [&_span]:h-full [&_span]:w-1/2 [&_span]:transition-transform [&_span]:duration-300 [&_span]:ease-[cubic-bezier(0.16,1,0.3,1)] [&_span]:data-[state=checked]:translate-x-full [&_span]:data-[state=checked]:rtl:-translate-x-full\" /><text class=\"pointer-events-none relative ms-0.5 flex w-6 items-center justify-center text-center transition-transform duration-300 ease-[cubic-bezier(0.16,1,0.3,1)] peer-data-[state=checked]:invisible peer-data-[state=unchecked]:translate-x-full peer-data-[state=unchecked]:rtl:-translate-x-full\"><powerofficon size=\"{{12}}\" aria-hidden=\"true\" /></text><text class=\"peer-data-[state=checked]:text-background pointer-events-none relative me-0.5 flex w-6 items-center justify-center text-center transition-transform duration-300 ease-[cubic-bezier(0.16,1,0.3,1)] peer-data-[state=checked]:-translate-x-full peer-data-[state=unchecked]:invisible peer-data-[state=checked]:rtl:translate-x-full\"><powericon size=\"{{12}}\" aria-hidden=\"true\" /></text></view><label htmlfor=\"{{id}}\" class=\"sr-only\">Power\n            </label></view></view></view></header>\n</view>"
        }
      ],
      "meta": {
        "tags": [
          "navbar, navigation"
        ],
        "colSpan": 3,
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "demoCanonical": {
          "componentName": "navbar-20",
          "group": "navbar",
          "frameworks": {
            "react": {
              "sourceFramework": "react",
              "sourceMode": "exact",
              "matchedName": "navbar-20",
              "path": "registry/default/components/navbar/navbar-20.tsx"
            },
            "vue": {
              "sourceFramework": "vue",
              "sourceMode": "exact",
              "matchedName": "navbar-20",
              "path": "registry/default/components/navbar/navbar-20.vue"
            },
            "html": {
              "sourceFramework": "html",
              "sourceMode": "exact",
              "matchedName": "navbar-20",
              "path": "registry/default/components/navbar/navbar-20.html"
            },
            "weapp": {
              "sourceFramework": "weapp",
              "sourceMode": "exact",
              "matchedName": "navbar-20",
              "path": "registry/default/components/navbar/navbar-20.wxml"
            }
          }
        },
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/react"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false,
        "category": "navbars",
        "title": "Navbar · Power"
      },
      "categories": [
        "navbars",
        "navbar"
      ],
      "dependencies": [
        "@timui/react"
      ]
    },
    {
      "name": "card",
      "type": "registry:ui",
      "files": [
        {
          "path": "registry/default/ui/card.tsx",
          "type": "registry:ui",
          "target": "components/ui/card.tsx",
          "content": "import * as React from 'react'\nimport {\n  cardContentVariants,\n  cardDescriptionVariants,\n  cardFooterVariants,\n  cardHeaderVariants,\n  cardTitleVariants,\n  cardVariants,\n  cn,\n} from '@timui/core'\n\nconst Card = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, ...props }, ref) => (\n    <div ref={ref} className={cn(cardVariants(), className)} {...props} />\n  )\n)\nCard.displayName = 'Card'\n\nconst CardHeader = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, ...props }, ref) => (\n    <div ref={ref} className={cn(cardHeaderVariants(), className)} {...props} />\n  )\n)\nCardHeader.displayName = 'CardHeader'\n\nconst CardTitle = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLHeadingElement>>(\n  ({ className, ...props }, ref) => (\n    <h3 ref={ref} className={cn(cardTitleVariants(), className)} {...props} />\n  )\n)\nCardTitle.displayName = 'CardTitle'\n\nconst CardDescription = React.forwardRef<\n  HTMLParagraphElement,\n  React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n  <p ref={ref} className={cn(cardDescriptionVariants(), className)} {...props} />\n))\nCardDescription.displayName = 'CardDescription'\n\nconst CardContent = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, ...props }, ref) => (\n    <div ref={ref} className={cn(cardContentVariants(), className)} {...props} />\n  )\n)\nCardContent.displayName = 'CardContent'\n\nconst CardFooter = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, ...props }, ref) => (\n    <div ref={ref} className={cn(cardFooterVariants(), className)} {...props} />\n  )\n)\nCardFooter.displayName = 'CardFooter'\n\nexport { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }\n"
        },
        {
          "path": "registry/default/vue/card/card-content.vue",
          "target": "components/ui/card/card-content.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, cardContentVariants } from \"@timui/core\";\nimport { type HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{\n  class?: HTMLAttributes[\"class\"];\n}>();\n</script>\n\n<template>\n  <div :class=\"cn(cardContentVariants(), props.class)\">\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/card/card-description.vue",
          "target": "components/ui/card/card-description.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, cardDescriptionVariants } from \"@timui/core\";\nimport { type HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{\n  class?: HTMLAttributes[\"class\"];\n}>();\n</script>\n\n<template>\n  <p :class=\"cn(cardDescriptionVariants(), props.class)\">\n    <slot />\n  </p>\n</template>\n"
        },
        {
          "path": "registry/default/vue/card/card-footer.vue",
          "target": "components/ui/card/card-footer.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, cardFooterVariants } from \"@timui/core\";\nimport { type HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{\n  class?: HTMLAttributes[\"class\"];\n}>();\n</script>\n\n<template>\n  <div :class=\"cn(cardFooterVariants(), props.class)\">\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/card/card-header.vue",
          "target": "components/ui/card/card-header.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, cardHeaderVariants } from \"@timui/core\";\nimport { type HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{\n  class?: HTMLAttributes[\"class\"];\n}>();\n</script>\n\n<template>\n  <div :class=\"cn(cardHeaderVariants(), props.class)\">\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/card/card-title.vue",
          "target": "components/ui/card/card-title.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, cardTitleVariants } from \"@timui/core\";\nimport { type HTMLAttributes } from \"vue\";\n\nconst props = defineProps<{\n  class?: HTMLAttributes[\"class\"];\n}>();\n</script>\n\n<template>\n  <h3 :class=\"cn(cardTitleVariants(), props.class)\">\n    <slot />\n  </h3>\n</template>\n"
        },
        {
          "path": "registry/default/vue/card/card.vue",
          "target": "components/ui/card/card.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { cn, cardVariants, cardHeaderVariants, cardTitleVariants, cardDescriptionVariants, cardContentVariants, cardFooterVariants } from \"@timui/core\";\nimport { type HTMLAttributes } from \"vue\";\n\ndefineOptions({\n  inheritAttrs: false,\n})\n\nconst props = defineProps<{\n  class?: HTMLAttributes[\"class\"];\n}>();\n</script>\n\n<template>\n  <div :class=\"cn(cardVariants(), props.class)\">\n    <slot />\n  </div>\n</template>\n\n<!-- Note: In Vue, we typically have separate components for sub-parts or use slots with exposing internal components? -->\n<!-- The existing card.vue might just be the Root. Where are the others? -->\n<!-- If they don't exist, I need to create them. -->\n"
        },
        {
          "path": "registry/default/html/card.html",
          "target": "components/ui/card.html",
          "type": "registry:component",
          "content": "<div class=\"rounded-lg border bg-card text-card-foreground shadow-sm\">\n    <div class=\"flex flex-col space-y-1.5 p-6\">\n        <h3 class=\"text-2xl font-semibold leading-none tracking-tight\">Card Title</h3>\n        <p class=\"text-sm text-muted-foreground\">Card Description</p>\n    </div>\n    <div class=\"p-6 pt-0\">Card Content</div>\n    <div class=\"flex items-center p-6 pt-0\">Card Footer</div>\n</div>"
        },
        {
          "path": "registry/default/weapp/card.wxml",
          "target": "components/ui/card.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}} card\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/card.wxss",
          "target": "components/ui/card.wxss",
          "type": "registry:component",
          "content": "/* packages/weapp/src/card/card.wxss */\n"
        },
        {
          "path": "registry/default/weapp/card.ts",
          "target": "components/ui/card.ts",
          "type": "registry:component",
          "content": "import { cardVariants } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    extClass: { type: String, value: '' },\n  },\n\n  data: {\n    className: '',\n  },\n\n  lifetimes: {\n    attached() {\n      this.updateClassName()\n    },\n  },\n\n  observers: {\n    extClass: function () {\n      this.updateClassName()\n    },\n  },\n\n  methods: {\n    updateClassName() {\n      // Use core package's cardVariants for consistent styling\n      const { baseClass } = cardVariants({\n        className: this.properties.extClass,\n      })\n\n      this.setData({ className: baseClass })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/card.json",
          "target": "components/ui/card.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        },
        {
          "path": "registry/default/weapp/card-content/card-content.wxml",
          "target": "components/ui/card-content/card-content.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/card-content/card-content.wxss",
          "target": "components/ui/card-content/card-content.wxss",
          "type": "registry:component",
          "content": "/* packages/weapp/src/card-content/card-content.wxss */\n"
        },
        {
          "path": "registry/default/weapp/card-content/card-content.json",
          "target": "components/ui/card-content/card-content.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/card-content/card-content.ts",
          "target": "components/ui/card-content/card-content.ts",
          "type": "registry:component",
          "content": "import { cardContentVariants } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: { type: String, value: '' },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass) {\n      this.setData({\n        className: cardContentVariants({ className: extClass }),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/card-description/card-description.wxml",
          "target": "components/ui/card-description/card-description.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/card-description/card-description.wxss",
          "target": "components/ui/card-description/card-description.wxss",
          "type": "registry:component",
          "content": "/* packages/weapp/src/card-description/card-description.wxss */\n"
        },
        {
          "path": "registry/default/weapp/card-description/card-description.json",
          "target": "components/ui/card-description/card-description.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/card-description/card-description.ts",
          "target": "components/ui/card-description/card-description.ts",
          "type": "registry:component",
          "content": "import { cardDescriptionVariants } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: { type: String, value: '' },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass) {\n      this.setData({\n        className: cardDescriptionVariants({ className: extClass }),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/card-footer/card-footer.wxml",
          "target": "components/ui/card-footer/card-footer.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/card-footer/card-footer.wxss",
          "target": "components/ui/card-footer/card-footer.wxss",
          "type": "registry:component",
          "content": "/* packages/weapp/src/card-footer/card-footer.wxss */\n"
        },
        {
          "path": "registry/default/weapp/card-footer/card-footer.json",
          "target": "components/ui/card-footer/card-footer.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/card-footer/card-footer.ts",
          "target": "components/ui/card-footer/card-footer.ts",
          "type": "registry:component",
          "content": "import { cardFooterVariants } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: { type: String, value: '' },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass) {\n      this.setData({\n        className: cardFooterVariants({ className: extClass }),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/card-header/card-header.wxml",
          "target": "components/ui/card-header/card-header.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/card-header/card-header.wxss",
          "target": "components/ui/card-header/card-header.wxss",
          "type": "registry:component",
          "content": "/* packages/weapp/src/card-header/card-header.wxss */\n"
        },
        {
          "path": "registry/default/weapp/card-header/card-header.json",
          "target": "components/ui/card-header/card-header.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/card-header/card-header.ts",
          "target": "components/ui/card-header/card-header.ts",
          "type": "registry:component",
          "content": "import { cardHeaderVariants } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: { type: String, value: '' },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass) {\n      this.setData({\n        className: cardHeaderVariants({ className: extClass }),\n      })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/card-title/card-title.wxml",
          "target": "components/ui/card-title/card-title.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{className}}\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/card-title/card-title.wxss",
          "target": "components/ui/card-title/card-title.wxss",
          "type": "registry:component",
          "content": "/* packages/weapp/src/card-title/card-title.wxss */\n"
        },
        {
          "path": "registry/default/weapp/card-title/card-title.json",
          "target": "components/ui/card-title/card-title.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/card-title/card-title.ts",
          "target": "components/ui/card-title/card-title.ts",
          "type": "registry:component",
          "content": "import { cardTitleVariants } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: { type: String, value: '' },\n  },\n  data: {\n    className: '',\n  },\n  observers: {\n    extClass: function (extClass) {\n      this.setData({\n        className: cardTitleVariants({ className: extClass }),\n      })\n    },\n  },\n})\n"
        }
      ],
      "dependencies": [
        "@timui/core"
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core"
            ]
          },
          "weapp": {},
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "sheet",
      "type": "registry:ui",
      "dependencies": [
        "@timui/core",
        "@zag-js/react",
        "class-variance-authority"
      ],
      "optionalPeerDependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "registry/default/ui/sheet.tsx",
          "type": "registry:ui",
          "target": "components/ui/sheet.tsx",
          "content": "'use client'\n\nimport * as React from 'react'\nimport type { AssertNoExtraKeys, SheetProps as CoreSheetProps } from '@timui/core'\nimport {\n  cn,\n  sheetCloseIconVariants,\n  sheetCloseVariants,\n  sheetContentVariants,\n  sheetDescriptionVariants,\n  sheetFooterVariants,\n  sheetHeaderVariants,\n  sheetOverlayVariants,\n  sheetPositionerVariants,\n  sheetTitleVariants,\n} from '@timui/core'\nimport { Portal } from '@zag-js/react'\nimport type { VariantProps } from 'class-variance-authority'\nimport { X } from 'lucide-react'\n\nimport { useSheet } from './sheet/use-sheet'\nimport { SheetProvider, useSheetContext } from './sheet/use-sheet-context'\n\n// Context is imported from ./sheet/use-sheet-context\n\ntype SheetProps = CoreSheetProps & { children?: React.ReactNode }\ntype _SheetPropsGuard = AssertNoExtraKeys<\n  SheetProps,\n  CoreSheetProps & { children?: React.ReactNode }\n>\n\nconst Sheet = (props: SheetProps) => {\n  const { children, ...machineProps } = props\n  const api = useSheet(machineProps)\n\n  return <SheetProvider value={api}>{children}</SheetProvider>\n}\n\nconst SheetTrigger = ({ children }: { children: React.ReactElement }) => {\n  const api = useSheetContext()\n  return React.cloneElement(children, api.getTriggerProps())\n}\n\nconst SheetClose = ({ children }: { children: React.ReactElement }) => {\n  const api = useSheetContext()\n  return React.cloneElement(children, api.getCloseTriggerProps())\n}\n\nconst SheetPortal = ({ children }: { children?: React.ReactNode }) => <>{children}</>\n\nconst SheetOverlay = React.forwardRef<HTMLDivElement, React.ComponentPropsWithoutRef<'div'>>(\n  ({ className, ...props }, ref) => {\n    const api = useSheetContext()\n\n    return (\n      <div\n        {...api.getBackdropProps()}\n        ref={ref}\n        className={cn(sheetOverlayVariants(), className)}\n        {...props}\n      />\n    )\n  }\n)\nSheetOverlay.displayName = 'SheetOverlay'\n\ninterface SheetContentProps\n  extends React.ComponentPropsWithoutRef<'div'>, VariantProps<typeof sheetContentVariants> {}\n\nconst SheetContent = React.forwardRef<HTMLDivElement, SheetContentProps>(\n  ({ side = 'right', className, children, ...props }, ref) => {\n    const api = useSheetContext()\n    if (!api.open) return null\n\n    return (\n      <Portal>\n        <SheetOverlay />\n        <div\n          {...api.getPositionerProps()} // Zag Dialog positioner usually handles centering, for Sheet we override with fixed positioning\n          className={cn(sheetPositionerVariants())}\n          style={{ zIndex: 50 }}\n        >\n          {/* Wrapper to handle Sheet transitions and positioning logic manually if needed or via api.contentProps? \n               Zag Dialog assumes centered modal. Sheet requires side docking. \n               We use `contentProps` but style it with Tailwind class `fixed ...`.\n           */}\n          <div\n            {...api.getContentProps()}\n            ref={ref}\n            className={cn(sheetContentVariants({ side }), className)}\n            {...props}\n          >\n            {children}\n            <button {...api.getCloseTriggerProps()} className={cn(sheetCloseVariants())}>\n              <X className={sheetCloseIconVariants()} />\n              <span className=\"sr-only\">Close</span>\n            </button>\n          </div>\n        </div>\n      </Portal>\n    )\n  }\n)\nSheetContent.displayName = 'SheetContent'\n\nconst SheetHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (\n  <div className={cn(sheetHeaderVariants(), className)} {...props} />\n)\nSheetHeader.displayName = 'SheetHeader'\n\nconst SheetFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (\n  <div className={cn(sheetFooterVariants(), className)} {...props} />\n)\nSheetFooter.displayName = 'SheetFooter'\n\nconst SheetTitle = React.forwardRef<HTMLHeadingElement, React.HTMLAttributes<HTMLHeadingElement>>(\n  ({ className, ...props }, ref) => {\n    const api = useSheetContext()\n    return (\n      <h2\n        {...api?.getTitleProps?.()}\n        ref={ref}\n        className={cn(sheetTitleVariants(), className)}\n        {...props}\n      />\n    )\n  }\n)\nSheetTitle.displayName = 'SheetTitle'\n\nconst SheetDescription = React.forwardRef<\n  HTMLParagraphElement,\n  React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => {\n  const api = useSheetContext()\n  return (\n    <p\n      {...api?.getDescriptionProps?.()}\n      ref={ref}\n      className={cn(sheetDescriptionVariants(), className)}\n      {...props}\n    />\n  )\n})\nSheetDescription.displayName = 'SheetDescription'\n\nexport {\n  Sheet,\n  SheetTrigger,\n  SheetClose,\n  SheetContent,\n  SheetHeader,\n  SheetFooter,\n  SheetTitle,\n  SheetDescription,\n  SheetPortal,\n  SheetOverlay,\n}\n"
        },
        {
          "path": "registry/default/ui/sheet/use-sheet-context.ts",
          "target": "components/ui/sheet/use-sheet-context.ts",
          "type": "registry:ui",
          "content": "import * as React from 'react'\nimport type { dialogConnect } from '@timui/core'\n\nexport type SheetContextValue = ReturnType<typeof dialogConnect>\n\nconst SheetContext = React.createContext<SheetContextValue | null>(null)\n\nexport const SheetProvider: React.Provider<SheetContextValue | null> = SheetContext.Provider\n\nexport function useSheetContext(): SheetContextValue {\n  const context = React.useContext(SheetContext)\n  if (!context) {\n    throw new Error('Sheet components must be used within `<SheetProvider />`')\n  }\n  return context\n}\n"
        },
        {
          "path": "registry/default/ui/sheet/use-sheet.ts",
          "target": "components/ui/sheet/use-sheet.ts",
          "type": "registry:ui",
          "content": "import * as React from 'react'\nimport { dialogConnect, dialogMachine, type SheetProps } from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/react'\n\nexport interface UseSheetProps extends SheetProps {\n  id?: string\n}\n\nexport function useSheet(props: UseSheetProps) {\n  const generatedId = React.useId()\n  const service = useMachine(dialogMachine, {\n    id: props.id ?? generatedId,\n    open: props.open,\n    defaultOpen: props.defaultOpen,\n    modal: props.modal,\n    onOpenChange(details) {\n      props.onOpenChange?.(details.open)\n    },\n  })\n\n  return React.useMemo(\n    () => dialogConnect(service as Parameters<typeof dialogConnect>[0], normalizeProps),\n    [service]\n  )\n}\n"
        },
        {
          "path": "registry/default/vue/sheet/sheet-close.vue",
          "target": "components/ui/sheet/sheet-close.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, type Component, type HTMLAttributes } from 'vue'\nimport { cn } from '@timui/core'\nimport { Primitive } from '../../primitive'\nimport { useSheetContext } from './use-sheet-context'\n\nconst props = withDefaults(\n  defineProps<{\n    as?: string | Component\n    asChild?: boolean\n    class?: HTMLAttributes['class']\n  }>(),\n  {\n    as: 'button',\n  }\n)\n\nconst api = useSheetContext()\nconst closeProps = computed(() => ({\n  ...(api.value.getCloseTriggerProps?.() ?? {}),\n  type: props.asChild ? undefined : 'button',\n  'data-slot': 'sheet-close',\n}))\n</script>\n\n<template>\n  <Primitive\n    :as=\"props.as\"\n    :as-child=\"props.asChild\"\n    :class=\"cn(props.class)\"\n    v-bind=\"closeProps\"\n  >\n    <slot />\n  </Primitive>\n</template>\n"
        },
        {
          "path": "registry/default/vue/sheet/sheet-content.vue",
          "target": "components/ui/sheet/sheet-content.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, type HTMLAttributes } from \"vue\";\nimport { X } from \"lucide-vue-next\";\nimport {\n  cn,\n  sheetCloseIconVariants,\n  sheetCloseVariants,\n  sheetContentVariants,\n  sheetOverlayVariants,\n  sheetPositionerVariants,\n} from \"@timui/core\";\nimport { useSheetContext } from \"./use-sheet-context\";\nimport Presence from \"../presence/presence.vue\";\n\nconst props = withDefaults(\n  defineProps<{\n    class?: HTMLAttributes[\"class\"];\n    side?: \"top\" | \"right\" | \"bottom\" | \"left\";\n  }>(),\n  { side: \"right\" }\n);\n\nconst api = useSheetContext();\nconst isOpen = computed(() => api.value?.open);\n</script>\n\n<template>\n  <Teleport to=\"body\">\n    <Presence\n      :present=\"api?.open\"\n      lazyMount\n      unmountOnExit\n      v-bind=\"api?.getBackdropProps?.()\"\n      :class=\"cn(sheetOverlayVariants())\"\n    />\n    <Presence\n      :present=\"api?.open\"\n      lazyMount\n      unmountOnExit\n      v-bind=\"api?.getPositionerProps?.()\"\n      :class=\"cn(sheetPositionerVariants())\"\n    >\n      <div\n        v-bind=\"api?.getContentProps?.()\"\n        :class=\"cn(sheetContentVariants({ side: props.side }), props.class)\"\n      >\n        <slot />\n        <button\n          v-bind=\"api?.getCloseTriggerProps?.()\"\n          :class=\"cn(sheetCloseVariants())\"\n        >\n          <X :class=\"sheetCloseIconVariants()\" />\n          <span class=\"sr-only\">Close</span>\n        </button>\n      </div>\n    </Presence>\n  </Teleport>\n</template>\n"
        },
        {
          "path": "registry/default/vue/sheet/sheet-description.vue",
          "target": "components/ui/sheet/sheet-description.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from \"vue\";\nimport { cn, sheetDescriptionVariants } from \"@timui/core\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\n</script>\n\n<template>\n  <p :class=\"cn(sheetDescriptionVariants(), props.class)\">\n    <slot />\n  </p>\n</template>\n"
        },
        {
          "path": "registry/default/vue/sheet/sheet-footer.vue",
          "target": "components/ui/sheet/sheet-footer.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed } from \"vue\";\nimport { cn, sheetFooterVariants } from \"@timui/core\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\n</script>\n\n<template>\n  <div :class=\"cn(sheetFooterVariants(), props.class)\">\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/sheet/sheet-header.vue",
          "target": "components/ui/sheet/sheet-header.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed } from \"vue\";\nimport { cn, sheetHeaderVariants } from \"@timui/core\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\n</script>\n\n<template>\n  <div :class=\"cn(sheetHeaderVariants(), props.class)\">\n    <slot />\n  </div>\n</template>\n"
        },
        {
          "path": "registry/default/vue/sheet/sheet-title.vue",
          "target": "components/ui/sheet/sheet-title.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from \"vue\";\nimport { cn, sheetTitleVariants } from \"@timui/core\";\n\nconst props = defineProps<{ class?: HTMLAttributes[\"class\"] }>();\n</script>\n\n<template>\n  <h2 :class=\"cn(sheetTitleVariants(), props.class)\">\n    <slot />\n  </h2>\n</template>\n"
        },
        {
          "path": "registry/default/vue/sheet/sheet-trigger.vue",
          "target": "components/ui/sheet/sheet-trigger.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, inject, type Component, type HTMLAttributes, type Ref } from \"vue\";\nimport { cn } from \"@timui/core\";\nimport { Primitive } from '../../primitive';\n\nconst props = withDefaults(\n  defineProps<{\n    as?: string | Component;\n    asChild?: boolean;\n    class?: HTMLAttributes[\"class\"];\n  }>(),\n  {\n    as: \"button\",\n  }\n);\n\ntype BindValue = string | number | boolean | null | undefined | ((...args: never[]) => void);\ntype SheetApi = {\n  getTriggerProps?: () => Record<string, BindValue>;\n};\nconst api = inject(\"sheet\") as Ref<SheetApi | undefined> | undefined;\nconst triggerProps = computed(() => api?.value?.getTriggerProps?.() || {});\n</script>\n\n<template>\n  <Primitive\n    :as=\"props.as\"\n    :as-child=\"props.asChild\"\n    v-bind=\"triggerProps\"\n    :class=\"cn(props.class)\"\n  >\n    <slot />\n  </Primitive>\n</template>\n"
        },
        {
          "path": "registry/default/vue/sheet/sheet.vue",
          "target": "components/ui/sheet/sheet.vue",
          "type": "registry:component",
          "content": "<script setup lang=\"ts\">\nimport { computed, provide, watch } from \"vue\";\nimport type { AssertNoExtraKeys, SheetProps as CoreSheetProps } from \"@timui/core\";\nimport { useSheet } from \"./use-sheet\";\nimport { provideSheetContext } from \"./use-sheet-context\";\n\ntype SheetProps = Omit<CoreSheetProps, \"id\"> & { id?: string };\ntype _SheetPropsGuard = AssertNoExtraKeys<SheetProps, CoreSheetProps>;\n\nconst props = defineProps<SheetProps>();\nlet sheetId = 0;\nconst localId = `sheet-${++sheetId}`;\n\nconst emit = defineEmits([\"update:open\", \"openChange\"]);\nconst api = useSheet({\n  id: props.id ?? localId,\n  open: props.open,\n  defaultOpen: props.defaultOpen,\n  modal: true,\n  onOpenChange(open) {\n    emit(\"update:open\", open);\n    emit(\"openChange\", open);\n  },\n});\n\nprovideSheetContext(api);\n\nwatch(\n  () => props.open,\n  (val?: boolean) => {\n    if (val !== undefined && val !== api.value?.open) {\n      api.value?.setOpen(val);\n    }\n  }\n);\n</script>\n\n<template>\n  <slot />\n</template>\n"
        },
        {
          "path": "registry/default/vue/sheet/use-sheet-context.ts",
          "target": "components/ui/sheet/use-sheet-context.ts",
          "type": "registry:component",
          "content": "import type { DialogApi } from '@timui/core'\nimport { inject, provide, type ComputedRef } from 'vue'\n\nexport const SheetContextKey = Symbol('SheetContext')\n\nexport function provideSheetContext(api: ComputedRef<DialogApi>) {\n  provide(SheetContextKey, api)\n}\n\nexport function useSheetContext(): ComputedRef<DialogApi> {\n  const context = inject<ComputedRef<DialogApi>>(SheetContextKey)\n  if (!context) {\n    throw new Error('useSheetContext must be used within a SheetProvider')\n  }\n  return context\n}\n"
        },
        {
          "path": "registry/default/vue/sheet/use-sheet.ts",
          "target": "components/ui/sheet/use-sheet.ts",
          "type": "registry:component",
          "content": "import { dialogConnect, dialogMachine, type DialogApi } from '@timui/core'\nimport { normalizeProps, useMachine } from '@zag-js/vue'\nimport { computed, type ComputedRef, useId } from 'vue'\n\nexport type UseSheetProps = {\n  id?: string\n  open?: boolean\n  defaultOpen?: boolean\n  modal?: boolean\n  onOpenChange?: (open: boolean) => void\n}\n\nexport function useSheet(props: UseSheetProps) {\n  const generatedId = useId()\n\n  const service = useMachine(dialogMachine, {\n    id: props.id ?? generatedId,\n    open: props.open,\n    defaultOpen: props.defaultOpen,\n    modal: props.modal ?? true,\n    onOpenChange(details) {\n      props.onOpenChange?.(details.open)\n    },\n  })\n\n  return computed(() => dialogConnect(service, normalizeProps))\n}\n"
        },
        {
          "path": "registry/default/html/sheet.html",
          "target": "components/ui/sheet.html",
          "type": "registry:component",
          "content": "<div data-timui-root data-timui-init=\"auto\">\n  <div data-slot=\"sheet-root\" data-state=\"closed\">\n    <button\n      data-slot=\"sheet-trigger\"\n      type=\"button\"\n      aria-expanded=\"false\"\n      class=\"rounded-md border px-4 py-2 text-sm\"\n    >\n      Open sheet\n    </button>\n    <div\n      data-slot=\"sheet-overlay\"\n      data-state=\"closed\"\n      hidden\n      class=\"fixed inset-0 z-40 bg-black/40\"\n    ></div>\n    <aside\n      data-slot=\"sheet-content\"\n      data-state=\"closed\"\n      hidden\n      class=\"fixed right-0 top-0 z-50 h-full w-80 border-l border-input bg-background p-4 shadow-lg\"\n    >\n      <div class=\"space-y-3\">\n        <h2 class=\"text-foreground text-lg font-semibold\">Sheet Title</h2>\n        <p class=\"text-muted-foreground text-sm\">Panel content goes here.</p>\n        <button data-slot=\"sheet-close\" type=\"button\" class=\"rounded-md border px-3 py-2 text-sm\">Close</button>\n      </div>\n    </aside>\n  </div>\n</div>\n<script type=\"module\">\n  import { autoInitHtmlRuntime } from '@timui/html'\n  autoInitHtmlRuntime({ components: ['sheet'] })\n</script>"
        },
        {
          "path": "registry/default/weapp/sheet.wxml",
          "target": "components/ui/sheet.wxml",
          "type": "registry:component",
          "content": "<root-portal wx:if=\"{{api.open}}\">\n  <!-- Overlay -->\n  <view \n    class=\"{{overlayClass}}\" \n    data-state=\"{{api.open ? 'open' : 'closed'}}\" \n    bindtap=\"onBackdropTap\" \n    catchtouchmove=\"noop\"\n  ></view>\n\n  <!-- Sheet Content -->\n  <view \n    class=\"{{contentClass}}\" \n    data-state=\"{{api.open ? 'open' : 'closed'}}\"\n    data-side=\"{{side}}\"\n    id=\"{{api.contentProps.id}}\"\n    role=\"dialog\"\n    aria-modal=\"true\"\n    aria-label=\"{{api.contentProps['aria-label']}}\"\n  >\n    <slot></slot>\n    \n    <!-- Close Button -->\n    <view \n      class=\"{{closeClass}}\" \n      data-state=\"{{api.open ? 'open' : 'closed'}}\"\n      bindtap=\"onCloseTap\"\n    >\n      <text>✕</text>\n    </view>\n  </view>\n</root-portal>\n"
        },
        {
          "path": "registry/default/weapp/sheet.wxss",
          "target": "components/ui/sheet.wxss",
          "type": "registry:component",
          "content": "/* Sheet 底部安全区适配（iPhone X+ Home Indicator） */\n.sheet-safe-area {\n  padding-bottom: constant(safe-area-inset-bottom); /* iOS < 11.2 */\n  padding-bottom: env(safe-area-inset-bottom);\n}\n"
        },
        {
          "path": "registry/default/weapp/sheet.ts",
          "target": "components/ui/sheet.ts",
          "type": "registry:component",
          "content": "import {\n  sheetCloseVariants,\n  sheetContentVariants,\n  sheetDescriptionVariants,\n  sheetOverlayVariants,\n  sheetTitleVariants,\n} from '@timui/core'\n\nimport { emitTimEvent, resolveClasses } from '../utils'\nimport { setupSheetMachine } from './use-sheet'\n\ntype MachineEvent =\n  | string\n  | {\n      type: string\n      [key: string]: string | number | boolean | string[] | number[] | null | undefined\n    }\n\ntype SheetSide = 'top' | 'bottom' | 'left' | 'right'\n\ntype WeappSheetApi = {\n  open?: boolean\n  backdropProps?: {\n    onClick?: () => void\n  }\n  closeTriggerProps?: {\n    onClick?: () => void\n  }\n}\n\ntype WeappService = {\n  setContext: (context: { open?: boolean }) => void\n}\n\ntype OpenChangeDetails = {\n  open: boolean\n}\n\ntype WeappSheetInternal =\n  WechatMiniprogram.Component.InstanceMethods<WechatMiniprogram.IAnyObject> & {\n    _service?: WeappService\n    _cleanup?: () => void\n    _send?: (event: MachineEvent) => void\n    _connect?: (state: object, send: (event: MachineEvent) => void) => WeappSheetApi\n    data: {\n      api: WeappSheetApi\n    }\n    properties: {\n      open: boolean\n      side: string\n      id: string\n      extClass: string\n    }\n  }\n\nfunction toSheetSide(value: string): SheetSide {\n  if (value === 'top' || value === 'left' || value === 'right') return value\n  return 'bottom'\n}\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n\n  properties: {\n    open: { type: Boolean, value: false },\n    side: { type: String, value: 'bottom' }, // 'top' | 'bottom' | 'left' | 'right'\n    id: { type: String, value: 'sheet' },\n    extClass: { type: String, value: '' },\n  },\n\n  data: {\n    api: {} as WeappSheetApi,\n    contentClass: '',\n    backdropClass: '',\n    titleClass: '',\n    descriptionClass: '',\n    closeClass: '',\n  },\n\n  lifetimes: {\n    attached() {\n      const self = this as WeappSheetInternal\n      const { service, cleanup, send, connect } = setupSheetMachine(this, {\n        id: this.properties.id || 'sheet',\n        open: this.properties.open,\n        onOpenChange: (details: OpenChangeDetails) => {\n          this.triggerEvent('change', details)\n          emitTimEvent(this, 'openchange', 'sheet.openChange', this.properties.id || 'sheet', {\n            open: details.open,\n          })\n          if (details.open) this.triggerEvent('open')\n          else this.triggerEvent('close')\n        },\n      })\n      self._service = service as WeappService\n      self._cleanup = cleanup\n      self._send = send as (event: MachineEvent) => void\n      self._connect = connect\n    },\n    detached() {\n      const self = this as WeappSheetInternal\n      self._cleanup?.()\n    },\n  },\n\n  observers: {\n    state: function (state) {\n      const self = this as WeappSheetInternal\n      if (!state || !self._send || !self._connect) return\n\n      const api = self._connect(state, self._send) as WeappSheetApi\n\n      const side = toSheetSide(this.properties.side)\n      const contentClass = resolveClasses(sheetContentVariants({ side }), self.properties.extClass)\n      const backdropClass = resolveClasses(sheetOverlayVariants())\n\n      const titleClass = resolveClasses(sheetTitleVariants())\n      const descriptionClass = resolveClasses(sheetDescriptionVariants())\n      const closeClass = resolveClasses(sheetCloseVariants())\n\n      this.setData({\n        api,\n        contentClass,\n        backdropClass,\n        titleClass,\n        descriptionClass,\n        closeClass,\n      })\n    },\n    open: function (val) {\n      const self = this as WeappSheetInternal\n      if (self._service && val !== self.data.api.open) {\n        self._send?.(val ? 'OPEN' : 'CLOSE')\n      }\n    },\n  },\n\n  methods: {\n    onBackdropTap() {\n      const self = this as WeappSheetInternal\n      self.data.api.backdropProps?.onClick?.()\n    },\n    onCloseTap() {\n      const self = this as WeappSheetInternal\n      self.data.api.closeTriggerProps?.onClick?.()\n    },\n    noop() {},\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/sheet.json",
          "target": "components/ui/sheet.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}\n"
        },
        {
          "path": "registry/default/weapp/sheet-description/sheet-description.wxml",
          "target": "components/ui/sheet-description/sheet-description.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{baseClass}}\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/sheet-description/sheet-description.wxss",
          "target": "components/ui/sheet-description/sheet-description.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/sheet-description/sheet-description.json",
          "target": "components/ui/sheet-description/sheet-description.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/sheet-description/sheet-description.ts",
          "target": "components/ui/sheet-description/sheet-description.ts",
          "type": "registry:component",
          "content": "import { sheetDescriptionVariants } from '@timui/core'\n\nimport { resolveClasses } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: { type: String, value: '' },\n  },\n  data: { baseClass: '' },\n  observers: {\n    extClass: function (extClass) {\n      const { baseClass } = resolveClasses(sheetDescriptionVariants(), extClass)\n      this.setData({ baseClass })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/sheet-footer/sheet-footer.wxml",
          "target": "components/ui/sheet-footer/sheet-footer.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{baseClass}}\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/sheet-footer/sheet-footer.wxss",
          "target": "components/ui/sheet-footer/sheet-footer.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/sheet-footer/sheet-footer.json",
          "target": "components/ui/sheet-footer/sheet-footer.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/sheet-footer/sheet-footer.ts",
          "target": "components/ui/sheet-footer/sheet-footer.ts",
          "type": "registry:component",
          "content": "import { sheetFooterVariants } from '@timui/core'\n\nimport { resolveClasses } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: { type: String, value: '' },\n  },\n  data: { baseClass: '' },\n  observers: {\n    extClass: function (extClass) {\n      const { baseClass } = resolveClasses(sheetFooterVariants(), extClass)\n      this.setData({ baseClass })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/sheet-header/sheet-header.wxml",
          "target": "components/ui/sheet-header/sheet-header.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{baseClass}}\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/sheet-header/sheet-header.wxss",
          "target": "components/ui/sheet-header/sheet-header.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/sheet-header/sheet-header.json",
          "target": "components/ui/sheet-header/sheet-header.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/sheet-header/sheet-header.ts",
          "target": "components/ui/sheet-header/sheet-header.ts",
          "type": "registry:component",
          "content": "import { sheetHeaderVariants } from '@timui/core'\n\nimport { resolveClasses } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: { type: String, value: '' },\n  },\n  data: { baseClass: '' },\n  observers: {\n    extClass: function (extClass) {\n      const { baseClass } = resolveClasses(sheetHeaderVariants(), extClass)\n      this.setData({ baseClass })\n    },\n  },\n})\n"
        },
        {
          "path": "registry/default/weapp/sheet-title/sheet-title.wxml",
          "target": "components/ui/sheet-title/sheet-title.wxml",
          "type": "registry:component",
          "content": "<view class=\"{{baseClass}}\">\n  <slot></slot>\n</view>\n"
        },
        {
          "path": "registry/default/weapp/sheet-title/sheet-title.wxss",
          "target": "components/ui/sheet-title/sheet-title.wxss",
          "type": "registry:component",
          "content": ""
        },
        {
          "path": "registry/default/weapp/sheet-title/sheet-title.json",
          "target": "components/ui/sheet-title/sheet-title.json",
          "type": "registry:component",
          "content": "{\n  \"component\": true\n}\n"
        },
        {
          "path": "registry/default/weapp/sheet-title/sheet-title.ts",
          "target": "components/ui/sheet-title/sheet-title.ts",
          "type": "registry:component",
          "content": "import { sheetTitleVariants } from '@timui/core'\n\nimport { resolveClasses } from '../utils'\n\nComponent({\n  options: {\n    styleIsolation: 'apply-shared',\n    pureDataPattern: /^_/,\n  },\n\n  externalClasses: ['ext-class'],\n  properties: {\n    extClass: { type: String, value: '' },\n  },\n  data: { baseClass: '' },\n  observers: {\n    extClass: function (extClass) {\n      const { baseClass } = resolveClasses(sheetTitleVariants(), extClass)\n      this.setData({ baseClass })\n    },\n  },\n})\n"
        }
      ],
      "meta": {
        "frameworks": [
          "react",
          "vue",
          "weapp",
          "html"
        ],
        "dependenciesByFramework": {
          "react": {
            "dependencies": [
              "@timui/core",
              "@zag-js/react",
              "class-variance-authority"
            ],
            "optionalPeerDependencies": [
              "lucide-react"
            ]
          },
          "vue": {
            "dependencies": [
              "@timui/core",
              "@zag-js/vue"
            ],
            "optionalPeerDependencies": [
              "lucide-vue-next"
            ]
          },
          "weapp": {
            "dependencies": [
              "@timui/core"
            ]
          },
          "html": {}
        },
        "placeholder": false,
        "clientOnly": false
      }
    },
    {
      "name": "login-01",
      "type": "registry:block",
      "description": "Block: login-01",
      "files": [
        {
          "path": "blocks/authentication/login-01.tsx",
          "content": "import { Button } from '@/components/ui/button'\nimport {\n  Card,\n  CardContent,\n  CardDescription,\n  CardFooter,\n  CardHeader,\n  CardTitle,\n} from '@/components/ui/card'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\n\nexport default function Login01() {\n  return (\n    <Card className=\"w-full max-w-sm\">\n      <CardHeader>\n        <CardTitle className=\"text-2xl\">Login</CardTitle>\n        <CardDescription>Enter your email below to login to your account.</CardDescription>\n      </CardHeader>\n      <CardContent className=\"grid gap-4\">\n        <div className=\"grid gap-2\">\n          <Label htmlFor=\"email\">Email</Label>\n          <Input id=\"email\" type=\"email\" placeholder=\"m@example.com\" required />\n        </div>\n        <div className=\"grid gap-2\">\n          <Label htmlFor=\"password\">Password</Label>\n          <Input id=\"password\" type=\"password\" required />\n        </div>\n      </CardContent>\n      <CardFooter>\n        <Button className=\"w-full\">Sign in</Button>\n      </CardFooter>\n    </Card>\n  )\n}\n",
          "type": "registry:block",
          "target": "components/blocks/authentication/login-01.tsx"
        }
      ],
      "categories": [
        "authentication"
      ],
      "registryDependencies": [
        "button",
        "card",
        "input",
        "label"
      ],
      "meta": {
        "frameworks": [
          "react"
        ],
        "category": "authentication",
        "tags": [
          "authentication"
        ],
        "clientOnly": false,
        "isActive": true,
        "mdxBody": "```tsx\nimport { Button } from '@/components/ui/button'\nimport {\n  Card,\n  CardContent,\n  CardDescription,\n  CardFooter,\n  CardHeader,\n  CardTitle,\n} from '@/components/ui/card'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\n\nexport default function Login01() {\n  return (\n    <Card className=\"w-full max-w-sm\">\n      <CardHeader>\n        <CardTitle className=\"text-2xl\">Login</CardTitle>\n        <CardDescription>Enter your email below to login to your account.</CardDescription>\n      </CardHeader>\n      <CardContent className=\"grid gap-4\">\n        <div className=\"grid gap-2\">\n          <Label htmlFor=\"email\">Email</Label>\n          <Input id=\"email\" type=\"email\" placeholder=\"m@example.com\" required />\n        </div>\n        <div className=\"grid gap-2\">\n          <Label htmlFor=\"password\">Password</Label>\n          <Input id=\"password\" type=\"password\" required />\n        </div>\n      </CardContent>\n      <CardFooter>\n        <Button className=\"w-full\">Sign in</Button>\n      </CardFooter>\n    </Card>\n  )\n}\n\n```",
        "title": "Login · Email"
      }
    },
    {
      "name": "agent-chat-01",
      "type": "registry:block",
      "description": "Block: agent-chat-01",
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "blocks/mobile-agent/agent-chat-01.tsx",
          "content": "'use client'\n\nimport { ArrowUp, Bot, CheckCircle2, Command, FileText, Sparkles } from 'lucide-react'\n\nimport { Avatar, AvatarFallback } from '@/components/ui/avatar'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\n\nconst tasks = [\n  { label: 'Read registry-index.json', done: true },\n  { label: 'Install wallet-home-01', done: true },\n  { label: 'Patch mobile safe area', done: false },\n]\n\nexport default function AgentChat01() {\n  return (\n    <section className=\"mx-auto flex min-h-dvh w-full max-w-md flex-col bg-background text-foreground\">\n      <header className=\"flex items-center gap-3 border-b px-5 pb-4 pt-safe-top\">\n        <Avatar className=\"size-11\">\n          <AvatarFallback className=\"bg-primary text-primary-foreground\">\n            <Bot className=\"size-5\" />\n          </AvatarFallback>\n        </Avatar>\n        <div className=\"min-w-0 flex-1\">\n          <h1 className=\"text-base font-semibold tracking-normal\">Timkit Agent</h1>\n          <p className=\"truncate text-xs text-muted-foreground\">Mobile UI registry session</p>\n        </div>\n        <Badge className=\"rounded-md\" variant=\"secondary\">\n          Live\n        </Badge>\n      </header>\n\n      <main className=\"flex flex-1 flex-col gap-4 overflow-y-auto px-5 py-5\">\n        <div className=\"max-w-[82%] rounded-lg bg-muted p-3\">\n          <p className=\"text-sm leading-relaxed\">\n            Build a mobile checkout screen using Timkit components and keep every tap target above\n            44px.\n          </p>\n        </div>\n\n        <div className=\"ml-auto max-w-[86%] rounded-lg bg-primary p-3 text-primary-foreground\">\n          <div className=\"mb-2 flex items-center gap-2 text-xs font-medium opacity-80\">\n            <Sparkles className=\"size-3.5\" />\n            Registry plan\n          </div>\n          <div className=\"grid gap-2\">\n            {tasks.map((task) => (\n              <div\n                key={task.label}\n                className=\"flex items-center gap-2 rounded-md bg-primary-foreground/10 px-2 py-2 text-sm\"\n              >\n                {task.done ? <CheckCircle2 className=\"size-4\" /> : <Command className=\"size-4\" />}\n                <span>{task.label}</span>\n              </div>\n            ))}\n          </div>\n        </div>\n\n        <div className=\"max-w-[88%] rounded-lg border bg-card p-3\">\n          <div className=\"mb-2 flex items-center gap-2 text-xs font-medium text-muted-foreground\">\n            <FileText className=\"size-3.5\" />\n            Command\n          </div>\n          <code className=\"block overflow-x-auto rounded-md bg-muted px-3 py-2 text-xs\">\n            npx @timui/cli add commerce-home-01 --framework react\n          </code>\n        </div>\n      </main>\n\n      <form className=\"flex gap-2 border-t px-5 py-3 pb-safe-bottom\">\n        <Input className=\"min-h-[44px] rounded-lg\" placeholder=\"Ask the agent to compose UI\" />\n        <Button aria-label=\"Send message\" className=\"size-11 rounded-lg\" size=\"icon\" type=\"button\">\n          <ArrowUp className=\"size-4\" />\n        </Button>\n      </form>\n    </section>\n  )\n}\n",
          "type": "registry:block",
          "target": "components/blocks/mobile-agent/agent-chat-01.tsx"
        }
      ],
      "categories": [
        "mobile-agent"
      ],
      "registryDependencies": [
        "avatar",
        "badge",
        "button",
        "input"
      ],
      "meta": {
        "frameworks": [
          "react"
        ],
        "category": "mobile-agent",
        "tags": [
          "mobile",
          "mobile-agent"
        ],
        "clientOnly": true,
        "viewport": "mobile-first",
        "isActive": true,
        "mdxBody": "```tsx\n'use client'\n\nimport { ArrowUp, Bot, CheckCircle2, Command, FileText, Sparkles } from 'lucide-react'\n\nimport { Avatar, AvatarFallback } from '@/components/ui/avatar'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\n\nconst tasks = [\n  { label: 'Read registry-index.json', done: true },\n  { label: 'Install wallet-home-01', done: true },\n  { label: 'Patch mobile safe area', done: false },\n]\n\nexport default function AgentChat01() {\n  return (\n    <section className=\"mx-auto flex min-h-dvh w-full max-w-md flex-col bg-background text-foreground\">\n      <header className=\"flex items-center gap-3 border-b px-5 pb-4 pt-safe-top\">\n        <Avatar className=\"size-11\">\n          <AvatarFallback className=\"bg-primary text-primary-foreground\">\n            <Bot className=\"size-5\" />\n          </AvatarFallback>\n        </Avatar>\n        <div className=\"min-w-0 flex-1\">\n          <h1 className=\"text-base font-semibold tracking-normal\">Timkit Agent</h1>\n          <p className=\"truncate text-xs text-muted-foreground\">Mobile UI registry session</p>\n        </div>\n        <Badge className=\"rounded-md\" variant=\"secondary\">\n          Live\n        </Badge>\n      </header>\n\n      <main className=\"flex flex-1 flex-col gap-4 overflow-y-auto px-5 py-5\">\n        <div className=\"max-w-[82%] rounded-lg bg-muted p-3\">\n          <p className=\"text-sm leading-relaxed\">\n            Build a mobile checkout screen using Timkit components and keep every tap target above\n            44px.\n          </p>\n        </div>\n\n        <div className=\"ml-auto max-w-[86%] rounded-lg bg-primary p-3 text-primary-foreground\">\n          <div className=\"mb-2 flex items-center gap-2 text-xs font-medium opacity-80\">\n            <Sparkles className=\"size-3.5\" />\n            Registry plan\n          </div>\n          <div className=\"grid gap-2\">\n            {tasks.map((task) => (\n              <div\n                key={task.label}\n                className=\"flex items-center gap-2 rounded-md bg-primary-foreground/10 px-2 py-2 text-sm\"\n              >\n                {task.done ? <CheckCircle2 className=\"size-4\" /> : <Command className=\"size-4\" />}\n                <span>{task.label}</span>\n              </div>\n            ))}\n          </div>\n        </div>\n\n        <div className=\"max-w-[88%] rounded-lg border bg-card p-3\">\n          <div className=\"mb-2 flex items-center gap-2 text-xs font-medium text-muted-foreground\">\n            <FileText className=\"size-3.5\" />\n            Command\n          </div>\n          <code className=\"block overflow-x-auto rounded-md bg-muted px-3 py-2 text-xs\">\n            npx @timui/cli add commerce-home-01 --framework react\n          </code>\n        </div>\n      </main>\n\n      <form className=\"flex gap-2 border-t px-5 py-3 pb-safe-bottom\">\n        <Input className=\"min-h-[44px] rounded-lg\" placeholder=\"Ask the agent to compose UI\" />\n        <Button aria-label=\"Send message\" className=\"size-11 rounded-lg\" size=\"icon\" type=\"button\">\n          <ArrowUp className=\"size-4\" />\n        </Button>\n      </form>\n    </section>\n  )\n}\n\n```",
        "title": "Agent Chat · Timkit Agent"
      }
    },
    {
      "name": "agent-command-center-01",
      "type": "registry:block",
      "description": "Block: agent-command-center-01",
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "blocks/mobile-agent/agent-command-center-01.tsx",
          "content": "'use client'\n\nimport {\n  Bot,\n  CheckCircle2,\n  CircleDot,\n  Code2,\n  GitBranch,\n  Layers3,\n  Play,\n  TerminalSquare,\n} from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\n\nconst signals = [\n  { label: 'Registry', value: '658 items', icon: Layers3 },\n  { label: 'Plan', value: '6 picks', icon: GitBranch },\n  { label: 'Preview', value: 'Vue + React', icon: Play },\n]\n\nconst steps = [\n  { label: 'Read agent-index.json', state: 'done' },\n  { label: 'Fetch mobile-agent blocks', state: 'done' },\n  { label: 'Install registry dependencies', state: 'active' },\n  { label: 'Run local preview smoke', state: 'queued' },\n]\n\nexport default function AgentCommandCenter01() {\n  return (\n    <section className=\"mx-auto flex min-h-dvh w-full max-w-md flex-col bg-background text-foreground\">\n      <header className=\"border-b px-5 pb-4 pt-safe-top\">\n        <div className=\"flex items-center justify-between gap-3\">\n          <div className=\"flex min-w-0 items-center gap-3\">\n            <div className=\"grid size-11 shrink-0 place-items-center rounded-lg bg-primary text-primary-foreground\">\n              <Bot className=\"size-5\" />\n            </div>\n            <div className=\"min-w-0\">\n              <p className=\"text-xs font-medium text-muted-foreground\">Agent workspace</p>\n              <h1 className=\"truncate text-lg font-semibold tracking-normal\">Command center</h1>\n            </div>\n          </div>\n          <Badge className=\"rounded-md\" variant=\"secondary\">\n            Running\n          </Badge>\n        </div>\n      </header>\n\n      <main className=\"flex flex-1 flex-col gap-4 overflow-y-auto px-5 py-5\">\n        <div className=\"grid grid-cols-3 gap-3\">\n          {signals.map((signal) => {\n            const Icon = signal.icon\n            return (\n              <div key={signal.label} className=\"rounded-lg border bg-card p-3\">\n                <Icon className=\"size-4 text-primary\" />\n                <p className=\"mt-3 text-[11px] font-medium text-muted-foreground\">{signal.label}</p>\n                <p className=\"mt-1 text-sm font-semibold\">{signal.value}</p>\n              </div>\n            )\n          })}\n        </div>\n\n        <div className=\"rounded-lg border bg-card p-4\">\n          <div className=\"mb-4 flex items-center justify-between gap-3\">\n            <div>\n              <p className=\"text-xs font-medium text-muted-foreground\">Current intent</p>\n              <h2 className=\"mt-1 text-base font-semibold tracking-normal\">\n                Build a mobile AI console\n              </h2>\n            </div>\n            <Button aria-label=\"Run plan\" className=\"size-11 rounded-lg\" size=\"icon\">\n              <Play className=\"size-4\" />\n            </Button>\n          </div>\n          <div className=\"grid gap-2\">\n            {steps.map((step) => (\n              <div\n                key={step.label}\n                className=\"flex min-h-[44px] items-center gap-3 rounded-lg bg-muted px-3 text-sm\"\n              >\n                {step.state === 'done' ? (\n                  <CheckCircle2 className=\"size-4 text-emerald-600\" />\n                ) : step.state === 'active' ? (\n                  <TerminalSquare className=\"size-4 text-primary\" />\n                ) : (\n                  <CircleDot className=\"size-4 text-muted-foreground\" />\n                )}\n                <span className=\"min-w-0 flex-1 truncate\">{step.label}</span>\n                <span className=\"text-xs text-muted-foreground\">{step.state}</span>\n              </div>\n            ))}\n          </div>\n        </div>\n\n        <div className=\"rounded-lg border bg-card p-4\">\n          <div className=\"mb-3 flex items-center gap-2 text-xs font-medium text-muted-foreground\">\n            <Code2 className=\"size-4\" />\n            Next command\n          </div>\n          <code className=\"block overflow-x-auto rounded-md bg-muted px-3 py-2 text-xs\">\n            npx shadcn@latest add https://ui.timkit.cn/r/agent-chat-01.json\n          </code>\n        </div>\n      </main>\n    </section>\n  )\n}\n",
          "type": "registry:block",
          "target": "components/blocks/mobile-agent/agent-command-center-01.tsx"
        }
      ],
      "categories": [
        "mobile-agent"
      ],
      "registryDependencies": [
        "badge",
        "button"
      ],
      "meta": {
        "frameworks": [
          "react"
        ],
        "category": "mobile-agent",
        "tags": [
          "mobile",
          "mobile-agent"
        ],
        "clientOnly": true,
        "viewport": "mobile-first",
        "isActive": true,
        "mdxBody": "```tsx\n'use client'\n\nimport {\n  Bot,\n  CheckCircle2,\n  CircleDot,\n  Code2,\n  GitBranch,\n  Layers3,\n  Play,\n  TerminalSquare,\n} from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\n\nconst signals = [\n  { label: 'Registry', value: '658 items', icon: Layers3 },\n  { label: 'Plan', value: '6 picks', icon: GitBranch },\n  { label: 'Preview', value: 'Vue + React', icon: Play },\n]\n\nconst steps = [\n  { label: 'Read agent-index.json', state: 'done' },\n  { label: 'Fetch mobile-agent blocks', state: 'done' },\n  { label: 'Install registry dependencies', state: 'active' },\n  { label: 'Run local preview smoke', state: 'queued' },\n]\n\nexport default function AgentCommandCenter01() {\n  return (\n    <section className=\"mx-auto flex min-h-dvh w-full max-w-md flex-col bg-background text-foreground\">\n      <header className=\"border-b px-5 pb-4 pt-safe-top\">\n        <div className=\"flex items-center justify-between gap-3\">\n          <div className=\"flex min-w-0 items-center gap-3\">\n            <div className=\"grid size-11 shrink-0 place-items-center rounded-lg bg-primary text-primary-foreground\">\n              <Bot className=\"size-5\" />\n            </div>\n            <div className=\"min-w-0\">\n              <p className=\"text-xs font-medium text-muted-foreground\">Agent workspace</p>\n              <h1 className=\"truncate text-lg font-semibold tracking-normal\">Command center</h1>\n            </div>\n          </div>\n          <Badge className=\"rounded-md\" variant=\"secondary\">\n            Running\n          </Badge>\n        </div>\n      </header>\n\n      <main className=\"flex flex-1 flex-col gap-4 overflow-y-auto px-5 py-5\">\n        <div className=\"grid grid-cols-3 gap-3\">\n          {signals.map((signal) => {\n            const Icon = signal.icon\n            return (\n              <div key={signal.label} className=\"rounded-lg border bg-card p-3\">\n                <Icon className=\"size-4 text-primary\" />\n                <p className=\"mt-3 text-[11px] font-medium text-muted-foreground\">{signal.label}</p>\n                <p className=\"mt-1 text-sm font-semibold\">{signal.value}</p>\n              </div>\n            )\n          })}\n        </div>\n\n        <div className=\"rounded-lg border bg-card p-4\">\n          <div className=\"mb-4 flex items-center justify-between gap-3\">\n            <div>\n              <p className=\"text-xs font-medium text-muted-foreground\">Current intent</p>\n              <h2 className=\"mt-1 text-base font-semibold tracking-normal\">\n                Build a mobile AI console\n              </h2>\n            </div>\n            <Button aria-label=\"Run plan\" className=\"size-11 rounded-lg\" size=\"icon\">\n              <Play className=\"size-4\" />\n            </Button>\n          </div>\n          <div className=\"grid gap-2\">\n            {steps.map((step) => (\n              <div\n                key={step.label}\n                className=\"flex min-h-[44px] items-center gap-3 rounded-lg bg-muted px-3 text-sm\"\n              >\n                {step.state === 'done' ? (\n                  <CheckCircle2 className=\"size-4 text-emerald-600\" />\n                ) : step.state === 'active' ? (\n                  <TerminalSquare className=\"size-4 text-primary\" />\n                ) : (\n                  <CircleDot className=\"size-4 text-muted-foreground\" />\n                )}\n                <span className=\"min-w-0 flex-1 truncate\">{step.label}</span>\n                <span className=\"text-xs text-muted-foreground\">{step.state}</span>\n              </div>\n            ))}\n          </div>\n        </div>\n\n        <div className=\"rounded-lg border bg-card p-4\">\n          <div className=\"mb-3 flex items-center gap-2 text-xs font-medium text-muted-foreground\">\n            <Code2 className=\"size-4\" />\n            Next command\n          </div>\n          <code className=\"block overflow-x-auto rounded-md bg-muted px-3 py-2 text-xs\">\n            npx shadcn@latest add https://ui.timkit.cn/r/agent-chat-01.json\n          </code>\n        </div>\n      </main>\n    </section>\n  )\n}\n\n```",
        "title": "Agent Command Center · Command center"
      }
    },
    {
      "name": "agent-run-timeline-01",
      "type": "registry:block",
      "description": "Block: agent-run-timeline-01",
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "blocks/mobile-agent/agent-run-timeline-01.tsx",
          "content": "'use client'\n\nimport { CheckCircle2, CircleDot, Clock3, Loader2 } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\n\nconst events = [\n  { title: 'Intent parsed', detail: 'mobile agent console, React, safe area', state: 'done' },\n  { title: 'Registry ranked', detail: 'templates, blocks, primitives scored', state: 'done' },\n  { title: 'Source installed', detail: 'agent-command-center-01 and button', state: 'active' },\n  { title: 'Preview verified', detail: 'waiting for runtime smoke', state: 'queued' },\n]\n\nexport default function AgentRunTimeline01() {\n  return (\n    <section className=\"mx-auto flex min-h-dvh w-full max-w-md flex-col bg-background px-5 py-5 pt-safe-top text-foreground\">\n      <header>\n        <div className=\"flex items-center justify-between gap-3\">\n          <div>\n            <p className=\"text-xs font-medium text-muted-foreground\">Execution timeline</p>\n            <h1 className=\"mt-1 text-2xl font-semibold tracking-normal\">Agent run</h1>\n          </div>\n          <Badge className=\"rounded-md\" variant=\"secondary\">\n            74%\n          </Badge>\n        </div>\n      </header>\n\n      <main className=\"mt-6 flex-1 overflow-y-auto pb-safe-bottom\">\n        <div className=\"rounded-lg border bg-card p-4\">\n          <div className=\"grid gap-4\">\n            {events.map((event, index) => {\n              const isDone = event.state === 'done'\n              const isActive = event.state === 'active'\n              return (\n                <div key={event.title} className=\"grid grid-cols-[28px_1fr] gap-3\">\n                  <div className=\"flex flex-col items-center\">\n                    <span className=\"grid size-7 place-items-center rounded-full bg-muted\">\n                      {isDone ? (\n                        <CheckCircle2 className=\"size-4 text-emerald-600\" />\n                      ) : isActive ? (\n                        <Loader2 className=\"size-4 animate-spin text-primary\" />\n                      ) : (\n                        <CircleDot className=\"size-4 text-muted-foreground\" />\n                      )}\n                    </span>\n                    {index < events.length - 1 ? (\n                      <span className=\"mt-2 h-12 w-px bg-border\" />\n                    ) : null}\n                  </div>\n                  <div className=\"min-w-0 pb-4\">\n                    <div className=\"flex min-h-[28px] items-center justify-between gap-2\">\n                      <h2 className=\"truncate text-sm font-semibold\">{event.title}</h2>\n                      <span className=\"flex shrink-0 items-center gap-1 text-xs text-muted-foreground\">\n                        <Clock3 className=\"size-3.5\" />\n                        {isDone ? 'done' : event.state}\n                      </span>\n                    </div>\n                    <p className=\"mt-1 text-sm leading-6 text-muted-foreground\">{event.detail}</p>\n                  </div>\n                </div>\n              )\n            })}\n          </div>\n        </div>\n      </main>\n    </section>\n  )\n}\n",
          "type": "registry:block",
          "target": "components/blocks/mobile-agent/agent-run-timeline-01.tsx"
        }
      ],
      "categories": [
        "mobile-agent"
      ],
      "registryDependencies": [
        "badge"
      ],
      "meta": {
        "frameworks": [
          "react"
        ],
        "category": "mobile-agent",
        "tags": [
          "mobile",
          "mobile-agent"
        ],
        "clientOnly": true,
        "viewport": "mobile-first",
        "isActive": true,
        "mdxBody": "```tsx\n'use client'\n\nimport { CheckCircle2, CircleDot, Clock3, Loader2 } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\n\nconst events = [\n  { title: 'Intent parsed', detail: 'mobile agent console, React, safe area', state: 'done' },\n  { title: 'Registry ranked', detail: 'templates, blocks, primitives scored', state: 'done' },\n  { title: 'Source installed', detail: 'agent-command-center-01 and button', state: 'active' },\n  { title: 'Preview verified', detail: 'waiting for runtime smoke', state: 'queued' },\n]\n\nexport default function AgentRunTimeline01() {\n  return (\n    <section className=\"mx-auto flex min-h-dvh w-full max-w-md flex-col bg-background px-5 py-5 pt-safe-top text-foreground\">\n      <header>\n        <div className=\"flex items-center justify-between gap-3\">\n          <div>\n            <p className=\"text-xs font-medium text-muted-foreground\">Execution timeline</p>\n            <h1 className=\"mt-1 text-2xl font-semibold tracking-normal\">Agent run</h1>\n          </div>\n          <Badge className=\"rounded-md\" variant=\"secondary\">\n            74%\n          </Badge>\n        </div>\n      </header>\n\n      <main className=\"mt-6 flex-1 overflow-y-auto pb-safe-bottom\">\n        <div className=\"rounded-lg border bg-card p-4\">\n          <div className=\"grid gap-4\">\n            {events.map((event, index) => {\n              const isDone = event.state === 'done'\n              const isActive = event.state === 'active'\n              return (\n                <div key={event.title} className=\"grid grid-cols-[28px_1fr] gap-3\">\n                  <div className=\"flex flex-col items-center\">\n                    <span className=\"grid size-7 place-items-center rounded-full bg-muted\">\n                      {isDone ? (\n                        <CheckCircle2 className=\"size-4 text-emerald-600\" />\n                      ) : isActive ? (\n                        <Loader2 className=\"size-4 animate-spin text-primary\" />\n                      ) : (\n                        <CircleDot className=\"size-4 text-muted-foreground\" />\n                      )}\n                    </span>\n                    {index < events.length - 1 ? (\n                      <span className=\"mt-2 h-12 w-px bg-border\" />\n                    ) : null}\n                  </div>\n                  <div className=\"min-w-0 pb-4\">\n                    <div className=\"flex min-h-[28px] items-center justify-between gap-2\">\n                      <h2 className=\"truncate text-sm font-semibold\">{event.title}</h2>\n                      <span className=\"flex shrink-0 items-center gap-1 text-xs text-muted-foreground\">\n                        <Clock3 className=\"size-3.5\" />\n                        {isDone ? 'done' : event.state}\n                      </span>\n                    </div>\n                    <p className=\"mt-1 text-sm leading-6 text-muted-foreground\">{event.detail}</p>\n                  </div>\n                </div>\n              )\n            })}\n          </div>\n        </div>\n      </main>\n    </section>\n  )\n}\n\n```",
        "title": "Agent Run Timeline · Agent run"
      }
    },
    {
      "name": "agent-tool-grid-01",
      "type": "registry:block",
      "description": "Block: agent-tool-grid-01",
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "blocks/mobile-agent/agent-tool-grid-01.tsx",
          "content": "'use client'\n\nimport { Bot, Code2, Database, FileJson2, MonitorSmartphone, ShieldCheck } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\n\nconst tools = [\n  { name: 'Registry fetch', detail: '/r/{name}.json', icon: FileJson2 },\n  { name: 'SDK plan', detail: '@timui/agent', icon: Bot },\n  { name: 'CLI install', detail: 'shadcn add URL', icon: Code2 },\n  { name: 'Preview smoke', detail: 'LOAD_PREVIEW', icon: MonitorSmartphone },\n  { name: 'Data contract', detail: 'registry-index', icon: Database },\n  { name: 'A11y guard', detail: '44px targets', icon: ShieldCheck },\n]\n\nexport default function AgentToolGrid01() {\n  return (\n    <section className=\"mx-auto flex min-h-dvh w-full max-w-md flex-col bg-background px-5 py-5 pt-safe-top text-foreground\">\n      <header className=\"flex items-center justify-between gap-3\">\n        <div>\n          <p className=\"text-xs font-medium text-muted-foreground\">Agent tools</p>\n          <h1 className=\"mt-1 text-2xl font-semibold tracking-normal\">Choose capability</h1>\n        </div>\n        <Badge className=\"rounded-md\" variant=\"secondary\">\n          6 tools\n        </Badge>\n      </header>\n\n      <main className=\"mt-5 grid flex-1 grid-cols-2 gap-3 overflow-y-auto pb-safe-bottom\">\n        {tools.map((tool) => {\n          const Icon = tool.icon\n          return (\n            <Button\n              key={tool.name}\n              className=\"h-auto min-h-[132px] flex-col items-start justify-between rounded-lg border bg-card p-4 text-left text-card-foreground hover:bg-muted\"\n              variant=\"ghost\"\n            >\n              <span className=\"grid size-10 place-items-center rounded-lg bg-primary/10 text-primary\">\n                <Icon className=\"size-5\" />\n              </span>\n              <span className=\"block\">\n                <span className=\"block text-sm font-semibold\">{tool.name}</span>\n                <span className=\"mt-1 block text-xs font-normal text-muted-foreground\">\n                  {tool.detail}\n                </span>\n              </span>\n            </Button>\n          )\n        })}\n      </main>\n    </section>\n  )\n}\n",
          "type": "registry:block",
          "target": "components/blocks/mobile-agent/agent-tool-grid-01.tsx"
        }
      ],
      "categories": [
        "mobile-agent"
      ],
      "registryDependencies": [
        "badge",
        "button"
      ],
      "meta": {
        "frameworks": [
          "react"
        ],
        "category": "mobile-agent",
        "tags": [
          "mobile",
          "mobile-agent"
        ],
        "clientOnly": true,
        "viewport": "mobile-first",
        "isActive": true,
        "mdxBody": "```tsx\n'use client'\n\nimport { Bot, Code2, Database, FileJson2, MonitorSmartphone, ShieldCheck } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\n\nconst tools = [\n  { name: 'Registry fetch', detail: '/r/{name}.json', icon: FileJson2 },\n  { name: 'SDK plan', detail: '@timui/agent', icon: Bot },\n  { name: 'CLI install', detail: 'shadcn add URL', icon: Code2 },\n  { name: 'Preview smoke', detail: 'LOAD_PREVIEW', icon: MonitorSmartphone },\n  { name: 'Data contract', detail: 'registry-index', icon: Database },\n  { name: 'A11y guard', detail: '44px targets', icon: ShieldCheck },\n]\n\nexport default function AgentToolGrid01() {\n  return (\n    <section className=\"mx-auto flex min-h-dvh w-full max-w-md flex-col bg-background px-5 py-5 pt-safe-top text-foreground\">\n      <header className=\"flex items-center justify-between gap-3\">\n        <div>\n          <p className=\"text-xs font-medium text-muted-foreground\">Agent tools</p>\n          <h1 className=\"mt-1 text-2xl font-semibold tracking-normal\">Choose capability</h1>\n        </div>\n        <Badge className=\"rounded-md\" variant=\"secondary\">\n          6 tools\n        </Badge>\n      </header>\n\n      <main className=\"mt-5 grid flex-1 grid-cols-2 gap-3 overflow-y-auto pb-safe-bottom\">\n        {tools.map((tool) => {\n          const Icon = tool.icon\n          return (\n            <Button\n              key={tool.name}\n              className=\"h-auto min-h-[132px] flex-col items-start justify-between rounded-lg border bg-card p-4 text-left text-card-foreground hover:bg-muted\"\n              variant=\"ghost\"\n            >\n              <span className=\"grid size-10 place-items-center rounded-lg bg-primary/10 text-primary\">\n                <Icon className=\"size-5\" />\n              </span>\n              <span className=\"block\">\n                <span className=\"block text-sm font-semibold\">{tool.name}</span>\n                <span className=\"mt-1 block text-xs font-normal text-muted-foreground\">\n                  {tool.detail}\n                </span>\n              </span>\n            </Button>\n          )\n        })}\n      </main>\n    </section>\n  )\n}\n\n```",
        "title": "Agent Tool Grid · Choose capability"
      }
    },
    {
      "name": "commerce-home-01",
      "type": "registry:block",
      "description": "Block: commerce-home-01",
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "blocks/mobile-commerce/commerce-home-01.tsx",
          "content": "import { ArrowRight, Heart, Search, ShoppingBag, Sparkles, Star } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent } from '@/components/ui/card'\nimport { Input } from '@/components/ui/input'\n\nconst categories = ['Drops', 'Daily', 'Outdoor', 'Studio']\n\nconst products = [\n  {\n    name: 'Trace Knit Jacket',\n    detail: 'Water-repellent shell',\n    price: '$128',\n    rating: '4.9',\n    accent: 'bg-sky-100 text-sky-900 dark:bg-sky-400/15 dark:text-sky-200',\n  },\n  {\n    name: 'Arc Running Tote',\n    detail: '18L recycled nylon',\n    price: '$74',\n    rating: '4.8',\n    accent: 'bg-emerald-100 text-emerald-900 dark:bg-emerald-400/15 dark:text-emerald-200',\n  },\n]\n\nexport default function CommerceHome01() {\n  return (\n    <section className=\"mx-auto flex min-h-dvh w-full max-w-md flex-col bg-background text-foreground\">\n      <header className=\"flex items-center justify-between px-5 pb-4 pt-safe-top\">\n        <div>\n          <p className=\"text-xs font-medium text-muted-foreground\">Good morning</p>\n          <h1 className=\"mt-1 text-2xl font-semibold tracking-normal\">Find your next fit</h1>\n        </div>\n        <Button aria-label=\"Open shopping bag\" className=\"size-11 rounded-lg\" size=\"icon\">\n          <ShoppingBag className=\"size-5\" />\n        </Button>\n      </header>\n\n      <main className=\"flex flex-1 flex-col gap-5 px-5 pb-safe-bottom\">\n        <label className=\"relative block\">\n          <span className=\"sr-only\">Search products</span>\n          <Search className=\"pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground\" />\n          <Input\n            className=\"min-h-[44px] rounded-lg pl-10\"\n            placeholder=\"Search jackets, bags, shoes\"\n            type=\"search\"\n          />\n        </label>\n\n        <div className=\"flex gap-2 overflow-x-auto pb-1\">\n          {categories.map((category, index) => (\n            <Button\n              key={category}\n              className=\"min-h-[44px] shrink-0 rounded-lg px-4\"\n              variant={index === 0 ? 'default' : 'outline'}\n            >\n              {category}\n            </Button>\n          ))}\n        </div>\n\n        <div className=\"rounded-lg border bg-card p-4 shadow-sm\">\n          <div className=\"flex items-start justify-between gap-4\">\n            <div>\n              <Badge className=\"rounded-md\" variant=\"secondary\">\n                <Sparkles className=\"mr-1 size-3\" />\n                Agent pick\n              </Badge>\n              <h2 className=\"mt-4 max-w-[13rem] text-2xl font-semibold tracking-normal\">\n                Capsule pieces for a rainy city week.\n              </h2>\n            </div>\n            <div className=\"grid size-24 place-items-center rounded-lg bg-primary/10 text-primary\">\n              <ShoppingBag className=\"size-10\" />\n            </div>\n          </div>\n          <Button className=\"mt-5 min-h-[44px] rounded-lg\" variant=\"secondary\">\n            Build outfit\n            <ArrowRight className=\"ml-2 size-4\" />\n          </Button>\n        </div>\n\n        <div className=\"grid gap-3\">\n          {products.map((product) => (\n            <Card key={product.name} className=\"rounded-lg\">\n              <CardContent className=\"flex items-center gap-3 p-3\">\n                <div className={`grid size-16 place-items-center rounded-lg ${product.accent}`}>\n                  <ShoppingBag className=\"size-7\" />\n                </div>\n                <div className=\"min-w-0 flex-1\">\n                  <h3 className=\"truncate text-sm font-semibold\">{product.name}</h3>\n                  <p className=\"mt-1 truncate text-xs text-muted-foreground\">{product.detail}</p>\n                  <div className=\"mt-2 flex items-center gap-2 text-xs text-muted-foreground\">\n                    <Star className=\"size-3 fill-current\" />\n                    {product.rating}\n                  </div>\n                </div>\n                <div className=\"flex flex-col items-end gap-2\">\n                  <Button\n                    aria-label={`Save ${product.name}`}\n                    className=\"size-11 rounded-lg\"\n                    size=\"icon\"\n                    variant=\"ghost\"\n                  >\n                    <Heart className=\"size-4\" />\n                  </Button>\n                  <span className=\"text-sm font-semibold\">{product.price}</span>\n                </div>\n              </CardContent>\n            </Card>\n          ))}\n        </div>\n      </main>\n    </section>\n  )\n}\n",
          "type": "registry:block",
          "target": "components/blocks/mobile-commerce/commerce-home-01.tsx"
        }
      ],
      "categories": [
        "mobile-commerce"
      ],
      "registryDependencies": [
        "badge",
        "button",
        "card",
        "input"
      ],
      "meta": {
        "frameworks": [
          "react"
        ],
        "category": "mobile-commerce",
        "tags": [
          "mobile",
          "mobile-commerce"
        ],
        "clientOnly": false,
        "viewport": "mobile-first",
        "isActive": true,
        "mdxBody": "```tsx\nimport { ArrowRight, Heart, Search, ShoppingBag, Sparkles, Star } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent } from '@/components/ui/card'\nimport { Input } from '@/components/ui/input'\n\nconst categories = ['Drops', 'Daily', 'Outdoor', 'Studio']\n\nconst products = [\n  {\n    name: 'Trace Knit Jacket',\n    detail: 'Water-repellent shell',\n    price: '$128',\n    rating: '4.9',\n    accent: 'bg-sky-100 text-sky-900 dark:bg-sky-400/15 dark:text-sky-200',\n  },\n  {\n    name: 'Arc Running Tote',\n    detail: '18L recycled nylon',\n    price: '$74',\n    rating: '4.8',\n    accent: 'bg-emerald-100 text-emerald-900 dark:bg-emerald-400/15 dark:text-emerald-200',\n  },\n]\n\nexport default function CommerceHome01() {\n  return (\n    <section className=\"mx-auto flex min-h-dvh w-full max-w-md flex-col bg-background text-foreground\">\n      <header className=\"flex items-center justify-between px-5 pb-4 pt-safe-top\">\n        <div>\n          <p className=\"text-xs font-medium text-muted-foreground\">Good morning</p>\n          <h1 className=\"mt-1 text-2xl font-semibold tracking-normal\">Find your next fit</h1>\n        </div>\n        <Button aria-label=\"Open shopping bag\" className=\"size-11 rounded-lg\" size=\"icon\">\n          <ShoppingBag className=\"size-5\" />\n        </Button>\n      </header>\n\n      <main className=\"flex flex-1 flex-col gap-5 px-5 pb-safe-bottom\">\n        <label className=\"relative block\">\n          <span className=\"sr-only\">Search products</span>\n          <Search className=\"pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground\" />\n          <Input\n            className=\"min-h-[44px] rounded-lg pl-10\"\n            placeholder=\"Search jackets, bags, shoes\"\n            type=\"search\"\n          />\n        </label>\n\n        <div className=\"flex gap-2 overflow-x-auto pb-1\">\n          {categories.map((category, index) => (\n            <Button\n              key={category}\n              className=\"min-h-[44px] shrink-0 rounded-lg px-4\"\n              variant={index === 0 ? 'default' : 'outline'}\n            >\n              {category}\n            </Button>\n          ))}\n        </div>\n\n        <div className=\"rounded-lg border bg-card p-4 shadow-sm\">\n          <div className=\"flex items-start justify-between gap-4\">\n            <div>\n              <Badge className=\"rounded-md\" variant=\"secondary\">\n                <Sparkles className=\"mr-1 size-3\" />\n                Agent pick\n              </Badge>\n              <h2 className=\"mt-4 max-w-[13rem] text-2xl font-semibold tracking-normal\">\n                Capsule pieces for a rainy city week.\n              </h2>\n            </div>\n            <div className=\"grid size-24 place-items-center rounded-lg bg-primary/10 text-primary\">\n              <ShoppingBag className=\"size-10\" />\n            </div>\n          </div>\n          <Button className=\"mt-5 min-h-[44px] rounded-lg\" variant=\"secondary\">\n            Build outfit\n            <ArrowRight className=\"ml-2 size-4\" />\n          </Button>\n        </div>\n\n        <div className=\"grid gap-3\">\n          {products.map((product) => (\n            <Card key={product.name} className=\"rounded-lg\">\n              <CardContent className=\"flex items-center gap-3 p-3\">\n                <div className={`grid size-16 place-items-center rounded-lg ${product.accent}`}>\n                  <ShoppingBag className=\"size-7\" />\n                </div>\n                <div className=\"min-w-0 flex-1\">\n                  <h3 className=\"truncate text-sm font-semibold\">{product.name}</h3>\n                  <p className=\"mt-1 truncate text-xs text-muted-foreground\">{product.detail}</p>\n                  <div className=\"mt-2 flex items-center gap-2 text-xs text-muted-foreground\">\n                    <Star className=\"size-3 fill-current\" />\n                    {product.rating}\n                  </div>\n                </div>\n                <div className=\"flex flex-col items-end gap-2\">\n                  <Button\n                    aria-label={`Save ${product.name}`}\n                    className=\"size-11 rounded-lg\"\n                    size=\"icon\"\n                    variant=\"ghost\"\n                  >\n                    <Heart className=\"size-4\" />\n                  </Button>\n                  <span className=\"text-sm font-semibold\">{product.price}</span>\n                </div>\n              </CardContent>\n            </Card>\n          ))}\n        </div>\n      </main>\n    </section>\n  )\n}\n\n```",
        "title": "Commerce Home · Find your next fit"
      }
    },
    {
      "name": "wallet-home-01",
      "type": "registry:block",
      "description": "Block: wallet-home-01",
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "blocks/mobile-finance/wallet-home-01.tsx",
          "content": "import { ArrowDownLeft, ArrowUpRight, CreditCard, ShieldCheck, Wallet } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent } from '@/components/ui/card'\nimport { Progress } from '@/components/ui/progress'\n\nconst actions = [\n  { label: 'Send', icon: ArrowUpRight },\n  { label: 'Receive', icon: ArrowDownLeft },\n  { label: 'Cards', icon: CreditCard },\n]\n\nconst transactions = [\n  {\n    name: 'Figma',\n    amount: '-$24.00',\n    tone: 'bg-violet-100 text-violet-900 dark:bg-violet-400/15 dark:text-violet-200',\n  },\n  {\n    name: 'Stripe payout',\n    amount: '+$890.20',\n    tone: 'bg-emerald-100 text-emerald-900 dark:bg-emerald-400/15 dark:text-emerald-200',\n  },\n  {\n    name: 'Vercel',\n    amount: '-$20.00',\n    tone: 'bg-slate-100 text-slate-900 dark:bg-slate-400/15 dark:text-slate-200',\n  },\n]\n\nexport default function WalletHome01() {\n  return (\n    <section className=\"mx-auto flex min-h-dvh w-full max-w-md flex-col bg-background text-foreground\">\n      <header className=\"px-5 pb-4 pt-safe-top\">\n        <div className=\"flex items-center justify-between\">\n          <div>\n            <p className=\"text-xs font-medium text-muted-foreground\">Total balance</p>\n            <h1 className=\"mt-1 text-3xl font-semibold tracking-normal\">$24,892.48</h1>\n          </div>\n          <Button\n            aria-label=\"Security center\"\n            className=\"size-11 rounded-lg\"\n            size=\"icon\"\n            variant=\"outline\"\n          >\n            <ShieldCheck className=\"size-5\" />\n          </Button>\n        </div>\n      </header>\n\n      <main className=\"flex flex-1 flex-col gap-5 px-5 pb-safe-bottom\">\n        <div className=\"rounded-lg bg-foreground p-5 text-background shadow-sm\">\n          <div className=\"flex items-center justify-between\">\n            <Badge className=\"rounded-md bg-background/15 text-background hover:bg-background/20\">\n              Timkit Card\n            </Badge>\n            <Wallet className=\"size-6 opacity-80\" />\n          </div>\n          <div className=\"mt-12 flex items-end justify-between\">\n            <div>\n              <p className=\"text-xs text-background/60\">Monthly spend</p>\n              <p className=\"mt-1 text-xl font-semibold\">$3,240.18</p>\n            </div>\n            <p className=\"text-sm text-background/70\">**** 0924</p>\n          </div>\n        </div>\n\n        <div className=\"grid grid-cols-3 gap-3\">\n          {actions.map((action) => {\n            const Icon = action.icon\n            return (\n              <Button key={action.label} className=\"min-h-[56px] rounded-lg\" variant=\"secondary\">\n                <Icon className=\"mr-2 size-4\" />\n                {action.label}\n              </Button>\n            )\n          })}\n        </div>\n\n        <Card className=\"rounded-lg\">\n          <CardContent className=\"p-4\">\n            <div className=\"flex items-center justify-between gap-4\">\n              <div>\n                <h2 className=\"text-sm font-semibold\">Agent budget guard</h2>\n                <p className=\"mt-1 text-xs text-muted-foreground\">$1,840 left this month</p>\n              </div>\n              <span className=\"text-sm font-semibold\">62%</span>\n            </div>\n            <Progress className=\"mt-4 h-2\" value={62} />\n          </CardContent>\n        </Card>\n\n        <div>\n          <div className=\"mb-3 flex items-center justify-between\">\n            <h2 className=\"text-sm font-semibold\">Recent activity</h2>\n            <Button className=\"h-11 rounded-lg px-3\" variant=\"ghost\">\n              View all\n            </Button>\n          </div>\n          <div className=\"grid gap-3\">\n            {transactions.map((item) => (\n              <div\n                key={item.name}\n                className=\"flex min-h-[64px] items-center gap-3 rounded-lg border bg-card px-3\"\n              >\n                <div className={`grid size-10 place-items-center rounded-lg ${item.tone}`}>\n                  <CreditCard className=\"size-4\" />\n                </div>\n                <span className=\"flex-1 text-sm font-medium\">{item.name}</span>\n                <span className=\"text-sm font-semibold\">{item.amount}</span>\n              </div>\n            ))}\n          </div>\n        </div>\n      </main>\n    </section>\n  )\n}\n",
          "type": "registry:block",
          "target": "components/blocks/mobile-finance/wallet-home-01.tsx"
        }
      ],
      "categories": [
        "mobile-finance"
      ],
      "registryDependencies": [
        "badge",
        "button",
        "card",
        "progress"
      ],
      "meta": {
        "frameworks": [
          "react"
        ],
        "category": "mobile-finance",
        "tags": [
          "mobile",
          "mobile-finance"
        ],
        "clientOnly": false,
        "viewport": "mobile-first",
        "isActive": true,
        "mdxBody": "```tsx\nimport { ArrowDownLeft, ArrowUpRight, CreditCard, ShieldCheck, Wallet } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent } from '@/components/ui/card'\nimport { Progress } from '@/components/ui/progress'\n\nconst actions = [\n  { label: 'Send', icon: ArrowUpRight },\n  { label: 'Receive', icon: ArrowDownLeft },\n  { label: 'Cards', icon: CreditCard },\n]\n\nconst transactions = [\n  {\n    name: 'Figma',\n    amount: '-$24.00',\n    tone: 'bg-violet-100 text-violet-900 dark:bg-violet-400/15 dark:text-violet-200',\n  },\n  {\n    name: 'Stripe payout',\n    amount: '+$890.20',\n    tone: 'bg-emerald-100 text-emerald-900 dark:bg-emerald-400/15 dark:text-emerald-200',\n  },\n  {\n    name: 'Vercel',\n    amount: '-$20.00',\n    tone: 'bg-slate-100 text-slate-900 dark:bg-slate-400/15 dark:text-slate-200',\n  },\n]\n\nexport default function WalletHome01() {\n  return (\n    <section className=\"mx-auto flex min-h-dvh w-full max-w-md flex-col bg-background text-foreground\">\n      <header className=\"px-5 pb-4 pt-safe-top\">\n        <div className=\"flex items-center justify-between\">\n          <div>\n            <p className=\"text-xs font-medium text-muted-foreground\">Total balance</p>\n            <h1 className=\"mt-1 text-3xl font-semibold tracking-normal\">$24,892.48</h1>\n          </div>\n          <Button\n            aria-label=\"Security center\"\n            className=\"size-11 rounded-lg\"\n            size=\"icon\"\n            variant=\"outline\"\n          >\n            <ShieldCheck className=\"size-5\" />\n          </Button>\n        </div>\n      </header>\n\n      <main className=\"flex flex-1 flex-col gap-5 px-5 pb-safe-bottom\">\n        <div className=\"rounded-lg bg-foreground p-5 text-background shadow-sm\">\n          <div className=\"flex items-center justify-between\">\n            <Badge className=\"rounded-md bg-background/15 text-background hover:bg-background/20\">\n              Timkit Card\n            </Badge>\n            <Wallet className=\"size-6 opacity-80\" />\n          </div>\n          <div className=\"mt-12 flex items-end justify-between\">\n            <div>\n              <p className=\"text-xs text-background/60\">Monthly spend</p>\n              <p className=\"mt-1 text-xl font-semibold\">$3,240.18</p>\n            </div>\n            <p className=\"text-sm text-background/70\">**** 0924</p>\n          </div>\n        </div>\n\n        <div className=\"grid grid-cols-3 gap-3\">\n          {actions.map((action) => {\n            const Icon = action.icon\n            return (\n              <Button key={action.label} className=\"min-h-[56px] rounded-lg\" variant=\"secondary\">\n                <Icon className=\"mr-2 size-4\" />\n                {action.label}\n              </Button>\n            )\n          })}\n        </div>\n\n        <Card className=\"rounded-lg\">\n          <CardContent className=\"p-4\">\n            <div className=\"flex items-center justify-between gap-4\">\n              <div>\n                <h2 className=\"text-sm font-semibold\">Agent budget guard</h2>\n                <p className=\"mt-1 text-xs text-muted-foreground\">$1,840 left this month</p>\n              </div>\n              <span className=\"text-sm font-semibold\">62%</span>\n            </div>\n            <Progress className=\"mt-4 h-2\" value={62} />\n          </CardContent>\n        </Card>\n\n        <div>\n          <div className=\"mb-3 flex items-center justify-between\">\n            <h2 className=\"text-sm font-semibold\">Recent activity</h2>\n            <Button className=\"h-11 rounded-lg px-3\" variant=\"ghost\">\n              View all\n            </Button>\n          </div>\n          <div className=\"grid gap-3\">\n            {transactions.map((item) => (\n              <div\n                key={item.name}\n                className=\"flex min-h-[64px] items-center gap-3 rounded-lg border bg-card px-3\"\n              >\n                <div className={`grid size-10 place-items-center rounded-lg ${item.tone}`}>\n                  <CreditCard className=\"size-4\" />\n                </div>\n                <span className=\"flex-1 text-sm font-medium\">{item.name}</span>\n                <span className=\"text-sm font-semibold\">{item.amount}</span>\n              </div>\n            ))}\n          </div>\n        </div>\n      </main>\n    </section>\n  )\n}\n\n```",
        "title": "Wallet Home · $24,892.48"
      }
    },
    {
      "name": "._login-01",
      "type": "registry:block",
      "description": "Block: ._login-01",
      "files": [
        {
          "path": "blocks/authentication/._login-01.tsx",
          "content": "\u0000\u0005\u0016\u0007\u0000\u0002\u0000\u0000Mac OS X        \u0000\u0002\u0000\u0000\u0000\t\u0000\u0000\u00002\u0000\u0000\u0000q\u0000\u0000\u0000\u0002\u0000\u0000\u0000�\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000ATTR\u0000\u0000\u0000\u0000\u0000\u0000\u0000�\u0000\u0000\u0000�\u0000\u0000\u0000\u000b\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0000\u0000\u0000�\u0000\u0000\u0000\u000b\u0000\u0000\u0015com.apple.provenance\u0000\u0001\u0002\u0000s�&YT���",
          "type": "registry:block",
          "target": "components/blocks/authentication/._login-01.tsx"
        }
      ],
      "categories": [
        "authentication"
      ],
      "registryDependencies": [],
      "meta": {
        "frameworks": [
          "react"
        ],
        "category": "authentication",
        "tags": [
          "authentication"
        ],
        "clientOnly": false,
        "isActive": true,
        "mdxBody": "```tsx\n\u0000\u0005\u0016\u0007\u0000\u0002\u0000\u0000Mac OS X        \u0000\u0002\u0000\u0000\u0000\t\u0000\u0000\u00002\u0000\u0000\u0000q\u0000\u0000\u0000\u0002\u0000\u0000\u0000�\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000ATTR\u0000\u0000\u0000\u0000\u0000\u0000\u0000�\u0000\u0000\u0000�\u0000\u0000\u0000\u000b\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0000\u0000\u0000�\u0000\u0000\u0000\u000b\u0000\u0000\u0015com.apple.provenance\u0000\u0001\u0002\u0000s�&YT���\n```",
        "title": ". Login · Pattern 01"
      }
    },
    {
      "name": "._agent-chat-01",
      "type": "registry:block",
      "description": "Block: ._agent-chat-01",
      "files": [
        {
          "path": "blocks/mobile-agent/._agent-chat-01.tsx",
          "content": "\u0000\u0005\u0016\u0007\u0000\u0002\u0000\u0000Mac OS X        \u0000\u0002\u0000\u0000\u0000\t\u0000\u0000\u00002\u0000\u0000\u0000q\u0000\u0000\u0000\u0002\u0000\u0000\u0000�\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000ATTR\u0000\u0000\u0000\u0000\u0000\u0000\u0000�\u0000\u0000\u0000�\u0000\u0000\u0000\u000b\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0000\u0000\u0000�\u0000\u0000\u0000\u000b\u0000\u0000\u0015com.apple.provenance\u0000\u0001\u0002\u0000x�\t���i�",
          "type": "registry:block",
          "target": "components/blocks/mobile-agent/._agent-chat-01.tsx"
        }
      ],
      "categories": [
        "mobile-agent"
      ],
      "registryDependencies": [],
      "meta": {
        "frameworks": [
          "react"
        ],
        "category": "mobile-agent",
        "tags": [
          "mobile",
          "mobile-agent"
        ],
        "clientOnly": false,
        "viewport": "mobile-first",
        "isActive": true,
        "mdxBody": "```tsx\n\u0000\u0005\u0016\u0007\u0000\u0002\u0000\u0000Mac OS X        \u0000\u0002\u0000\u0000\u0000\t\u0000\u0000\u00002\u0000\u0000\u0000q\u0000\u0000\u0000\u0002\u0000\u0000\u0000�\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000ATTR\u0000\u0000\u0000\u0000\u0000\u0000\u0000�\u0000\u0000\u0000�\u0000\u0000\u0000\u000b\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0000\u0000\u0000�\u0000\u0000\u0000\u000b\u0000\u0000\u0015com.apple.provenance\u0000\u0001\u0002\u0000x�\t���i�\n```",
        "title": ". Agent Chat · Pattern 01"
      }
    },
    {
      "name": "._commerce-home-01",
      "type": "registry:block",
      "description": "Block: ._commerce-home-01",
      "files": [
        {
          "path": "blocks/mobile-commerce/._commerce-home-01.tsx",
          "content": "\u0000\u0005\u0016\u0007\u0000\u0002\u0000\u0000Mac OS X        \u0000\u0002\u0000\u0000\u0000\t\u0000\u0000\u00002\u0000\u0000\u0000q\u0000\u0000\u0000\u0002\u0000\u0000\u0000�\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000ATTR\u0000\u0000\u0000\u0000\u0000\u0000\u0000�\u0000\u0000\u0000�\u0000\u0000\u0000\u000b\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0000\u0000\u0000�\u0000\u0000\u0000\u000b\u0000\u0000\u0015com.apple.provenance\u0000\u0001\u0002\u0000x�\t���i�",
          "type": "registry:block",
          "target": "components/blocks/mobile-commerce/._commerce-home-01.tsx"
        }
      ],
      "categories": [
        "mobile-commerce"
      ],
      "registryDependencies": [],
      "meta": {
        "frameworks": [
          "react"
        ],
        "category": "mobile-commerce",
        "tags": [
          "mobile",
          "mobile-commerce"
        ],
        "clientOnly": false,
        "viewport": "mobile-first",
        "isActive": true,
        "mdxBody": "```tsx\n\u0000\u0005\u0016\u0007\u0000\u0002\u0000\u0000Mac OS X        \u0000\u0002\u0000\u0000\u0000\t\u0000\u0000\u00002\u0000\u0000\u0000q\u0000\u0000\u0000\u0002\u0000\u0000\u0000�\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000ATTR\u0000\u0000\u0000\u0000\u0000\u0000\u0000�\u0000\u0000\u0000�\u0000\u0000\u0000\u000b\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0000\u0000\u0000�\u0000\u0000\u0000\u000b\u0000\u0000\u0015com.apple.provenance\u0000\u0001\u0002\u0000x�\t���i�\n```",
        "title": ". Commerce Home · Pattern 01"
      }
    },
    {
      "name": "._wallet-home-01",
      "type": "registry:block",
      "description": "Block: ._wallet-home-01",
      "files": [
        {
          "path": "blocks/mobile-finance/._wallet-home-01.tsx",
          "content": "\u0000\u0005\u0016\u0007\u0000\u0002\u0000\u0000Mac OS X        \u0000\u0002\u0000\u0000\u0000\t\u0000\u0000\u00002\u0000\u0000\u0000q\u0000\u0000\u0000\u0002\u0000\u0000\u0000�\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000ATTR\u0000\u0000\u0000\u0000\u0000\u0000\u0000�\u0000\u0000\u0000�\u0000\u0000\u0000\u000b\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0000\u0000\u0000�\u0000\u0000\u0000\u000b\u0000\u0000\u0015com.apple.provenance\u0000\u0001\u0002\u0000x�\t���i�",
          "type": "registry:block",
          "target": "components/blocks/mobile-finance/._wallet-home-01.tsx"
        }
      ],
      "categories": [
        "mobile-finance"
      ],
      "registryDependencies": [],
      "meta": {
        "frameworks": [
          "react"
        ],
        "category": "mobile-finance",
        "tags": [
          "mobile",
          "mobile-finance"
        ],
        "clientOnly": false,
        "viewport": "mobile-first",
        "isActive": true,
        "mdxBody": "```tsx\n\u0000\u0005\u0016\u0007\u0000\u0002\u0000\u0000Mac OS X        \u0000\u0002\u0000\u0000\u0000\t\u0000\u0000\u00002\u0000\u0000\u0000q\u0000\u0000\u0000\u0002\u0000\u0000\u0000�\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000ATTR\u0000\u0000\u0000\u0000\u0000\u0000\u0000�\u0000\u0000\u0000�\u0000\u0000\u0000\u000b\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0000\u0000\u0000�\u0000\u0000\u0000\u000b\u0000\u0000\u0015com.apple.provenance\u0000\u0001\u0002\u0000x�\t���i�\n```",
        "title": ". Wallet Home · Pattern 01"
      }
    },
    {
      "name": "mobile-agent-console",
      "type": "registry:page",
      "description": "Mobile template: mobile-agent-console",
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "templates/mobile-app/mobile-agent-console.tsx",
          "content": "'use client'\n\nimport { ArrowUp, Bot, CheckCircle2, Code2, Home, Layers, Search, Settings2 } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\n\nconst steps = ['Select mobile template', 'Install registry deps', 'Patch theme tokens']\n\nexport default function MobileAgentConsolePage() {\n  return (\n    <main className=\"mx-auto flex min-h-dvh w-full max-w-md flex-col bg-background text-foreground\">\n      <header className=\"flex items-center justify-between px-5 pb-4 pt-safe-top\">\n        <div>\n          <p className=\"text-xs font-medium text-muted-foreground\">Agent console</p>\n          <h1 className=\"mt-1 text-2xl font-semibold tracking-normal\">Build session</h1>\n        </div>\n        <Button aria-label=\"Settings\" className=\"size-11 rounded-lg\" size=\"icon\" variant=\"outline\">\n          <Settings2 className=\"size-5\" />\n        </Button>\n      </header>\n\n      <section className=\"flex flex-1 flex-col gap-4 overflow-y-auto px-5 pb-24\">\n        <div className=\"rounded-lg border bg-card p-4\">\n          <div className=\"flex items-center gap-3\">\n            <div className=\"grid size-11 place-items-center rounded-lg bg-primary text-primary-foreground\">\n              <Bot className=\"size-5\" />\n            </div>\n            <div>\n              <Badge className=\"rounded-md\" variant=\"secondary\">\n                Timkit registry\n              </Badge>\n              <h2 className=\"mt-2 text-base font-semibold\">Mobile checkout flow</h2>\n            </div>\n          </div>\n          <div className=\"mt-4 grid gap-2\">\n            {steps.map((step, index) => (\n              <div\n                key={step}\n                className=\"flex min-h-[44px] items-center gap-2 rounded-lg bg-muted px-3 text-sm\"\n              >\n                {index < 2 ? (\n                  <CheckCircle2 className=\"size-4 text-emerald-600\" />\n                ) : (\n                  <Code2 className=\"size-4 text-muted-foreground\" />\n                )}\n                {step}\n              </div>\n            ))}\n          </div>\n        </div>\n\n        <div className=\"max-w-[86%] rounded-lg bg-muted p-3 text-sm leading-relaxed\">\n          Use mobile-marketplace and replace the product cards with the checkout summary.\n        </div>\n        <div className=\"ml-auto max-w-[86%] rounded-lg bg-primary p-3 text-sm leading-relaxed text-primary-foreground\">\n          I found the template and will install button, input, badge, and card dependencies.\n        </div>\n\n        <form className=\"fixed inset-x-0 bottom-[68px] mx-auto flex max-w-md gap-2 bg-background/95 px-5 py-3 backdrop-blur\">\n          <Input className=\"min-h-[44px] rounded-lg\" placeholder=\"Describe the next UI change\" />\n          <Button aria-label=\"Send\" className=\"size-11 rounded-lg\" size=\"icon\" type=\"button\">\n            <ArrowUp className=\"size-4\" />\n          </Button>\n        </form>\n      </section>\n\n      <nav className=\"fixed inset-x-0 bottom-0 mx-auto flex max-w-md justify-around border-t bg-background/95 px-5 py-3 pb-safe-bottom backdrop-blur\">\n        {[Home, Search, Layers, Settings2].map((Icon, index) => (\n          <Button\n            key={index}\n            aria-label={`Tab ${index + 1}`}\n            className=\"size-11 rounded-lg\"\n            size=\"icon\"\n            variant={index === 0 ? 'secondary' : 'ghost'}\n          >\n            <Icon className=\"size-5\" />\n          </Button>\n        ))}\n      </nav>\n    </main>\n  )\n}\n",
          "type": "registry:page",
          "target": "app/mobile-agent-console/page.tsx"
        }
      ],
      "categories": [
        "mobile-app"
      ],
      "registryDependencies": [
        "badge",
        "button",
        "input"
      ],
      "meta": {
        "frameworks": [
          "react"
        ],
        "category": "mobile-app",
        "tags": [
          "mobile",
          "template",
          "mobile-app"
        ],
        "clientOnly": true,
        "viewport": "mobile-first",
        "source": "packages/react/src/templates"
      }
    },
    {
      "name": "mobile-agent-workbench",
      "type": "registry:page",
      "description": "Mobile template: mobile-agent-workbench",
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "templates/mobile-app/mobile-agent-workbench.tsx",
          "content": "'use client'\n\nimport {\n  Bot,\n  CheckCircle2,\n  Code2,\n  FileJson2,\n  Home,\n  Layers3,\n  Search,\n  Settings2,\n  TerminalSquare,\n} from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\n\nconst recommendations = [\n  { name: 'agent-command-center-01', type: 'block' },\n  { name: 'agent-tool-grid-01', type: 'block' },\n  { name: 'mobile-agent-console', type: 'page' },\n]\n\nconst checks = ['Registry JSON fetched', 'Dependencies mapped', 'Preview protocol ready']\n\nexport default function MobileAgentWorkbenchPage() {\n  return (\n    <main className=\"mx-auto flex min-h-dvh w-full max-w-md flex-col bg-background text-foreground\">\n      <header className=\"px-5 pb-4 pt-safe-top\">\n        <div className=\"flex items-center justify-between gap-3\">\n          <div>\n            <p className=\"text-xs font-medium text-muted-foreground\">Timkit for agents</p>\n            <h1 className=\"mt-1 text-2xl font-semibold tracking-normal\">Build workbench</h1>\n          </div>\n          <Button\n            aria-label=\"Settings\"\n            className=\"size-11 rounded-lg\"\n            size=\"icon\"\n            variant=\"outline\"\n          >\n            <Settings2 className=\"size-5\" />\n          </Button>\n        </div>\n      </header>\n\n      <section className=\"flex flex-1 flex-col gap-4 overflow-y-auto px-5 pb-24\">\n        <div className=\"rounded-lg border bg-card p-4\">\n          <div className=\"mb-4 flex items-center gap-3\">\n            <div className=\"grid size-11 place-items-center rounded-lg bg-primary text-primary-foreground\">\n              <Bot className=\"size-5\" />\n            </div>\n            <div className=\"min-w-0\">\n              <Badge className=\"rounded-md\" variant=\"secondary\">\n                Agent plan\n              </Badge>\n              <h2 className=\"mt-2 truncate text-base font-semibold\">Mobile SaaS console</h2>\n            </div>\n          </div>\n          <div className=\"grid gap-2\">\n            {recommendations.map((item) => (\n              <div\n                key={item.name}\n                className=\"flex min-h-[44px] items-center gap-3 rounded-lg bg-muted px-3 text-sm\"\n              >\n                {item.type === 'page' ? (\n                  <FileJson2 className=\"size-4 text-primary\" />\n                ) : (\n                  <Layers3 className=\"size-4 text-primary\" />\n                )}\n                <span className=\"min-w-0 flex-1 truncate\">{item.name}</span>\n                <span className=\"text-xs text-muted-foreground\">{item.type}</span>\n              </div>\n            ))}\n          </div>\n        </div>\n\n        <div className=\"rounded-lg border bg-card p-4\">\n          <div className=\"mb-3 flex items-center gap-2 text-xs font-medium text-muted-foreground\">\n            <TerminalSquare className=\"size-4\" />\n            Install command\n          </div>\n          <code className=\"block overflow-x-auto rounded-md bg-muted px-3 py-2 text-xs\">\n            npx shadcn@latest add https://ui.timkit.cn/r/mobile-agent-workbench.json\n          </code>\n        </div>\n\n        <div className=\"rounded-lg border bg-card p-4\">\n          <h2 className=\"text-sm font-semibold\">Verification</h2>\n          <div className=\"mt-3 grid gap-2\">\n            {checks.map((check) => (\n              <div key={check} className=\"flex min-h-[44px] items-center gap-2 text-sm\">\n                <CheckCircle2 className=\"size-4 text-emerald-600\" />\n                {check}\n              </div>\n            ))}\n          </div>\n        </div>\n\n        <form className=\"fixed inset-x-0 bottom-[68px] mx-auto flex max-w-md gap-2 bg-background/95 px-5 py-3 backdrop-blur\">\n          <Input className=\"min-h-[44px] rounded-lg\" placeholder=\"Ask for the next UI patch\" />\n          <Button aria-label=\"Generate\" className=\"size-11 rounded-lg\" size=\"icon\" type=\"button\">\n            <Code2 className=\"size-4\" />\n          </Button>\n        </form>\n      </section>\n\n      <nav className=\"fixed inset-x-0 bottom-0 mx-auto flex max-w-md justify-around border-t bg-background/95 px-5 py-3 pb-safe-bottom backdrop-blur\">\n        {[Home, Search, Layers3, Settings2].map((Icon, index) => (\n          <Button\n            key={index}\n            aria-label={`Tab ${index + 1}`}\n            className=\"size-11 rounded-lg\"\n            size=\"icon\"\n            variant={index === 0 ? 'secondary' : 'ghost'}\n          >\n            <Icon className=\"size-5\" />\n          </Button>\n        ))}\n      </nav>\n    </main>\n  )\n}\n",
          "type": "registry:page",
          "target": "app/mobile-agent-workbench/page.tsx"
        }
      ],
      "categories": [
        "mobile-app"
      ],
      "registryDependencies": [
        "badge",
        "button",
        "input"
      ],
      "meta": {
        "frameworks": [
          "react"
        ],
        "category": "mobile-app",
        "tags": [
          "mobile",
          "template",
          "mobile-app"
        ],
        "clientOnly": true,
        "viewport": "mobile-first",
        "source": "packages/react/src/templates"
      }
    },
    {
      "name": "mobile-marketplace",
      "type": "registry:page",
      "description": "Mobile template: mobile-marketplace",
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "templates/mobile-app/mobile-marketplace.tsx",
          "content": "import { Bell, Home, Layers, Search, ShoppingBag, Star, UserRound } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent } from '@/components/ui/card'\nimport { Input } from '@/components/ui/input'\n\nconst products = ['Trail shell', 'Daily sling', 'Studio cap']\n\nexport default function MobileMarketplacePage() {\n  return (\n    <main className=\"mx-auto flex min-h-dvh w-full max-w-md flex-col bg-background text-foreground\">\n      <header className=\"flex items-center justify-between px-5 pb-4 pt-safe-top\">\n        <div>\n          <p className=\"text-xs font-medium text-muted-foreground\">Marketplace</p>\n          <h1 className=\"mt-1 text-2xl font-semibold tracking-normal\">Curated drops</h1>\n        </div>\n        <Button\n          aria-label=\"Notifications\"\n          className=\"size-11 rounded-lg\"\n          size=\"icon\"\n          variant=\"outline\"\n        >\n          <Bell className=\"size-5\" />\n        </Button>\n      </header>\n\n      <section className=\"flex flex-1 flex-col gap-5 px-5 pb-24\">\n        <label className=\"relative block\">\n          <span className=\"sr-only\">Search catalog</span>\n          <Search className=\"pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground\" />\n          <Input className=\"min-h-[44px] rounded-lg pl-10\" placeholder=\"Search catalog\" />\n        </label>\n\n        <div className=\"rounded-lg border bg-card p-4\">\n          <Badge className=\"rounded-md\" variant=\"secondary\">\n            Agent bundle\n          </Badge>\n          <h2 className=\"mt-4 text-2xl font-semibold tracking-normal\">\n            A weekend kit in three pieces\n          </h2>\n          <Button className=\"mt-5 min-h-[44px] rounded-lg\">\n            Shop bundle\n            <ShoppingBag className=\"ml-2 size-4\" />\n          </Button>\n        </div>\n\n        <div className=\"grid gap-3\">\n          {products.map((product, index) => (\n            <Card key={product} className=\"rounded-lg\">\n              <CardContent className=\"flex items-center gap-3 p-3\">\n                <div className=\"grid size-16 place-items-center rounded-lg bg-muted\">\n                  <Layers className=\"size-6 text-muted-foreground\" />\n                </div>\n                <div className=\"flex-1\">\n                  <h3 className=\"text-sm font-semibold\">{product}</h3>\n                  <p className=\"mt-1 text-xs text-muted-foreground\">Ready in {index + 2} colors</p>\n                  <p className=\"mt-2 flex items-center gap-1 text-xs text-muted-foreground\">\n                    <Star className=\"size-3 fill-current\" />\n                    4.{index + 7}\n                  </p>\n                </div>\n                <span className=\"text-sm font-semibold\">${72 + index * 18}</span>\n              </CardContent>\n            </Card>\n          ))}\n        </div>\n      </section>\n\n      <nav className=\"fixed inset-x-0 bottom-0 mx-auto flex max-w-md justify-around border-t bg-background/95 px-5 py-3 pb-safe-bottom backdrop-blur\">\n        {[Home, Search, ShoppingBag, UserRound].map((Icon, index) => (\n          <Button\n            key={index}\n            aria-label={`Tab ${index + 1}`}\n            className=\"size-11 rounded-lg\"\n            size=\"icon\"\n            variant={index === 0 ? 'secondary' : 'ghost'}\n          >\n            <Icon className=\"size-5\" />\n          </Button>\n        ))}\n      </nav>\n    </main>\n  )\n}\n",
          "type": "registry:page",
          "target": "app/mobile-marketplace/page.tsx"
        }
      ],
      "categories": [
        "mobile-app"
      ],
      "registryDependencies": [
        "badge",
        "button",
        "card",
        "input"
      ],
      "meta": {
        "frameworks": [
          "react"
        ],
        "category": "mobile-app",
        "tags": [
          "mobile",
          "template",
          "mobile-app"
        ],
        "clientOnly": false,
        "viewport": "mobile-first",
        "source": "packages/react/src/templates"
      }
    },
    {
      "name": "mobile-wallet",
      "type": "registry:page",
      "description": "Mobile template: mobile-wallet",
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "templates/mobile-app/mobile-wallet.tsx",
          "content": "import {\n  ArrowDownLeft,\n  ArrowUpRight,\n  CreditCard,\n  Home,\n  PieChart,\n  ShieldCheck,\n  UserRound,\n} from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Progress } from '@/components/ui/progress'\n\nconst rows = [\n  { label: 'Cloud tools', value: '-$44.00' },\n  { label: 'Client payment', value: '+$1,280.00' },\n  { label: 'Team lunch', value: '-$86.40' },\n]\n\nexport default function MobileWalletPage() {\n  return (\n    <main className=\"mx-auto flex min-h-dvh w-full max-w-md flex-col bg-background text-foreground\">\n      <header className=\"px-5 pb-4 pt-safe-top\">\n        <div className=\"flex items-center justify-between\">\n          <div>\n            <p className=\"text-xs font-medium text-muted-foreground\">Available balance</p>\n            <h1 className=\"mt-1 text-3xl font-semibold tracking-normal\">$18,420.90</h1>\n          </div>\n          <Button\n            aria-label=\"Security\"\n            className=\"size-11 rounded-lg\"\n            size=\"icon\"\n            variant=\"outline\"\n          >\n            <ShieldCheck className=\"size-5\" />\n          </Button>\n        </div>\n      </header>\n\n      <section className=\"flex flex-1 flex-col gap-5 px-5 pb-24\">\n        <div className=\"rounded-lg bg-foreground p-5 text-background\">\n          <Badge className=\"rounded-md bg-background/15 text-background hover:bg-background/20\">\n            Primary card\n          </Badge>\n          <div className=\"mt-16 flex items-end justify-between\">\n            <p className=\"text-xl font-semibold\">**** 4820</p>\n            <CreditCard className=\"size-6 opacity-80\" />\n          </div>\n        </div>\n\n        <div className=\"grid grid-cols-2 gap-3\">\n          <Button className=\"min-h-[52px] rounded-lg\">\n            <ArrowUpRight className=\"mr-2 size-4\" />\n            Send\n          </Button>\n          <Button className=\"min-h-[52px] rounded-lg\" variant=\"secondary\">\n            <ArrowDownLeft className=\"mr-2 size-4\" />\n            Request\n          </Button>\n        </div>\n\n        <div className=\"rounded-lg border bg-card p-4\">\n          <div className=\"flex items-center justify-between\">\n            <h2 className=\"text-sm font-semibold\">Spend limit</h2>\n            <span className=\"text-sm font-semibold\">58%</span>\n          </div>\n          <Progress className=\"mt-4 h-2\" value={58} />\n        </div>\n\n        <div className=\"grid gap-3\">\n          {rows.map((row) => (\n            <div\n              key={row.label}\n              className=\"flex min-h-[60px] items-center justify-between rounded-lg border bg-card px-4\"\n            >\n              <span className=\"text-sm font-medium\">{row.label}</span>\n              <span className=\"text-sm font-semibold\">{row.value}</span>\n            </div>\n          ))}\n        </div>\n      </section>\n\n      <nav className=\"fixed inset-x-0 bottom-0 mx-auto flex max-w-md justify-around border-t bg-background/95 px-5 py-3 pb-safe-bottom backdrop-blur\">\n        {[Home, PieChart, CreditCard, UserRound].map((Icon, index) => (\n          <Button\n            key={index}\n            aria-label={`Tab ${index + 1}`}\n            className=\"size-11 rounded-lg\"\n            size=\"icon\"\n            variant={index === 0 ? 'secondary' : 'ghost'}\n          >\n            <Icon className=\"size-5\" />\n          </Button>\n        ))}\n      </nav>\n    </main>\n  )\n}\n",
          "type": "registry:page",
          "target": "app/mobile-wallet/page.tsx"
        }
      ],
      "categories": [
        "mobile-app"
      ],
      "registryDependencies": [
        "badge",
        "button",
        "progress"
      ],
      "meta": {
        "frameworks": [
          "react"
        ],
        "category": "mobile-app",
        "tags": [
          "mobile",
          "template",
          "mobile-app"
        ],
        "clientOnly": false,
        "viewport": "mobile-first",
        "source": "packages/react/src/templates"
      }
    },
    {
      "name": "ui-tokens",
      "type": "registry:theme",
      "description": "Design tokens (CSS Variables)",
      "files": [
        {
          "path": "styles/theme.css",
          "content": ":root {\n  --background-default: oklch(1 0 0);\n  --background-subtle: oklch(0.985 0 0);\n  --background-overlay: oklch(1 0 0);\n  --foreground-default: oklch(0.145 0 0);\n  --foreground-muted: oklch(0.556 0 0);\n  --foreground-inverted: oklch(1 0 0);\n  --primary-DEFAULT: oklch(0.205 0 0);\n  --primary-foreground: oklch(0.985 0 0);\n  --secondary-DEFAULT: oklch(0.97 0 0);\n  --secondary-foreground: oklch(0.205 0 0);\n  --destructive-DEFAULT: oklch(0.637 0.237 25.331);\n  --destructive-foreground: oklch(1 0 0);\n  --border-default: oklch(0.922 0 0);\n  --border-input: oklch(0.922 0 0);\n  --ring: oklch(0.145 0 0);\n  --radius-sm: 0.375rem;\n  --radius-md: 0.5rem;\n  --radius-lg: 0.625rem;\n  --radius-full: 9999px;\n}\n",
          "type": "registry:css",
          "target": "src/styles/theme.css"
        }
      ]
    }
  ],
  "generatedAt": "2026-05-28T16:09:50.699Z",
  "schemaVersion": "1.0",
  "minCliVersion": "0.0.1",
  "checksum": "cd7de256022e7d074069d64ff0132b1a4d8994c5527f9ddaf912cf1c9270f595"
}